@kids-reporter/draft-editor 1.0.11 → 1.0.13

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.
@@ -7,6 +7,7 @@ exports.atomicBlockRenderer = atomicBlockRenderer;
7
7
  var _blockquote = require("./block-renderers/blockquote");
8
8
  var _embeddedCode = require("./block-renderers/embedded-code");
9
9
  var _image = require("./block-renderers/image");
10
+ var _imageLink = require("./block-renderers/image-link");
10
11
  var _infoBox = require("./block-renderers/info-box");
11
12
  var _slideshow = require("./block-renderers/slideshow");
12
13
  var _draftRenderer = require("@kids-reporter/draft-renderer");
@@ -25,6 +26,8 @@ const AtomicBlock = props => {
25
26
  return Divider();
26
27
  case 'IMAGE':
27
28
  return (0, _image.EditableImage)(props);
29
+ case 'IMAGE_LINK':
30
+ return (0, _imageLink.EditableImageLink)(props);
28
31
  case 'SLIDESHOW':
29
32
  return (0, _slideshow.EditableSlideshow)(props);
30
33
  case 'EMBEDDEDCODE':
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ImageLinkEditor = exports.EditableImageLink = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
9
+ var _modals = require("@keystone-ui/modals");
10
+ var _fields = require("@keystone-ui/fields");
11
+ var _draftJs = require("draft-js");
12
+ var _draftRenderer = require("@kids-reporter/draft-renderer");
13
+ var _imageSelector = require("../buttons/selector/image-selector");
14
+ var _alignSelector = require("../buttons/selector/align-selector");
15
+ var _styled = require("./styled");
16
+ var _richTextEditor = require("../rich-text-editor");
17
+ var _link = require("../entity-decorators/link");
18
+ var _btNames = _interopRequireDefault(require("../buttons/bt-names"));
19
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
22
+ const disabledButtons = [_btNames.default.bold, _btNames.default.italic, _btNames.default.underline, _btNames.default.fontColor, _btNames.default.backgroundColor, _btNames.default.ol, _btNames.default.ul, _btNames.default.divider, _btNames.default.h2, _btNames.default.h3, _btNames.default.h4, _btNames.default.h5, _btNames.default.code, _btNames.default.codeBlock, _btNames.default.blockquote, _btNames.default.infoBox, _btNames.default.slideshow, _btNames.default.newsReading, _btNames.default.tocAnchor, _btNames.default.anchor, _btNames.default.embed, _btNames.default.annotation, _btNames.default.image, _btNames.default.imageLink];
23
+ const {
24
+ ImageLinkInArticleBody
25
+ } = _draftRenderer.blockRenderers;
26
+ const StyledImage = (0, _styledComponents.default)(ImageLinkInArticleBody)``;
27
+ const Label = _styledComponents.default.label`
28
+ display: block;
29
+ margin: 10px 0;
30
+ font-weight: 600;
31
+ `;
32
+ const EditableBlock = (0, _styledComponents.default)(_styled.EditableBlock)`
33
+ &:hover {
34
+ ${StyledImage} {
35
+ background-color: #f0f0f0;
36
+ opacity: 0.3;
37
+ }
38
+ `;
39
+ const ImageLinkEditor = props => {
40
+ const {
41
+ isOpen,
42
+ inputValue,
43
+ onConfirm,
44
+ onCancel
45
+ } = props;
46
+ const [url, setURL] = (0, _react.useState)(inputValue.url ?? '');
47
+ const [align, setAlign] = (0, _react.useState)(inputValue.alignment ?? _imageSelector.ImageAlignment.DEFAULT);
48
+ const contentState = (0, _draftJs.convertFromRaw)(inputValue.rawContentState);
49
+ const [description, setDescription] = (0, _react.useState)({
50
+ value: _draftJs.EditorState.createWithContent(contentState)
51
+ });
52
+ const contentWrapperRef = (0, _react.useRef)(null);
53
+ const onAlignSelectChange = align => {
54
+ setAlign(align);
55
+ };
56
+ const onAlignSelectOpen = () => {
57
+ var _contentWrapperRef$cu;
58
+ const scrollWrapper = (_contentWrapperRef$cu = contentWrapperRef.current) === null || _contentWrapperRef$cu === void 0 ? void 0 : _contentWrapperRef$cu.parentElement;
59
+ if (scrollWrapper) {
60
+ scrollWrapper.scrollTop = scrollWrapper === null || scrollWrapper === void 0 ? void 0 : scrollWrapper.scrollHeight;
61
+ }
62
+ };
63
+ return /*#__PURE__*/_react.default.createElement(_modals.DrawerController, {
64
+ isOpen: isOpen
65
+ }, /*#__PURE__*/_react.default.createElement(_modals.Drawer, {
66
+ title: "Image Link",
67
+ actions: {
68
+ cancel: {
69
+ label: 'Cancel',
70
+ action: () => onCancel()
71
+ },
72
+ confirm: {
73
+ label: 'Confirm',
74
+ action: () => onConfirm({
75
+ url: url,
76
+ alignment: align,
77
+ rawContentState: (0, _draftJs.convertToRaw)(description.value.getCurrentContent())
78
+ })
79
+ }
80
+ }
81
+ }, /*#__PURE__*/_react.default.createElement(Label, null, "\u9023\u7D50"), /*#__PURE__*/_react.default.createElement(_fields.TextInput, {
82
+ placeholder: "\u5716\u7247\u9023\u7D50",
83
+ type: "text",
84
+ value: url,
85
+ onChange: e => setURL(e.target.value)
86
+ }), /*#__PURE__*/_react.default.createElement(_alignSelector.AlignSelector, {
87
+ align: align,
88
+ options: _imageSelector.ImageAlignOptions,
89
+ onChange: onAlignSelectChange,
90
+ onOpen: onAlignSelectOpen
91
+ }), /*#__PURE__*/_react.default.createElement(Label, null, "\u5716\u8AAA"), /*#__PURE__*/_react.default.createElement(_richTextEditor.RichTextEditor, {
92
+ decorators: [_link.editableLinkDecorator],
93
+ disabledButtons: disabledButtons,
94
+ editorState: description.value,
95
+ onChange: editorState => {
96
+ setDescription({
97
+ value: editorState
98
+ });
99
+ }
100
+ })));
101
+ };
102
+ exports.ImageLinkEditor = ImageLinkEditor;
103
+ const EditableImageLink = props => {
104
+ const [isEditorOpen, setIsEditorOpen] = (0, _react.useState)(false);
105
+ const {
106
+ block,
107
+ blockProps,
108
+ contentState
109
+ } = props;
110
+ const {
111
+ onEditStart,
112
+ onEditFinish
113
+ } = blockProps;
114
+ const entityKey = block.getEntityAt(0);
115
+ const entity = contentState.getEntity(entityKey);
116
+ const data = entity.getData() || {};
117
+ const {
118
+ url,
119
+ alignment,
120
+ rawContentState
121
+ } = data; // eslint-disable-line
122
+
123
+ const onChange = inputValue => {
124
+ setIsEditorOpen(false);
125
+ onEditFinish({
126
+ entityKey,
127
+ entityData: inputValue
128
+ });
129
+ };
130
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isEditorOpen && /*#__PURE__*/_react.default.createElement(ImageLinkEditor, {
131
+ isOpen: isEditorOpen,
132
+ inputValue: {
133
+ url: url,
134
+ alignment: alignment,
135
+ rawContentState: rawContentState
136
+ },
137
+ onConfirm: onChange,
138
+ onCancel: () => {
139
+ setIsEditorOpen(false);
140
+ onEditFinish();
141
+ }
142
+ }), /*#__PURE__*/_react.default.createElement(EditableBlock, {
143
+ component: /*#__PURE__*/_react.default.createElement(StyledImage, {
144
+ data: data
145
+ }),
146
+ onClick: () => {
147
+ onEditStart();
148
+ setIsEditorOpen(true);
149
+ }
150
+ }));
151
+ };
152
+ exports.EditableImageLink = EditableImageLink;
@@ -26,6 +26,7 @@ var _default = exports.default = {
26
26
  annotation: 'annotation',
27
27
  embed: 'embed',
28
28
  image: 'image',
29
+ imageLink: 'image-link',
29
30
  infoBox: 'info-box',
30
31
  link: 'link',
31
32
  slideshow: 'slideshow',
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ImageLinkButton = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _draftJs = require("draft-js");
9
+ var _imageLink = require("../block-renderers/image-link");
10
+ var _imageSelector = require("../buttons/selector/image-selector");
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ const ImageLinkButton = props => {
14
+ const {
15
+ editorState,
16
+ onChange: onEditorStateChange,
17
+ className
18
+ } = props;
19
+ const [isEditorOpen, setIsEditorOpen] = (0, _react.useState)(false);
20
+ const promptForImageLinkEditor = () => {
21
+ setIsEditorOpen(true);
22
+ };
23
+ const onChange = ({
24
+ url,
25
+ alignment,
26
+ rawContentState
27
+ }) => {
28
+ const contentState = editorState.getCurrentContent();
29
+ const contentStateWithEntity = contentState.createEntity('IMAGE_LINK', 'IMMUTABLE', {
30
+ url,
31
+ alignment,
32
+ rawContentState
33
+ });
34
+ const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
35
+ const newEditorState = _draftJs.EditorState.set(editorState, {
36
+ currentContent: contentStateWithEntity
37
+ });
38
+
39
+ //The third parameter here is a space string, not an empty string
40
+ //If you set an empty string, you will get an error: Unknown DraftEntity key: null
41
+ onEditorStateChange(_draftJs.AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' '));
42
+ setIsEditorOpen(false);
43
+ };
44
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isEditorOpen && /*#__PURE__*/_react.default.createElement(_imageLink.ImageLinkEditor, {
45
+ isOpen: isEditorOpen,
46
+ inputValue: {
47
+ url: '',
48
+ alignment: _imageSelector.ImageAlignment.DEFAULT,
49
+ rawContentState: {
50
+ blocks: [],
51
+ entityMap: {}
52
+ }
53
+ },
54
+ onConfirm: onChange,
55
+ onCancel: () => {
56
+ setIsEditorOpen(false);
57
+ }
58
+ }), /*#__PURE__*/_react.default.createElement("div", {
59
+ className: className,
60
+ onClick: promptForImageLinkEditor
61
+ }, /*#__PURE__*/_react.default.createElement("i", {
62
+ className: "far fa-image"
63
+ }), /*#__PURE__*/_react.default.createElement("span", null, " ImageLink")));
64
+ };
65
+ exports.ImageLinkButton = ImageLinkButton;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.withStyle = exports.InlineStyleControls = exports.CustomTOCAnchorButton = exports.CustomSlideshowButton = exports.CustomNewsReadingButton = exports.CustomLinkButton = exports.CustomInfoBoxButton = exports.CustomImageButton = exports.CustomFontColorButton = exports.CustomEnlargeButton = exports.CustomEmbeddedCodeButton = exports.CustomDividerButton = exports.CustomBlockquoteButton = exports.CustomBackgroundColorButton = exports.CustomAnnotationButton = exports.CustomAnchorButton = exports.BlockStyleControls = void 0;
6
+ exports.withStyle = exports.InlineStyleControls = exports.CustomTOCAnchorButton = exports.CustomSlideshowButton = exports.CustomNewsReadingButton = exports.CustomLinkButton = exports.CustomInfoBoxButton = exports.CustomImageLinkButton = exports.CustomImageButton = exports.CustomFontColorButton = exports.CustomEnlargeButton = exports.CustomEmbeddedCodeButton = exports.CustomDividerButton = exports.CustomBlockquoteButton = exports.CustomBackgroundColorButton = exports.CustomAnnotationButton = exports.CustomAnchorButton = exports.BlockStyleControls = void 0;
7
7
  var _styledComponents = _interopRequireDefault(require("styled-components"));
