@pie-lib/editable-html 9.5.13 → 10.0.0-beta.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +0 -302
  2. package/lib/components.js +116 -0
  3. package/lib/components.js.map +1 -0
  4. package/lib/editor.js +418 -103
  5. package/lib/editor.js.map +1 -1
  6. package/lib/index.js +101 -155
  7. package/lib/index.js.map +1 -1
  8. package/lib/new-serialization.js +320 -0
  9. package/lib/new-serialization.js.map +1 -0
  10. package/lib/old-serialization.js +330 -0
  11. package/lib/parse-html.js +1 -1
  12. package/lib/parse-html.js.map +1 -1
  13. package/lib/plugins/characters/custom-popper.js +1 -1
  14. package/lib/plugins/characters/custom-popper.js.map +1 -1
  15. package/lib/plugins/characters/index.js +21 -19
  16. package/lib/plugins/characters/index.js.map +1 -1
  17. package/lib/plugins/characters/utils.js +1 -1
  18. package/lib/plugins/characters/utils.js.map +1 -1
  19. package/lib/plugins/hotKeys/index.js +67 -0
  20. package/lib/plugins/hotKeys/index.js.map +1 -0
  21. package/lib/plugins/image/alt-dialog.js +1 -6
  22. package/lib/plugins/image/alt-dialog.js.map +1 -1
  23. package/lib/plugins/image/component.js +70 -53
  24. package/lib/plugins/image/component.js.map +1 -1
  25. package/lib/plugins/image/image-toolbar.js +7 -9
  26. package/lib/plugins/image/image-toolbar.js.map +1 -1
  27. package/lib/plugins/image/index.js +83 -27
  28. package/lib/plugins/image/index.js.map +1 -1
  29. package/lib/plugins/image/insert-image-handler.js +72 -33
  30. package/lib/plugins/image/insert-image-handler.js.map +1 -1
  31. package/lib/plugins/index.js +23 -41
  32. package/lib/plugins/index.js.map +1 -1
  33. package/lib/plugins/list/index.js +64 -100
  34. package/lib/plugins/list/index.js.map +1 -1
  35. package/lib/plugins/math/index.js +86 -60
  36. package/lib/plugins/math/index.js.map +1 -1
  37. package/lib/plugins/media/index.js +202 -132
  38. package/lib/plugins/media/index.js.map +1 -1
  39. package/lib/plugins/media/media-dialog.js +17 -16
  40. package/lib/plugins/media/media-dialog.js.map +1 -1
  41. package/lib/plugins/media/media-toolbar.js +3 -3
  42. package/lib/plugins/media/media-toolbar.js.map +1 -1
  43. package/lib/plugins/media/media-wrapper.js +21 -58
  44. package/lib/plugins/media/media-wrapper.js.map +1 -1
  45. package/lib/plugins/respArea/drag-in-the-blank/choice.js +3 -3
  46. package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
  47. package/lib/plugins/respArea/drag-in-the-blank/index.js +3 -2
  48. package/lib/plugins/respArea/drag-in-the-blank/index.js.map +1 -1
  49. package/lib/plugins/respArea/explicit-constructed-response/index.js +3 -2
  50. package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
  51. package/lib/plugins/respArea/icons/index.js +13 -15
  52. package/lib/plugins/respArea/icons/index.js.map +1 -1
  53. package/lib/plugins/respArea/index.js +87 -53
  54. package/lib/plugins/respArea/index.js.map +1 -1
  55. package/lib/plugins/respArea/inline-dropdown/index.js +4 -3
  56. package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
  57. package/lib/plugins/respArea/utils.js +17 -20
  58. package/lib/plugins/respArea/utils.js.map +1 -1
  59. package/lib/plugins/table/icons/index.js +1 -1
  60. package/lib/plugins/table/icons/index.js.map +1 -1
  61. package/lib/plugins/table/index.js +381 -212
  62. package/lib/plugins/table/index.js.map +1 -1
  63. package/lib/plugins/table/table-toolbar.js +5 -6
  64. package/lib/plugins/table/table-toolbar.js.map +1 -1
  65. package/lib/plugins/toolbar/default-toolbar.js +55 -11
  66. package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
  67. package/lib/plugins/toolbar/done-button.js +1 -1
  68. package/lib/plugins/toolbar/done-button.js.map +1 -1
  69. package/lib/plugins/toolbar/editor-and-toolbar.js +186 -232
  70. package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
  71. package/lib/plugins/toolbar/index.js +1 -2
  72. package/lib/plugins/toolbar/index.js.map +1 -1
  73. package/lib/plugins/toolbar/toolbar-buttons.js +1 -1
  74. package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
  75. package/lib/plugins/toolbar/toolbar.js +253 -239
  76. package/lib/plugins/toolbar/toolbar.js.map +1 -1
  77. package/lib/plugins/utils.js +27 -2
  78. package/lib/plugins/utils.js.map +1 -1
  79. package/lib/serialization.js +1 -1
  80. package/lib/serialization.js.map +1 -1
  81. package/lib/slate-editor.js +302 -0
  82. package/lib/test-serializer.js +189 -0
  83. package/lib/test-serializer.js.map +1 -0
  84. package/lib/theme.js +1 -1
  85. package/lib/theme.js.map +1 -1
  86. package/package.json +18 -14
  87. package/playground/image/data.js +20 -20
  88. package/playground/image/index.html +22 -20
  89. package/playground/image/index.jsx +12 -10
  90. package/playground/index.html +25 -23
  91. package/playground/mathquill/index.html +23 -20
  92. package/playground/mathquill/index.jsx +18 -22
  93. package/playground/prod-test/index.html +24 -20
  94. package/playground/prod-test/index.jsx +5 -3
  95. package/playground/schema-override/data.js +10 -10
  96. package/playground/schema-override/image-plugin.jsx +3 -4
  97. package/playground/schema-override/index.html +21 -19
  98. package/playground/schema-override/index.jsx +13 -14
  99. package/playground/serialization/data.js +10 -10
  100. package/playground/serialization/image-plugin.jsx +3 -4
  101. package/playground/serialization/index.html +22 -20
  102. package/playground/table-examples.html +5 -8
  103. package/playground/webpack.config.js +10 -10
  104. package/src/components.js +135 -0
  105. package/src/editor.jsx +478 -141
  106. package/src/index.jsx +71 -95
  107. package/src/new-serialization.jsx +291 -0
  108. package/src/parse-html.js +1 -1
  109. package/src/plugins/characters/custom-popper.js +7 -7
  110. package/src/plugins/characters/index.jsx +33 -34
  111. package/src/plugins/characters/utils.js +81 -81
  112. package/src/plugins/hotKeys/index.js +54 -0
  113. package/src/plugins/image/alt-dialog.jsx +4 -5
  114. package/src/plugins/image/component.jsx +106 -89
  115. package/src/plugins/image/image-toolbar.jsx +27 -19
  116. package/src/plugins/image/index.jsx +75 -43
  117. package/src/plugins/image/insert-image-handler.js +62 -27
  118. package/src/plugins/index.jsx +23 -41
  119. package/src/plugins/list/index.jsx +70 -95
  120. package/src/plugins/math/index.jsx +102 -82
  121. package/src/plugins/media/index.jsx +159 -124
  122. package/src/plugins/media/media-dialog.js +98 -71
  123. package/src/plugins/media/media-toolbar.jsx +8 -8
  124. package/src/plugins/media/media-wrapper.jsx +29 -30
  125. package/src/plugins/respArea/drag-in-the-blank/choice.jsx +21 -19
  126. package/src/plugins/respArea/drag-in-the-blank/index.jsx +14 -11
  127. package/src/plugins/respArea/explicit-constructed-response/index.jsx +7 -6
  128. package/src/plugins/respArea/icons/index.jsx +11 -14
  129. package/src/plugins/respArea/index.jsx +92 -52
  130. package/src/plugins/respArea/inline-dropdown/index.jsx +9 -8
  131. package/src/plugins/respArea/utils.jsx +26 -35
  132. package/src/plugins/table/icons/index.jsx +17 -11
  133. package/src/plugins/table/index.jsx +288 -231
  134. package/src/plugins/table/table-toolbar.jsx +15 -11
  135. package/src/plugins/toolbar/default-toolbar.jsx +65 -19
  136. package/src/plugins/toolbar/done-button.jsx +4 -4
  137. package/src/plugins/toolbar/editor-and-toolbar.jsx +150 -145
  138. package/src/plugins/toolbar/index.jsx +2 -3
  139. package/src/plugins/toolbar/toolbar-buttons.jsx +11 -11
  140. package/src/plugins/toolbar/toolbar.jsx +244 -221
  141. package/src/plugins/utils.js +21 -4
  142. package/src/serialization.jsx +32 -32
  143. package/src/test-serializer.js +139 -0
  144. package/src/test-serializer.js.rej +20 -0
