@atlaskit/editor-plugin-placeholder-text 0.1.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.
Files changed (73) hide show
  1. package/.eslintrc.js +14 -0
  2. package/CHANGELOG.md +1 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +30 -0
  5. package/dist/cjs/actions.js +35 -0
  6. package/dist/cjs/fake-text-cursor/cursor.js +107 -0
  7. package/dist/cjs/index.js +13 -0
  8. package/dist/cjs/placeholder-text-nodeview.js +89 -0
  9. package/dist/cjs/plugin-key.js +8 -0
  10. package/dist/cjs/plugin.js +270 -0
  11. package/dist/cjs/selection-utils.js +14 -0
  12. package/dist/cjs/styles.js +13 -0
  13. package/dist/cjs/types.js +5 -0
  14. package/dist/cjs/ui/FloatingToolbar/index.js +88 -0
  15. package/dist/cjs/ui/FloatingToolbar/styles.js +15 -0
  16. package/dist/cjs/ui/FloatingToolbar/utils.js +55 -0
  17. package/dist/cjs/ui/PlaceholderFloatingToolbar/index.js +90 -0
  18. package/dist/es2019/actions.js +27 -0
  19. package/dist/es2019/fake-text-cursor/cursor.js +77 -0
  20. package/dist/es2019/index.js +1 -0
  21. package/dist/es2019/placeholder-text-nodeview.js +77 -0
  22. package/dist/es2019/plugin-key.js +2 -0
  23. package/dist/es2019/plugin.js +250 -0
  24. package/dist/es2019/selection-utils.js +8 -0
  25. package/dist/es2019/styles.js +52 -0
  26. package/dist/es2019/types.js +1 -0
  27. package/dist/es2019/ui/FloatingToolbar/index.js +49 -0
  28. package/dist/es2019/ui/FloatingToolbar/styles.js +15 -0
  29. package/dist/es2019/ui/FloatingToolbar/utils.js +42 -0
  30. package/dist/es2019/ui/PlaceholderFloatingToolbar/index.js +61 -0
  31. package/dist/esm/actions.js +29 -0
  32. package/dist/esm/fake-text-cursor/cursor.js +100 -0
  33. package/dist/esm/index.js +1 -0
  34. package/dist/esm/placeholder-text-nodeview.js +82 -0
  35. package/dist/esm/plugin-key.js +2 -0
  36. package/dist/esm/plugin.js +262 -0
  37. package/dist/esm/selection-utils.js +8 -0
  38. package/dist/esm/styles.js +6 -0
  39. package/dist/esm/types.js +1 -0
  40. package/dist/esm/ui/FloatingToolbar/index.js +67 -0
  41. package/dist/esm/ui/FloatingToolbar/styles.js +8 -0
  42. package/dist/esm/ui/FloatingToolbar/utils.js +49 -0
  43. package/dist/esm/ui/PlaceholderFloatingToolbar/index.js +80 -0
  44. package/dist/types/actions.d.ts +4 -0
  45. package/dist/types/fake-text-cursor/cursor.d.ts +30 -0
  46. package/dist/types/index.d.ts +2 -0
  47. package/dist/types/placeholder-text-nodeview.d.ts +17 -0
  48. package/dist/types/plugin-key.d.ts +3 -0
  49. package/dist/types/plugin.d.ts +7 -0
  50. package/dist/types/selection-utils.d.ts +2 -0
  51. package/dist/types/styles.d.ts +1 -0
  52. package/dist/types/types.d.ts +22 -0
  53. package/dist/types/ui/FloatingToolbar/index.d.ts +28 -0
  54. package/dist/types/ui/FloatingToolbar/styles.d.ts +1 -0
  55. package/dist/types/ui/FloatingToolbar/utils.d.ts +18 -0
  56. package/dist/types/ui/PlaceholderFloatingToolbar/index.d.ts +25 -0
  57. package/dist/types-ts4.5/actions.d.ts +4 -0
  58. package/dist/types-ts4.5/fake-text-cursor/cursor.d.ts +30 -0
  59. package/dist/types-ts4.5/index.d.ts +2 -0
  60. package/dist/types-ts4.5/placeholder-text-nodeview.d.ts +17 -0
  61. package/dist/types-ts4.5/plugin-key.d.ts +3 -0
  62. package/dist/types-ts4.5/plugin.d.ts +7 -0
  63. package/dist/types-ts4.5/selection-utils.d.ts +2 -0
  64. package/dist/types-ts4.5/styles.d.ts +1 -0
  65. package/dist/types-ts4.5/types.d.ts +22 -0
  66. package/dist/types-ts4.5/ui/FloatingToolbar/index.d.ts +28 -0
  67. package/dist/types-ts4.5/ui/FloatingToolbar/styles.d.ts +1 -0
  68. package/dist/types-ts4.5/ui/FloatingToolbar/utils.d.ts +18 -0
  69. package/dist/types-ts4.5/ui/PlaceholderFloatingToolbar/index.d.ts +25 -0
  70. package/package.json +100 -0
  71. package/report.api.md +80 -0
  72. package/styles/package.json +15 -0
  73. package/tmp/api-report-tmp.d.ts +49 -0