8
8
  var _controlButtons = require("./control-buttons");
9
9
  var _bgColor = require("./bg-color");
@@ -13,6 +13,7 @@ var _embeddedCode = require("./embedded-code");
13
13
  var _enlarge = require("./enlarge");
14
14
  var _fontColor = require("./font-color");
15
15
  var _image = require("./image");
16
+ var _imageLink = require("./image-link");
16
17
  var _tocAnchor = require("./toc-anchor");
17
18
  var _anchor = require("./anchor");
18
19
  var _link = require("./link");
@@ -38,6 +39,7 @@ const CustomEnlargeButton = exports.CustomEnlargeButton = (0, _styledComponents.
38
39
  color: #999;
39
40
  `;
40
41
  const CustomImageButton = exports.CustomImageButton = withStyle(_image.ImageButton);
42
+ const CustomImageLinkButton = exports.CustomImageLinkButton = withStyle(_imageLink.ImageLinkButton);
41
43
  const CustomSlideshowButton = exports.CustomSlideshowButton = withStyle(_slideshow.SlideshowButton);
42
44
  const CustomEmbeddedCodeButton = exports.CustomEmbeddedCodeButton = withStyle(_embeddedCode.EmbeddedCodeButton);
43
45
  const CustomNewsReadingButton = exports.CustomNewsReadingButton = withStyle(_newsReading.NewsReadingButton);
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.ImageAlignment = exports.ImageAlignOptions = void 0;
6
7
  exports.ImageSelector = ImageSelector;
7
8
  var _react = _interopRequireWildcard(require("react"));
8
9
  var _debounce = _interopRequireDefault(require("lodash/debounce"));
@@ -15,6 +16,30 @@ var _pagination = require("./pagination");
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
19
+ let ImageAlignment = exports.ImageAlignment = /*#__PURE__*/function (ImageAlignment) {
20
+ ImageAlignment["DEFAULT"] = "default";
21
+ ImageAlignment["PARAGRAPH"] = "paragraph-width";
22
+ ImageAlignment["LEFT"] = "left";
23
+ ImageAlignment["RIGHT"] = "right";
24
+ return ImageAlignment;
25
+ }({});
26
+ const ImageAlignOptions = exports.ImageAlignOptions = [{
27
+ value: ImageAlignment.DEFAULT,
28
+ label: '預設',
29
+ isDisabled: false
30
+ }, {
31
+ value: ImageAlignment.PARAGRAPH,
32
+ label: '與文章段落等寬',
33
+ isDisabled: false
34
+ }, {
35
+ value: ImageAlignment.LEFT,
36
+ label: '靠左',
37
+ isDisabled: false
38
+ }, {
39
+ value: ImageAlignment.RIGHT,
40
+ label: '靠右',
41
+ isDisabled: false
42
+ }];
18
43
  const _ = {
19
44
  debounce: _debounce.default
20
45
  };
@@ -135,7 +160,7 @@ const imagesQuery = (0, _apollo.gql)`
135
160
  }