@@ -14,7 +14,7 @@ const log = debug('@pie-lib:editable-html:plugins:table-toolbar');
14
14
  export class TableToolbar extends React.Component {
15
15
  static propTypes = {
16
16
  plugins: PropTypes.array.isRequired,
17
- value: PropTypes.object.isRequired,
17
+ editor: PropTypes.object.isRequired,
18
18
  onChange: PropTypes.func.isRequired,
19
19
  onAddRow: PropTypes.func.isRequired,
20
20
  onRemoveRow: PropTypes.func.isRequired,
@@ -24,16 +24,15 @@ export class TableToolbar extends React.Component {
24
24
  onToggleBorder: PropTypes.func.isRequired,
25
25
  hasBorder: PropTypes.bool,
26
26
  onDone: PropTypes.func.isRequired,
27
- classes: PropTypes.object.isRequired,
27
+ classes: PropTypes.object.isRequired
28
28
  };
29
29
 
30
30
  static defaultProps = {
31
31
  plugins: [],
32
- value: {},
33
- onChange: () => {},
32
+ onChange: () => {}
34
33
  };
35
34
 
36
- onDone = (e) => {
35
+ onDone = e => {
37
36
  const { onDone } = this.props;
38
37
  e.preventDefault();
39
38
  onDone();
@@ -42,7 +41,7 @@ export class TableToolbar extends React.Component {
42
41
  render() {
43
42
  const {
44
43
  plugins,
45
- value,
44
+ editor,
46
45
  onChange,
47
46
  onAddRow,
48
47
  onRemoveRow,
@@ -51,7 +50,7 @@ export class TableToolbar extends React.Component {
51
50
  onRemoveTable,
52
51
  onToggleBorder,
53
52
  hasBorder,
54
- classes,
53
+ classes
55
54
  } = this.props;
56
55
  log('[render] hasBorder:', hasBorder);
57
56
 
@@ -74,7 +73,12 @@ export class TableToolbar extends React.Component {
74
73
  <RemoveTable />
75
74
  </Button>
76
75
  {plugins.map((p, index) => (
77
- <ToolbarButton key={`plugin-${index}`} {...p.toolbar} value={value} onChange={onChange} />
76
+ <ToolbarButton
77
+ key={`plugin-${index}`}
78
+ editor={editor}
79
+ {...p.toolbar}
80
+ onChange={onChange}
81
+ />
78
82
  ))}
79
83
  <Button onClick={onToggleBorder} active={hasBorder}>
80
84
  <BorderAll />
@@ -90,10 +94,10 @@ const styles = () => ({
90
94
  tableToolbar: {
91
95
  width: '100%',
92
96
  display: 'flex',
93
- justifyContent: 'space-between',
97
+ justifyContent: 'space-between'
94
98
  },
95
99
  toolbarButtons: {
96
- display: 'flex',
97
- },
100
+ display: 'flex'
101
+ }
98
102
  });
99
103
  export default withStyles(styles)(TableToolbar);
@@ -1,25 +1,43 @@
1
1
  import { DoneButton } from './done-button';
2
2
  import PropTypes from 'prop-types';
3
3
  import React from 'react';
4
- import SlatePropTypes from 'slate-prop-types';
5
4
 
6
5
  import { hasBlock, hasMark } from '../utils';
7
6
  import { withStyles } from '@material-ui/core/styles';
8
7
 
9
8
  import { Button, MarkButton } from './toolbar-buttons';
10
9
  import debug from 'debug';
10
+ import { Editor, Element as SlateElement } from "slate";
11
11
 
12
12
  const log = debug('@pie-lib:editable-html:plugins:toolbar');
13
13
 
14
- export const ToolbarButton = (props) => {
15
- const onToggle = () => {
16
- const c = props.onToggle(props.value.change(), props);
14
+ const isMarkActive = (editor, format) => {
15
+ const marks = Editor.marks(editor);
16
+ return marks ? marks[format] === true : false;
17
+ };
18
+
19
+ const isBlockActive = (editor, format) => {
20
+ const { selection } = editor;
21
+ if (!selection) return false;
22
+
23
+ const [match] = Array.from(
24
+ Editor.nodes(editor, {
25
+ at: Editor.unhangRange(editor, selection),
26
+ match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format
27
+ })
28
+ );
29
+
30
+ return !!match;
31
+ };
17
32
 
18
- props.onChange(c);
33
+ export const ToolbarButton = props => {
34
+ const { editor } = props;
35
+ const onToggle = () => {
36
+ props.onToggle(editor, props);
19
37
  };
20
38
 
21
39
  if (props.isMark) {
22
- const isActive = hasMark(props.value, props.type);
40
+ const isActive = isMarkActive(editor, props.type);
23
41
 
24
42
  log('[ToolbarButton] mark:isActive: ', isActive);
25
43
 
@@ -30,7 +48,9 @@ export const ToolbarButton = (props) => {
30
48
  );
31
49
  } else {
32
50
  const { disabled } = props;
33
- const isActive = props.isActive ? props.isActive(props.value, props.type) : hasBlock(props.value, props.type);
51
+ const isActive = props.isActive
52
+ ? props.isActive(editor, props.type)
53
+ : isBlockActive(editor, props.type);
34
54
 
35
55
  log('[ToolbarButton] block:isActive: ', isActive);
36
56
 
@@ -38,7 +58,7 @@ export const ToolbarButton = (props) => {
38
58
  <Button
39
59
  active={isActive}
40
60
  disabled={disabled}
41
- onClick={() => props.onClick(props.value, props.onChange, props.getFocusedValue)}
61
+ onClick={() => props.onClick(editor)}
42
62
  extraStyles={props.buttonStyles}
43
63
  >
44
64
  {props.icon}
@@ -47,13 +67,26 @@ export const ToolbarButton = (props) => {
47
67
  }
48
68
  };
49
69
 
50
- const isActiveToolbarPlugin = (props) => (plugin) => {
70
+ ToolbarButton.propTypes = {
71
+ disabled: PropTypes.bool,
72
+ icon: PropTypes.object,
73
+ editor: PropTypes.object,
74
+ isActive: PropTypes.func,
75
+ isMark: PropTypes.bool,
76
+ onClick: PropTypes.func,
77
+ onToggle: PropTypes.func,
78
+ type: PropTypes.string,
79
+ buttonStyles: PropTypes.object,
80
+ };
81
+
82
+ const isActiveToolbarPlugin = props => plugin => {
51
83
  const isDisabled = (props[plugin.name] || {}).disabled;
52
84
 
53
85
  return plugin && plugin.toolbar && !isDisabled;
54
86
  };
55
87
 
56
88
  export const DefaultToolbar = ({
89
+ editor,
57
90
  plugins,
58
91
  pluginProps,
59
92
  value,
@@ -62,20 +95,27 @@ export const DefaultToolbar = ({
62
95
  onDone,
63
96
  classes,
64
97
  showDone,
65
- deletable,
98
+ deletable
66
99
  }) => {
67
- const filtered = plugins.filter(isActiveToolbarPlugin(pluginProps)).map((p) => p.toolbar);
100
+ const filtered = plugins.filter(isActiveToolbarPlugin(pluginProps)).map(p => p.toolbar);
68
101
 
69
102
  return (
70
103
  <div className={classes.defaultToolbar}>
71
104
  <div className={classes.buttonsContainer}>
72
105
  {filtered.map((p, index) => {
73
106
  return (
74
- <ToolbarButton {...p} key={index} value={value} onChange={onChange} getFocusedValue={getFocusedValue} />
107
+ <ToolbarButton
108
+ {...p}
109
+ editor={editor}
110
+ key={index}
111
+ value={value}
112
+ onChange={onChange}
113
+ getFocusedValue={getFocusedValue}
114
+ />
75
115
  );
76
116
  })}
77
117
  </div>
78
- {showDone && !deletable && <DoneButton onClick={onDone} />}
118
+ {showDone && !deletable && <DoneButton onClick={() => onDone(editor)} />}
79
119
  </div>
80
120
  );
81
121
  };
@@ -84,30 +124,36 @@ DefaultToolbar.propTypes = {
84
124
  classes: PropTypes.object.isRequired,
85
125
  plugins: PropTypes.array.isRequired,
86
126
  pluginProps: PropTypes.object,
87
- value: SlatePropTypes.value.isRequired,
127
+ value: PropTypes.arrayOf(
128
+ PropTypes.shape({
129
+ type: PropTypes.string,
130
+ children: PropTypes.array,
131
+ data: PropTypes.object
132
+ })
133
+ ),
88
134
  onChange: PropTypes.func.isRequired,
89
135
  getFocusedValue: PropTypes.func.isRequired,
90
136
  onDone: PropTypes.func.isRequired,
91
137
  showDone: PropTypes.bool,
92
138
  addArea: PropTypes.bool,
93
- deletable: PropTypes.bool,
139
+ deletable: PropTypes.bool
94
140
  };
95
141
 
96
142
  DefaultToolbar.defaultProps = {
97
- pluginProps: {},
143
+ pluginProps: {}
98
144
  };
99
145
 
100
146
  const toolbarStyles = () => ({
101
147
  defaultToolbar: {
102
148
  display: 'flex',
103
149
  width: '100%',
104
- justifyContent: 'space-between',
150
+ justifyContent: 'space-between'
105
151
  },
106
152
  buttonsContainer: {
107
153
  alignItems: 'center',
108
154
  display: 'flex',
109
- width: '100%',
110
- },
155
+ width: '100%'
156
+ }
111
157
  });
112
158
 
113
159
  export default withStyles(toolbarStyles)(DefaultToolbar);
@@ -12,7 +12,7 @@ export const RawDoneButton = ({ classes, onClick }) => (
12
12
  onClick={onClick}
13
13
  classes={{
14
14
  label: classes.label,
15
- root: classes.iconRoot,
15
+ root: classes.iconRoot
16
16
  }}
17
17
  >
18
18
  <Check />
@@ -21,7 +21,7 @@ export const RawDoneButton = ({ classes, onClick }) => (
21
21
 
22
22
  RawDoneButton.propTypes = {
23
23
  classes: PropTypes.object.isRequired,
24
- onClick: PropTypes.func,
24
+ onClick: PropTypes.func
25
25
  };
26
26
 
27
27
  const styles = {
@@ -30,7 +30,7 @@ const styles = {
30
30
  width: '28px',
31
31
  height: '28px',
32
32
  color: 'var(--editable-html-toolbar-check, #00bb00)',
33
- padding: '4px',
34
- },
33
+ padding: '4px'
34
+ }
35
35
  };
36
36
  export const DoneButton = withStyles(styles)(RawDoneButton);
@@ -1,128 +1,16 @@
1
1
  import React from 'react';
2
+
2
3
  import Toolbar from './toolbar';
3
4
  import classNames from 'classnames';
4
5
  import debug from 'debug';
5
6
  import { primary } from '../../theme';
6
7
  import { withStyles } from '@material-ui/core/styles';
7
8
  import PropTypes from 'prop-types';
8
- import SlatePropTypes from 'slate-prop-types';
9
- import { IS_FIREFOX } from 'slate-dev-environment';
10
9
  import { color } from '@pie-lib/render-ui';
11
10
 
12
11
  const log = debug('@pie-lib:editable-html:plugins:toolbar:editor-and-toolbar');
13
12
 
14
- export class EditorAndToolbar extends React.Component {
15
- static propTypes = {
16
- children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
17
- value: SlatePropTypes.value.isRequired,
18
- plugins: PropTypes.array.isRequired,
19
- onChange: PropTypes.func.isRequired,
20
- getFocusedValue: PropTypes.func.isRequired,
21
- onDone: PropTypes.func.isRequired,
22
- onDataChange: PropTypes.func,
23
- toolbarRef: PropTypes.func,
24
- focusedNode: SlatePropTypes.node,
25
- readOnly: PropTypes.bool,
26
- disableScrollbar: PropTypes.bool,
27
- disableUnderline: PropTypes.bool,
28
- autoWidth: PropTypes.bool,
29
- classes: PropTypes.object.isRequired,
30
- pluginProps: PropTypes.object,
31
- toolbarOpts: PropTypes.shape({
32
- position: PropTypes.oneOf(['bottom', 'top']),
33
- alwaysVisible: PropTypes.bool,
34
- error: PropTypes.string,
35
- }),
36
- };
37
-
38
- /** This is an interim fix until this PR is merged in slate:
39
- * https://github.com/ianstormtaylor/slate/pull/2236
40
- */
41
- componentDidMount() {
42
- if (IS_FIREFOX) {
43
- this.editorRef.tmp.isUpdatingSelection = true;
44
- }
45
- }
46
-
47
- render() {
48
- const {
49
- classes,
50
- children,
51
- value,
52
- plugins,
53
- onChange,
54
- getFocusedValue,
55
- onDone,
56
- focusedNode,
57
- autoWidth,
58
- readOnly,
59
- disableScrollbar,
60
- disableUnderline,
61
- pluginProps,
62
- toolbarOpts,
63
- onDataChange,
64
- toolbarRef,
65
- } = this.props;
66
-
67
- const inFocus = value.isFocused || (focusedNode !== null && focusedNode !== undefined);
68
- const holderNames = classNames(classes.editorHolder, {
69
- [classes.editorInFocus]: inFocus,
70
- [classes.readOnly]: readOnly,
71
- [classes.disabledUnderline]: disableUnderline,
72
- [classes.disabledScrollbar]: disableScrollbar,
73
- });
74
- let clonedChildren = children;
75
-
76
- if (typeof children !== 'string') {
77
- clonedChildren = React.cloneElement(children, {
78
- ref: (el) => (this.editorRef = el),
79
- });
80
- }
81
-
82
- log('[render] inFocus: ', inFocus, 'value.isFocused:', value.isFocused, 'focused node: ', focusedNode);
83
-
84
- return (
85
- <div
86
- className={classNames(
87
- {
88
- [classes.noBorder]: toolbarOpts && toolbarOpts.noBorder,
89
- [classes.error]: toolbarOpts && toolbarOpts.error,
90
- },
91
- classes.root,
92
- )}
93
- >
94
- <div className={holderNames}>
95
- <div
96
- className={classNames(
97
- {
98
- [classes.noPadding]: toolbarOpts && toolbarOpts.noBorder,
99
- },
100
- classes.children,
101
- )}
102
- >
103
- {clonedChildren}
104
- </div>
105
- </div>
106
- <Toolbar
107
- autoWidth={autoWidth}
108
- plugins={plugins}
109
- focusedNode={focusedNode}
110
- value={value}
111
- isFocused={inFocus}
112
- onChange={onChange}
113
- getFocusedValue={getFocusedValue}
114
- onDone={onDone}
115
- onDataChange={onDataChange}
116
- toolbarRef={toolbarRef}
117
- pluginProps={pluginProps}
118
- toolbarOpts={toolbarOpts}
119
- />
120
- </div>
121
- );
122
- }
123
- }
124
-
125
- const style = (theme) => ({
13
+ const style = {
126
14
  root: {
127
15
  position: 'relative',
128
16
  padding: '0px',
@@ -134,11 +22,15 @@ const style = (theme) => ({
134
22
  overflow: 'visible',
135
23
  maxHeight: '500px',
136
24
  // needed in order to be able to put the focus before a void element when it is the first one in the editor
137
- padding: '5px',
25
+ padding: '5px'
138
26
  },
27
+ '& [data-slate-void="true"]': {
28
+ // needed in order to be able to put the focus before a void element when it is the first one in the editor
29
+ padding: '1px'
30
+ }
139
31
  },
140
32
  children: {
141
- padding: '10px 16px',
33
+ padding: '10px 16px'
142
34
  },
143
35
  editorHolder: {
144
36
  position: 'relative',
@@ -155,7 +47,6 @@ const style = (theme) => ({
155
47
  position: 'absolute',
156
48
  transition: 'background-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
157
49
  pointerEvents: 'none',
158
- backgroundColor: 'rgba(0, 0, 0, 0.42)',
159
50
  },
160
51
  '&::after': {
161
52
  left: '0',
@@ -165,38 +56,39 @@ const style = (theme) => ({
165
56
  content: '""',
166
57
  position: 'absolute',
167
58
  transform: 'scaleX(0)',
168
- transition: 'transform 200ms cubic-bezier(0.0, 0.0, 0.2, 1) 0ms, background-color 200ms linear',
169
- backgroundColor: 'rgba(0, 0, 0, 0.42)',
59
+ transition:
60
+ 'transform 200ms cubic-bezier(0.0, 0.0, 0.2, 1) 0ms, background-color 200ms linear',
61
+ backgroundColor: 'rgba(0, 0, 0, 0.42)'
170
62
  },
171
63
  '&:focus': {
172
64
  '&::after': {
173
65
  transform: 'scaleX(1)',
174
66
  backgroundColor: primary,
175
- height: '2px',
176
- },
67
+ height: '2px'
68
+ }
177
69
  },
178
70
  '&:hover': {
179
71
  '&::after': {
180
72
  transform: 'scaleX(1)',
181
- backgroundColor: theme.palette.common.black,
182
- height: '2px',
183
- },
184
- },
73
+ backgroundColor: 'black',
74
+ height: '2px'
75
+ }
76
+ }
185
77
  },
186
78
  disabledUnderline: {
187
79
  '&::before': {
188
- display: 'none',
80
+ display: 'none'
189
81
  },
190
82
  '&::after': {
191
- display: 'none',
192
- },
83
+ display: 'none'
84
+ }
193
85
  },
194
86
  disabledScrollbar: {
195
87
  '&::-webkit-scrollbar': {
196
- display: 'none',
88
+ display: 'none'
197
89
  },
198
90
  scrollbarWidth: 'none',
199
- '-ms-overflow-style': 'none',
91
+ '-ms-overflow-style': 'none'
200
92
  },
201
93
  readOnly: {
202
94
  '&::before': {
@@ -204,7 +96,7 @@ const style = (theme) => ({
204
96
  backgroundSize: '5px 1px',
205
97
  backgroundImage: 'linear-gradient(to right, rgba(0, 0, 0, 0.42) 33%, transparent 0%)',
206
98
  backgroundRepeat: 'repeat-x',
207
- backgroundPosition: 'left top',
99
+ backgroundPosition: 'left top'
208
100
  },
209
101
  '&::after': {
210
102
  left: '0',
@@ -215,37 +107,150 @@ const style = (theme) => ({
215
107
  position: 'absolute',
216
108
  transform: 'scaleX(0)',
217
109
  transition: 'transform 200ms cubic-bezier(0.0, 0.0, 0.2, 1) 0ms, background-color 0ms linear',
218
- backgroundColor: 'rgba(0, 0, 0, 0)',
110
+ backgroundColor: 'rgba(0, 0, 0, 0)'
219
111
  },
220
112
  '&:hover': {
221
113
  '&::after': {
222
114
  transform: 'scaleX(0)',
223
- backgroundColor: theme.palette.common.black,
224
- height: '2px',
225
- },
226
- },
115
+ backgroundColor: 'black',
116
+ height: '2px'
117
+ }
118
+ }
227
119
  },
228
120
  editorInFocus: {
229
121
  '&::after': {
230
122
  transform: 'scaleX(1)',
231
123
  backgroundColor: primary,
232
- height: '2px',
124
+ height: '2px'
233
125
  },
234
126
  '&:hover': {
235
127
  '&::after': {
236
- backgroundColor: primary,
237
- },
238
- },
128
+ backgroundColor: primary
129
+ }
130
+ }
239
131
  },
240
132
  error: {
241
- border: `2px solid ${theme.palette.error.main}`,
133
+ border: '2px solid red'
242
134
  },
243
135
  noBorder: {
244
- border: 'none',
136
+ border: 'none'
245
137
  },
246
138
  noPadding: {
247
- padding: 0,
248
- },
249
- });
139
+ padding: 0
140
+ }
141
+ };
142
+
143
+ export const EditorAndToolbar = props => {
144
+ const {
145
+ editor,
146
+ classes,
147
+ children,
148
+ value,
149
+ plugins,
150
+ onChange,
151
+ getFocusedValue,
152
+ onDone,
153
+ focusedNode,
154
+ autoWidth,
155
+ readOnly,
156
+ disableScrollbar,
157
+ disableUnderline,
158
+ pluginProps,
159
+ toolbarOpts,
160
+ toolbarRef,
161
+ isFocused
162
+ } = props;
163
+
164
+ const holderNames = classNames(classes.editorHolder, {
165
+ [classes.editorInFocus]: isFocused,
166
+ [classes.readOnly]: readOnly,
167
+ [classes.disabledUnderline]: disableUnderline,
168
+ [classes.disabledScrollbar]: disableScrollbar
169
+ });
170
+ let clonedChildren = children;
171
+
172
+ log(
173
+ '[render] inFocus: ',
174
+ isFocused,
175
+ 'value.isFocused:',
176
+ value.isFocused,
177
+ 'focused node: ',
178
+ focusedNode
179
+ );
180
+
181
+ return (
182
+ <div
183
+ className={classNames(
184
+ {
185
+ [classes.noBorder]: toolbarOpts && toolbarOpts.noBorder,
186
+ [classes.error]: toolbarOpts && toolbarOpts.error
187
+ },
188
+ classes.root
189
+ )}
190
+ >
191
+ <div className={holderNames}>
192
+ <div
193
+ className={classNames(
194
+ {
195
+ [classes.noPadding]: toolbarOpts && toolbarOpts.noBorder
196
+ },
197
+ classes.children
198
+ )}
199
+ >
200
+ {clonedChildren}
201
+ </div>
202
+ </div>
203
+ <Toolbar
204
+ editor={editor}
205
+ autoWidth={autoWidth}
206
+ plugins={plugins}
207
+ focusedNode={focusedNode}
208
+ value={value}
209
+ isFocused={isFocused}
210
+ onChange={onChange}
211
+ getFocusedValue={getFocusedValue}
212
+ onDone={onDone}
213
+ toolbarRef={toolbarRef}
214
+ pluginProps={pluginProps}
215
+ toolbarOpts={toolbarOpts}
216
+ />
217
+ </div>
218
+ );
219
+ };
220
+
221
+ EditorAndToolbar.propTypes = {
222
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
223
+ value: PropTypes.arrayOf(
224
+ PropTypes.shape({
225
+ type: PropTypes.string,
226
+ children: PropTypes.array,
227
+ data: PropTypes.object
228
+ })
229
+ ),
230
+ editor: PropTypes.object.isRequired,
231
+ isFocused: PropTypes.bool,
232
+ plugins: PropTypes.array.isRequired,
233
+ onChange: PropTypes.func.isRequired,
234
+ getFocusedValue: PropTypes.func.isRequired,
235
+ onDone: PropTypes.func.isRequired,
236
+ toolbarRef: PropTypes.func,
237
+ focusedNode: PropTypes.shape({
238
+ type: PropTypes.string,
239
+ children: PropTypes.array,
240
+ data: PropTypes.object
241
+ }),
242
+ readOnly: PropTypes.bool,
243
+ disableScrollbar: PropTypes.bool,
244
+ disableUnderline: PropTypes.bool,
245
+ autoWidth: PropTypes.bool,
246
+ classes: PropTypes.object.isRequired,
247
+ pluginProps: PropTypes.object,
248
+ toolbarOpts: PropTypes.shape({
249
+ alwaysVisible: PropTypes.bool,
250
+ error: PropTypes.string,
251
+ noBorder: PropTypes.bool,
252
+ position: PropTypes.oneOf(['bottom', 'top'])
253
+ })
254
+ };
250
255
 
251
256
  export default withStyles(style)(EditorAndToolbar);
@@ -9,15 +9,14 @@ import EditorAndToolbar from './editor-and-toolbar';
9
9
  export default function ToolbarPlugin(opts) {
10
10
  return {
11
11
  /* eslint-disable-next-line */
12
- renderEditor: (props) => (
12
+ renderEditor: props => (
13
13
  <EditorAndToolbar
14
14
  {...props}
15
15
  mainEditorRef={opts.mainEditorRef}
16
16
  disableScrollbar={opts.disableScrollbar}
17
17
  disableUnderline={opts.disableUnderline}
18
- autoWidth={opts.autoWidth}
19
18
  onDone={opts.onDone}
20
19
  />
21
- ),
20
+ )
22
21
  };
23
22
  }