@@ -0,0 +1,82 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import { browser, ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/utils';
4
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
5
+ var serializePlaceholderNode = function serializePlaceholderNode(node) {
6
+ var element = document.createElement('span');
7
+ element.classList.add('pm-placeholder');
8
+
9
+ // the inline node api test suite requires the following class name
10
+ element.classList.add('placeholderView-content-wrap');
11
+ element.innerText = ZERO_WIDTH_SPACE;
12
+ var elementChildren = document.createElement('span');
13
+ elementChildren.classList.add('pm-placeholder__text');
14
+ elementChildren.dataset.placeholder = node.attrs.text;
15
+ elementChildren.setAttribute('contenteditable', 'false');
16
+ element.appendChild(elementChildren);
17
+ if (browser.safari) {
18
+ element.appendChild(document.createTextNode(ZERO_WIDTH_SPACE));
19
+ } else {
20
+ element.appendChild(document.createElement('wbr'));
21
+ }
22
+ return element;
23
+ };
24
+ export var PlaceholderTextNodeView = /*#__PURE__*/function () {
25
+ function PlaceholderTextNodeView(node, view, getPos) {
26
+ _classCallCheck(this, PlaceholderTextNodeView);
27
+ this.node = node;
28
+ this.view = view;
29
+ this.getPos = getPos;
30
+ this.dom = serializePlaceholderNode(this.node);
31
+ this.getPos = getPos;
32
+ }
33
+ _createClass(PlaceholderTextNodeView, [{
34
+ key: "stopEvent",
35
+ value: function stopEvent(e) {
36
+ if (e.type === 'mousedown' && typeof this.getPos === 'function') {
37
+ e.preventDefault();
38
+ var _view = this.view;
39
+ var startNodePosition = this.getPos();
40
+ if (typeof startNodePosition !== 'number') {
41
+ return false;
42
+ }
43
+ var tr = _view.state.tr;
44
+ tr.setSelection(Selection.near(tr.doc.resolve(startNodePosition)));
45
+ _view.dispatch(tr);
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ }, {
51
+ key: "ignoreMutation",
52
+ value: function ignoreMutation(record) {
53
+ if (typeof this.getPos !== 'function' || record.type !== 'selection') {
54
+ return true;
55
+ }
56
+ var view = this.view,
57
+ node = this.node;
58
+ var placeholderStartPosition = this.getPos();
59
+ if (typeof placeholderStartPosition !== 'number') {
60
+ return false;
61
+ }
62
+ var placeholderEndPosition = placeholderStartPosition + node.nodeSize;
63
+ var selection = view.state.selection;
64
+
65
+ // when the selection is set right after the placeholder.
66
+ // we should let ProseMirror deal with this edge-case
67
+ if (selection.from === placeholderEndPosition) {
68
+ return false;
69
+ }
70
+ var isSelectionAtPlaceholder = selection.from === placeholderStartPosition;
71
+ var isSelectionAfterlaceholder = selection.from > placeholderEndPosition;
72
+ if (isSelectionAtPlaceholder || isSelectionAfterlaceholder) {
73
+ var tr = view.state.tr;
74
+ tr.setSelection(Selection.near(tr.doc.resolve(placeholderEndPosition)));
75
+ view.dispatch(tr);
76
+ return true;
77
+ }
78
+ return true;
79
+ }
80
+ }]);
81
+ return PlaceholderTextNodeView;
82
+ }();
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export var pluginKey = new PluginKey('placeholderTextPlugin');
@@ -0,0 +1,262 @@
1
+ import React from 'react';
2
+ import { placeholder } from '@atlaskit/adf-schema';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
5
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
6
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
7
+ import { isNodeEmpty } from '@atlaskit/editor-common/utils';
8
+ import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
9
+ import MediaServicesTextIcon from '@atlaskit/icon/glyph/media-services/text';
10
+ import { hidePlaceholderFloatingToolbar, insertPlaceholderTextAtSelection, showPlaceholderFloatingToolbar } from './actions';
11
+ import { drawFakeTextCursor, FakeTextCursorSelection } from './fake-text-cursor/cursor';
12
+ import { PlaceholderTextNodeView } from './placeholder-text-nodeview';
13
+ import { pluginKey } from './plugin-key';
14
+ import { isSelectionAtPlaceholder } from './selection-utils';
15
+ import PlaceholderFloatingToolbar from './ui/PlaceholderFloatingToolbar';
16
+ var getOpenTypeAhead = function getOpenTypeAhead(trigger, api) {
17
+ var _api$typeAhead, _api$typeAhead2;
18
+ var typeAheadHandler = api === null || api === void 0 || (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 || (_api$typeAhead = _api$typeAhead.actions) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.findHandlerByTrigger(trigger);
19
+ if (!typeAheadHandler || !typeAheadHandler.id) {
20
+ return null;
21
+ }
22
+ return api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 || (_api$typeAhead2 = _api$typeAhead2.actions) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.openAtTransaction({
23
+ triggerHandler: typeAheadHandler,
24
+ inputMethod: INPUT_METHOD.KEYBOARD
25
+ });
26
+ };
27
+ export function createPlugin(dispatch, options, api) {
28
+ var allowInserting = !!options.allowInserting;
29
+ return new SafePlugin({
30
+ key: pluginKey,
31
+ state: {
32
+ init: function init() {
33
+ return {
34
+ showInsertPanelAt: null,
35
+ allowInserting: allowInserting
36
+ };
37
+ },
38
+ apply: function apply(tr, state) {
39
+ var meta = tr.getMeta(pluginKey);
40
+ if (meta && meta.showInsertPanelAt !== undefined) {
41
+ var newState = {
42
+ showInsertPanelAt: meta.showInsertPanelAt,
43
+ allowInserting: allowInserting
44
+ };
45
+ dispatch(pluginKey, newState);
46
+ return newState;
47
+ } else if (state.showInsertPanelAt) {
48
+ var _newState = {
49
+ showInsertPanelAt: tr.mapping.map(state.showInsertPanelAt),
50
+ allowInserting: allowInserting
51
+ };
52
+ dispatch(pluginKey, _newState);
53
+ return _newState;
54
+ }
55
+ return state;
56
+ }
57
+ },
58
+ appendTransaction: function appendTransaction(transactions, oldState, newState) {
59
+ if (transactions.some(function (txn) {
60
+ return txn.docChanged;
61
+ })) {
62
+ var didPlaceholderExistBeforeTxn = oldState.selection.$head.nodeAfter === newState.selection.$head.nodeAfter;
63
+ var adjacentNode = newState.selection.$head.nodeAfter;
64
+ var adjacentNodePos = newState.selection.$head.pos;
65
+ var placeholderNodeType = newState.schema.nodes.placeholder;
66
+ if (adjacentNode && adjacentNode.type === placeholderNodeType && didPlaceholderExistBeforeTxn) {
67
+ var _$newHead$nodeBefore;
68
+ var $newHead = newState.selection.$head;
69
+ var $oldHead = oldState.selection.$head;
70
+ // Check that cursor has moved forward in the document **and** that there is content before the cursor
71
+ var cursorMoved = $oldHead.pos < $newHead.pos;
72
+ var nodeBeforeHasContent = !isNodeEmpty($newHead.nodeBefore);
73
+ var nodeBeforeIsInline = (_$newHead$nodeBefore = $newHead.nodeBefore) === null || _$newHead$nodeBefore === void 0 ? void 0 : _$newHead$nodeBefore.type.isInline;
74
+ if (cursorMoved && (nodeBeforeHasContent || nodeBeforeIsInline)) {
75
+ var _NodeSelection$create = NodeSelection.create(newState.doc, adjacentNodePos),
76
+ $from = _NodeSelection$create.$from,
77
+ $to = _NodeSelection$create.$to;
78
+ return newState.tr.deleteRange($from.pos, $to.pos);
79
+ }
80
+ }
81
+ }
82
+
83
+ // Handle Fake Text Cursor for Floating Toolbar
84
+ if (!pluginKey.getState(oldState).showInsertPanelAt && pluginKey.getState(newState).showInsertPanelAt) {
85
+ return newState.tr.setSelection(new FakeTextCursorSelection(newState.selection.$from));
86
+ }
87
+ if (pluginKey.getState(oldState).showInsertPanelAt && !pluginKey.getState(newState).showInsertPanelAt) {
88
+ if (newState.selection instanceof FakeTextCursorSelection) {
89
+ return newState.tr.setSelection(new TextSelection(newState.selection.$from));
90
+ }
91
+ }
92
+ return;
93
+ },
94
+ props: {
95
+ decorations: drawFakeTextCursor,
96
+ handleDOMEvents: {
97
+ beforeinput: function beforeinput(view, event) {
98
+ var state = view.state;
99
+ if (event instanceof InputEvent && !event.isComposing && event.inputType === 'insertText' && isSelectionAtPlaceholder(view.state.selection)) {
100
+ event.stopPropagation();
101
+ event.preventDefault();
102
+ var startNodePosition = state.selection.from;
103
+ var content = event.data || '';
104
+ var tr = view.state.tr;
105
+ tr.delete(startNodePosition, startNodePosition + 1);
106
+ var openTypeAhead = getOpenTypeAhead(content, api);
107
+ if (openTypeAhead) {
108
+ openTypeAhead(tr);
109
+ } else {
110
+ tr.insertText(content);
111
+ }
112
+ view.dispatch(tr);
113
+ return true;
114
+ }
115
+ return false;
116
+ }
117
+ },
118
+ nodeViews: {
119
+ placeholder: function placeholder(node, view, getPos) {
120
+ return new PlaceholderTextNodeView(node, view, getPos);
121
+ }
122
+ }
123
+ }
124
+ });
125
+ }
126
+ function ContentComponent(_ref) {
127
+ var editorView = _ref.editorView,
128
+ dependencyApi = _ref.dependencyApi,
129
+ popupsMountPoint = _ref.popupsMountPoint,
130
+ popupsBoundariesElement = _ref.popupsBoundariesElement;
131
+ var _useSharedPluginState = useSharedPluginState(dependencyApi, ['placeholderText']),
132
+ placeholderTextState = _useSharedPluginState.placeholderTextState;
133
+ var insertPlaceholderText = function insertPlaceholderText(value) {
134
+ return insertPlaceholderTextAtSelection(value)(editorView.state, editorView.dispatch);
135
+ };
136
+ var hidePlaceholderToolbar = function hidePlaceholderToolbar() {
137
+ return hidePlaceholderFloatingToolbar(editorView.state, editorView.dispatch);
138
+ };
139
+ var getNodeFromPos = function getNodeFromPos(pos) {
140
+ return editorView.domAtPos(pos).node;
141
+ };
142
+ var getFixedCoordinatesFromPos = function getFixedCoordinatesFromPos(pos) {
143
+ return editorView.coordsAtPos(pos);
144
+ };
145
+ var setFocusInEditor = function setFocusInEditor() {
146
+ return editorView.focus();
147
+ };
148
+ if (placeholderTextState !== null && placeholderTextState !== void 0 && placeholderTextState.showInsertPanelAt) {
149
+ return /*#__PURE__*/React.createElement(PlaceholderFloatingToolbar, {
150
+ editorViewDOM: editorView.dom,
151
+ popupsMountPoint: popupsMountPoint,
152
+ popupsBoundariesElement: popupsBoundariesElement,
153
+ getFixedCoordinatesFromPos: getFixedCoordinatesFromPos,
154
+ getNodeFromPos: getNodeFromPos,
155
+ hidePlaceholderFloatingToolbar: hidePlaceholderToolbar,
156
+ showInsertPanelAt: placeholderTextState.showInsertPanelAt,
157
+ insertPlaceholder: insertPlaceholderText,
158
+ setFocusInEditor: setFocusInEditor
159
+ });
160
+ }
161
+ return null;
162
+ }
163
+ var basePlaceholderTextPlugin = function basePlaceholderTextPlugin(_ref2) {
164
+ var api = _ref2.api,
165
+ options = _ref2.config;
166
+ return {
167
+ name: 'placeholderText',
168
+ nodes: function nodes() {
169
+ return [{
170
+ name: 'placeholder',
171
+ node: placeholder
172
+ }];
173
+ },
174
+ pmPlugins: function pmPlugins() {
175
+ return [{
176
+ name: 'placeholderText',
177
+ plugin: function plugin(_ref3) {
178
+ var dispatch = _ref3.dispatch;
179
+ return createPlugin(dispatch, options, api);
180
+ }
181
+ }];
182
+ },
183
+ actions: {
184
+ showPlaceholderFloatingToolbar: showPlaceholderFloatingToolbar
185
+ },
186
+ getSharedState: function getSharedState(editorState) {
187
+ if (!editorState) {
188
+ return undefined;
189
+ }
190
+ var _ref4 = pluginKey.getState(editorState) || {
191
+ showInsertPanelAt: null
192
+ },
193
+ showInsertPanelAt = _ref4.showInsertPanelAt,
194
+ allowInserting = _ref4.allowInserting;
195
+ return {
196
+ showInsertPanelAt: showInsertPanelAt,
197
+ allowInserting: !!allowInserting
198
+ };
199
+ },
200
+ contentComponent: function contentComponent(_ref5) {
201
+ var editorView = _ref5.editorView,
202
+ popupsMountPoint = _ref5.popupsMountPoint,
203
+ popupsBoundariesElement = _ref5.popupsBoundariesElement;
204
+ return /*#__PURE__*/React.createElement(ContentComponent, {
205
+ editorView: editorView,
206
+ popupsMountPoint: popupsMountPoint,
207
+ popupsBoundariesElement: popupsBoundariesElement,
208
+ dependencyApi: api
209
+ });
210
+ }
211
+ };
212
+ };
213
+ var decorateWithPluginOptions = function decorateWithPluginOptions(plugin, options, api) {
214
+ if (!options.allowInserting) {
215
+ return plugin;
216
+ }
217
+ plugin.pluginsOptions = {
218
+ quickInsert: function quickInsert(_ref6) {
219
+ var formatMessage = _ref6.formatMessage;
220
+ return [{
221
+ id: 'placeholderText',
222
+ title: formatMessage(messages.placeholderText),
223
+ description: formatMessage(messages.placeholderTextDescription),
224
+ priority: 1400,
225
+ keywords: ['placeholder'],
226
+ icon: function icon() {
227
+ return /*#__PURE__*/React.createElement(MediaServicesTextIcon, {
228
+ label: ""
229
+ });
230
+ },
231
+ action: function action(insert, state) {
232
+ var _api$analytics;
233
+ var tr = state.tr;
234
+ tr.setMeta(pluginKey, {
235
+ showInsertPanelAt: tr.selection.anchor
236
+ });
237
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.attachAnalyticsEvent({
238
+ action: ACTION.INSERTED,
239
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
240
+ actionSubjectId: ACTION_SUBJECT_ID.PLACEHOLDER_TEXT,
241
+ attributes: {
242
+ inputMethod: INPUT_METHOD.QUICK_INSERT
243
+ },
244
+ eventType: EVENT_TYPE.TRACK
245
+ })(tr);
246
+ return tr;
247
+ }
248
+ }];
249
+ }
250
+ };
251
+ return plugin;
252
+ };
253
+ var placeholderTextPlugin = function placeholderTextPlugin(_ref7) {
254
+ var _ref7$config = _ref7.config,
255
+ options = _ref7$config === void 0 ? {} : _ref7$config,
256
+ api = _ref7.api;
257
+ return decorateWithPluginOptions(basePlaceholderTextPlugin({
258
+ config: options,
259
+ api: api
260
+ }), options, api);
261
+ };
262
+ export default placeholderTextPlugin;
@@ -0,0 +1,8 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export var isSelectionAtPlaceholder = function isSelectionAtPlaceholder(selection) {
3
+ if (!(selection instanceof TextSelection) || !selection.$cursor) {
4
+ return false;
5
+ }
6
+ var node = selection.$cursor.doc.nodeAt(selection.$cursor.pos);
7
+ return (node === null || node === void 0 ? void 0 : node.type.name) === 'placeholder';
8
+ };
@@ -0,0 +1,6 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+ var _templateObject;
3
+ import { css } from '@emotion/react';
4
+ import { akEditorSelectedNodeClassName, getSelectionStyles, SelectionStyle } from '@atlaskit/editor-shared-styles';
5
+ import { B75, N200 } from '@atlaskit/theme/colors';
6
+ export var placeholderTextStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n .ProseMirror span[data-placeholder] {\n color: ", ";\n display: inline;\n }\n\n .ProseMirror span.pm-placeholder {\n display: inline;\n color: ", ";\n }\n .ProseMirror span.pm-placeholder__text {\n display: inline;\n color: ", ";\n }\n\n .ProseMirror span.pm-placeholder.", " {\n ", "\n }\n\n .ProseMirror span.pm-placeholder__text[data-placeholder]::after {\n color: ", ";\n cursor: text;\n content: attr(data-placeholder);\n display: inline;\n }\n\n .ProseMirror {\n .ProseMirror-fake-text-cursor {\n display: inline;\n pointer-events: none;\n position: relative;\n }\n\n .ProseMirror-fake-text-cursor::after {\n content: '';\n display: inline;\n top: 0;\n position: absolute;\n border-right: 1px solid ", ";\n }\n\n .ProseMirror-fake-text-selection {\n display: inline;\n pointer-events: none;\n position: relative;\n background-color: ", ";\n }\n }\n"])), "var(--ds-text-subtlest, ".concat(N200, ")"), "var(--ds-text-subtlest, ".concat(N200, ")"), "var(--ds-text-subtlest, ".concat(N200, ")"), akEditorSelectedNodeClassName, getSelectionStyles([SelectionStyle.Background]), "var(--ds-text-subtlest, ".concat(N200, ")"), "var(--ds-border, rgba(0, 0, 0, 0.4))", "var(--ds-background-selected, ".concat(B75, ")"));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _inherits from "@babel/runtime/helpers/inherits";
4
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
5
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
6
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
7
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
8
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
9
+ /** @jsx jsx */
10
+ import { PureComponent } from 'react';
11
+ import { jsx } from '@emotion/react';
12
+ import { Popup } from '@atlaskit/editor-common/ui';
13
+ import { container } from './styles';
14
+ export { handlePositionCalculatedWith, getOffsetParent, getNearestNonTextNode } from './utils';
15
+
16
+ // eslint-disable-next-line @repo/internal/react/no-class-components
17
+ var FloatingToolbar = /*#__PURE__*/function (_PureComponent) {
18
+ _inherits(FloatingToolbar, _PureComponent);
19
+ var _super = _createSuper(FloatingToolbar);
20
+ function FloatingToolbar() {
21
+ _classCallCheck(this, FloatingToolbar);
22
+ return _super.apply(this, arguments);
23
+ }
24
+ _createClass(FloatingToolbar, [{
25
+ key: "render",
26
+ value: function render() {
27
+ var _this$props = this.props,
28
+ children = _this$props.children,
29
+ target = _this$props.target,
30
+ offset = _this$props.offset,
31
+ fitWidth = _this$props.fitWidth,
32
+ _this$props$fitHeight = _this$props.fitHeight,
33
+ fitHeight = _this$props$fitHeight === void 0 ? 40 : _this$props$fitHeight,
34
+ onPositionCalculated = _this$props.onPositionCalculated,
35
+ popupsMountPoint = _this$props.popupsMountPoint,
36
+ popupsBoundariesElement = _this$props.popupsBoundariesElement,
37
+ className = _this$props.className,
38
+ absoluteOffset = _this$props.absoluteOffset,
39
+ alignX = _this$props.alignX,
40
+ alignY = _this$props.alignY,
41
+ zIndex = _this$props.zIndex;
42
+ if (!target) {
43
+ return null;
44
+ }
45
+ return jsx(Popup, {
46
+ absoluteOffset: absoluteOffset,
47
+ alignX: alignX,
48
+ alignY: alignY,
49
+ target: target,
50
+ zIndex: zIndex,
51
+ mountTo: popupsMountPoint,
52
+ boundariesElement: popupsBoundariesElement,
53
+ offset: offset,
54
+ fitWidth: fitWidth,
55
+ fitHeight: fitHeight,
56
+ onPositionCalculated: onPositionCalculated
57
+ }, jsx("div", {
58
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
59
+ css: container(fitHeight),
60
+ "data-testid": "popup-container",
61
+ className: className
62
+ }, children));
63
+ }
64
+ }]);
65
+ return FloatingToolbar;
66
+ }(PureComponent);
67
+ export { FloatingToolbar as default };
@@ -0,0 +1,8 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+ var _templateObject, _templateObject2;
3
+ import { css } from '@emotion/react';
4
+ import { N0, N50A, N60A } from '@atlaskit/theme/colors';
5
+ import { borderRadius } from '@atlaskit/theme/constants';
6
+ export var container = function container(height) {
7
+ return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n border-radius: ", "px;\n box-shadow: ", ";\n display: flex;\n align-items: center;\n box-sizing: border-box;\n padding: ", " ", ";\n background-color: ", ";\n ", ";\n"])), borderRadius(), "var(--ds-shadow-overlay, ".concat("0 12px 24px -6px ".concat(N50A, ", 0 0 1px ").concat(N60A), ")"), "var(--ds-space-050, 4px)", "var(--ds-space-100, 8px)", "var(--ds-background-input, ".concat(N0, ")"), height ? css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n height: ", "px;\n "])), height) : '');
8
+ };
@@ -0,0 +1,49 @@
1
+ var getCursorHeightFrom = function getCursorHeightFrom(node) {
2
+ return parseFloat(window.getComputedStyle(node, undefined).lineHeight || '');
3
+ };
4
+ export var getOffsetParent = function getOffsetParent(editorViewDom, popupsMountPoint) {
5
+ return popupsMountPoint ? popupsMountPoint.offsetParent : editorViewDom.offsetParent;
6
+ };
7
+ export var getNearestNonTextNode = function getNearestNonTextNode(node) {
8
+ return node.nodeType === Node.TEXT_NODE ? node.parentNode : node;
9
+ };
10
+
11
+ /**
12
+ * We need to translate the co-ordinates because `coordsAtPos` returns co-ordinates
13
+ * relative to `window`. And, also need to adjust the cursor container height.
14
+ * (0, 0)
15
+ * +--------------------- [window] ---------------------+
16
+ * | (left, top) +-------- [Offset Parent] --------+ |
17
+ * | {coordsAtPos} | [Cursor] <- cursorHeight | |
18
+ * | | [FloatingToolbar] | |
19
+ */
20
+ var convertFixedCoordinatesToAbsolutePositioning = function convertFixedCoordinatesToAbsolutePositioning(coordinates, offsetParent, cursorHeight) {
21
+ var _coordinates$left, _coordinates$right, _coordinates$top, _coordinates$top2;
22
+ var _offsetParent$getBoun = offsetParent.getBoundingClientRect(),
23
+ offsetParentLeft = _offsetParent$getBoun.left,
24
+ offsetParentTop = _offsetParent$getBoun.top,
25
+ offsetParentHeight = _offsetParent$getBoun.height;
26
+ return {
27
+ left: ((_coordinates$left = coordinates.left) !== null && _coordinates$left !== void 0 ? _coordinates$left : 0) - offsetParentLeft,
28
+ right: ((_coordinates$right = coordinates.right) !== null && _coordinates$right !== void 0 ? _coordinates$right : 0) - offsetParentLeft,
29
+ top: ((_coordinates$top = coordinates.top) !== null && _coordinates$top !== void 0 ? _coordinates$top : 0) - (offsetParentTop - cursorHeight) + offsetParent.scrollTop,
30
+ bottom: offsetParentHeight - (((_coordinates$top2 = coordinates.top) !== null && _coordinates$top2 !== void 0 ? _coordinates$top2 : 0) - (offsetParentTop - cursorHeight) - offsetParent.scrollTop)
31
+ };
32
+ };
33
+ export var handlePositionCalculatedWith = function handlePositionCalculatedWith(offsetParent, node, getCurrentFixedCoordinates) {
34
+ return function (position) {
35
+ if (!offsetParent) {
36
+ return position;
37
+ }
38
+ var target = getNearestNonTextNode(node);
39
+ var cursorHeight = getCursorHeightFrom(target);
40
+ var fixedCoordinates = getCurrentFixedCoordinates();
41
+ var absoluteCoordinates = convertFixedCoordinatesToAbsolutePositioning(fixedCoordinates, offsetParent, cursorHeight);
42
+ return {
43
+ left: position.left ? absoluteCoordinates.left : undefined,
44
+ right: position.right ? absoluteCoordinates.right : undefined,
45
+ top: position.top ? absoluteCoordinates.top : undefined,
46
+ bottom: position.bottom ? absoluteCoordinates.bottom : undefined
47
+ };
48
+ };
49
+ };
@@ -0,0 +1,80 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
4
+ import _inherits from "@babel/runtime/helpers/inherits";
5
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
6
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
7
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
9
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
10
+ import React from 'react';
11
+ import { defineMessages, injectIntl } from 'react-intl-next';
12
+ import { PanelTextInput } from '@atlaskit/editor-common/ui';
13
+ import FloatingToolbar, { getNearestNonTextNode, getOffsetParent, handlePositionCalculatedWith } from '../FloatingToolbar';
14
+ export var messages = defineMessages({
15
+ placeholderTextPlaceholder: {
16
+ id: 'fabric.editor.placeholderTextPlaceholder',
17
+ defaultMessage: 'Add placeholder text',
18
+ description: ''
19
+ }
20
+ });
21
+ // eslint-disable-next-line @repo/internal/react/no-class-components
22
+ var PlaceholderFloatingToolbar = /*#__PURE__*/function (_React$Component) {
23
+ _inherits(PlaceholderFloatingToolbar, _React$Component);
24
+ var _super = _createSuper(PlaceholderFloatingToolbar);
25
+ function PlaceholderFloatingToolbar() {
26
+ var _this;
27
+ _classCallCheck(this, PlaceholderFloatingToolbar);
28
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
29
+ args[_key] = arguments[_key];
30
+ }
31
+ _this = _super.call.apply(_super, [this].concat(args));
32
+ _defineProperty(_assertThisInitialized(_this), "handleSubmit", function (value) {
33
+ if (value) {
34
+ _this.props.insertPlaceholder(value);
35
+ _this.props.setFocusInEditor();
36
+ } else {
37
+ _this.props.hidePlaceholderFloatingToolbar();
38
+ }
39
+ });
40
+ _defineProperty(_assertThisInitialized(_this), "handleBlur", function () {
41
+ _this.props.hidePlaceholderFloatingToolbar();
42
+ });
43
+ return _this;
44
+ }
45
+ _createClass(PlaceholderFloatingToolbar, [{
46
+ key: "render",
47
+ value: function render() {
48
+ var _this$props = this.props,
49
+ getNodeFromPos = _this$props.getNodeFromPos,
50
+ showInsertPanelAt = _this$props.showInsertPanelAt,
51
+ editorViewDOM = _this$props.editorViewDOM,
52
+ popupsMountPoint = _this$props.popupsMountPoint,
53
+ getFixedCoordinatesFromPos = _this$props.getFixedCoordinatesFromPos,
54
+ popupsBoundariesElement = _this$props.popupsBoundariesElement,
55
+ formatMessage = _this$props.intl.formatMessage;
56
+ var target = getNodeFromPos(showInsertPanelAt);
57
+ var offsetParent = getOffsetParent(editorViewDOM, popupsMountPoint);
58
+ var getFixedCoordinates = function getFixedCoordinates() {
59
+ return getFixedCoordinatesFromPos(showInsertPanelAt);
60
+ };
61
+ var handlePositionCalculated = handlePositionCalculatedWith(offsetParent, target, getFixedCoordinates);
62
+ return /*#__PURE__*/React.createElement(FloatingToolbar, {
63
+ target: getNearestNonTextNode(target),
64
+ onPositionCalculated: handlePositionCalculated,
65
+ popupsMountPoint: popupsMountPoint,
66
+ popupsBoundariesElement: popupsBoundariesElement,
67
+ fitHeight: 32,
68
+ offset: [0, 12]
69
+ }, /*#__PURE__*/React.createElement(PanelTextInput, {
70
+ placeholder: formatMessage(messages.placeholderTextPlaceholder),
71
+ onSubmit: this.handleSubmit,
72
+ onBlur: this.handleBlur,
73
+ autoFocus: true,
74
+ width: 300
75
+ }));
76
+ }
77
+ }]);
78
+ return PlaceholderFloatingToolbar;
79
+ }(React.Component);
80
+ export default injectIntl(PlaceholderFloatingToolbar);
@@ -0,0 +1,4 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const showPlaceholderFloatingToolbar: (state: EditorState, dispatch: (tr: Transaction) => void) => boolean;
3
+ export declare const insertPlaceholderTextAtSelection: (value: string) => (state: EditorState, dispatch: (tr: Transaction) => void) => boolean;
4
+ export declare const hidePlaceholderFloatingToolbar: (state: EditorState, dispatch: (tr: Transaction) => void) => boolean;
@@ -0,0 +1,30 @@
1
+ import type { Node, ResolvedPos } from '@atlaskit/editor-prosemirror/model';
2
+ import { Slice } from '@atlaskit/editor-prosemirror/model';
3
+ import type { EditorState, SelectionBookmark, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
5
+ import type { Mappable } from '@atlaskit/editor-prosemirror/transform';
6
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
+ export declare class FakeTextCursorBookmark {
8
+ pos: undefined | number;
9
+ visible: boolean;
10
+ constructor(pos: number);
11
+ map(mapping: Mappable): FakeTextCursorBookmark;
12
+ resolve(doc: Node): Selection;
13
+ }
14
+ export declare class FakeTextCursorSelection extends Selection {
15
+ constructor($pos: ResolvedPos);
16
+ map(doc: Node, mapping: Mappable): Selection;
17
+ static content(): Slice;
18
+ eq(other: Selection): boolean;
19
+ toJSON(): {
20
+ type: string;
21
+ pos: number;
22
+ };
23
+ static fromJSON(doc: Node, json: {
24
+ pos: number;
25
+ }): Selection;
26
+ getBookmark(): SelectionBookmark;
27
+ }
28
+ export declare const addFakeTextCursor: (state: EditorState, dispatch: (tr: Transaction) => void) => void;
29
+ export declare const removeFakeTextCursor: (state: EditorState, dispatch: (tr: Transaction) => void) => void;
30
+ export declare const drawFakeTextCursor: (state: EditorState) => DecorationSet | null;
@@ -0,0 +1,2 @@
1
+ export { default as placeholderTextPlugin } from './plugin';
2
+ export type { PlaceholderTextPlugin, PlaceholderTextPluginState, PlaceholderTextOptions, } from './types';
@@ -0,0 +1,17 @@
1
+ import type { getPosHandler } from '@atlaskit/editor-common/react-node-view';
2
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
+ import type { EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
4
+ type PmMutationRecord = MutationRecord | {
5
+ type: 'selection';
6
+ target: Element;
7
+ };
8
+ export declare class PlaceholderTextNodeView implements NodeView {
9
+ private readonly node;
10
+ private readonly view;
11
+ private readonly getPos;
12
+ readonly dom: Node;
13
+ constructor(node: PMNode, view: EditorView, getPos: getPosHandler);
14
+ stopEvent(e: Event): boolean;
15
+ ignoreMutation(record: PmMutationRecord): boolean;
16
+ }
17
+ export {};
@@ -0,0 +1,3 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ import type { PlaceholderTextPluginState } from './types';
3
+ export declare const pluginKey: PluginKey<PlaceholderTextPluginState>;
@@ -0,0 +1,7 @@
1
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
+ import type { PlaceholderTextOptions, PlaceholderTextPlugin, PlaceholderTextPluginState } from './types';
5
+ export declare function createPlugin(dispatch: Dispatch<PlaceholderTextPluginState>, options: PlaceholderTextOptions, api: ExtractInjectionAPI<PlaceholderTextPlugin> | undefined): SafePlugin | undefined;
6
+ declare const placeholderTextPlugin: PlaceholderTextPlugin;
7
+ export default placeholderTextPlugin;
@@ -0,0 +1,2 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const isSelectionAtPlaceholder: (selection: Selection) => boolean;
@@ -0,0 +1 @@
1
+ export declare const placeholderTextStyles: import("@emotion/react").SerializedStyles;