136
161
  `;
137
162
  function ImageSelector(props) {
138
- const alignment = props.alignment || 'default';
163
+ const alignment = props.alignment || ImageAlignment.DEFAULT;
139
164
  const [queryImages, {
140
165
  loading,
141
166
  error,
@@ -152,23 +177,6 @@ function ImageSelector(props) {
152
177
  const [align, setAlign] = (0, _react.useState)(alignment);
153
178
  const contentWrapperRef = (0, _react.useRef)(null);
154
179
  const pageSize = 6;
155
- const options = [{
156
- value: 'default',
157
- label: 'default',
158
- isDisabled: false
159
- }, {
160
- value: 'paragraph-width',
161
- label: '與文章段落等寬',
162
- isDisabled: false
163
- }, {
164
- value: 'left',
165
- label: 'left',
166
- isDisabled: false
167
- }, {
168
- value: 'right',
169
- label: 'right',
170
- isDisabled: false
171
- }];
172
180
  const {
173
181
  enableMultiSelect = false,
174
182
  enableCaption = false,
@@ -280,7 +288,7 @@ function ImageSelector(props) {
280
288
  enableDelete: enableMultiSelect
281
289
  })), enableAlignment && /*#__PURE__*/_react.default.createElement(_alignSelector.AlignSelector, {
282
290
  align: align,
283
- options: options,
291
+ options: ImageAlignOptions,
284
292
  onChange: onAlignSelectChange,
285
293
  onOpen: onAlignSelectOpen
286
294
  }))));
@@ -215,6 +215,8 @@ class RichTextEditor extends _react.default.Component {
215
215
  }, commonProps, this.commonEditProps)), /*#__PURE__*/_react.default.createElement(_buttons.CustomImageButton, _extends({
216
216
  isDisabled: disabledButtons.includes(_btNames.default.image),
217
217
  ImageSelector: _imageSelector.ImageSelector
218
+ }, commonProps)), /*#__PURE__*/_react.default.createElement(_buttons.CustomImageLinkButton, _extends({
219
+ isDisabled: disabledButtons.includes(_btNames.default.imageLink)
218
220
  }, commonProps)), /*#__PURE__*/_react.default.createElement(_buttons.CustomSlideshowButton, _extends({
219
221
  isDisabled: disabledButtons.includes(_btNames.default.slideshow),
220
222
  ImageSelector: _imageSelector.ImageSelector
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kids-reporter/draft-editor",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@kids-reporter/draft-renderer": "1.0.9",
26
+ "@kids-reporter/draft-renderer": "1.0.11",
27
27
  "@twreporter/errors": "^1.1.2",
28
28
  "draft-js": "^0.11.7"
29
29
  },