@atlaskit/editor-plugin-date 0.1.0 → 0.2.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 (76) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/actions.js +105 -0
  3. package/dist/cjs/commands.js +114 -1
  4. package/dist/cjs/index.js +9 -1
  5. package/dist/cjs/nodeviews/date.js +44 -0
  6. package/dist/cjs/plugin.js +197 -0
  7. package/dist/cjs/pm-plugins/keymap.js +41 -0
  8. package/dist/cjs/pm-plugins/main.js +39 -0
  9. package/dist/cjs/pm-plugins/plugin-key.js +8 -0
  10. package/dist/cjs/pm-plugins/types.js +5 -0
  11. package/dist/cjs/pm-plugins/utils.js +70 -0
  12. package/dist/cjs/ui/DatePicker/date-picker-input.js +253 -0
  13. package/dist/cjs/ui/DatePicker/index.js +170 -0
  14. package/dist/cjs/utils/formatParse.js +88 -0
  15. package/dist/cjs/utils/internal.js +176 -0
  16. package/dist/es2019/actions.js +93 -0
  17. package/dist/es2019/commands.js +113 -1
  18. package/dist/es2019/index.js +1 -1
  19. package/dist/es2019/nodeviews/date.js +47 -0
  20. package/dist/es2019/plugin.js +183 -0
  21. package/dist/es2019/pm-plugins/keymap.js +34 -0
  22. package/dist/es2019/pm-plugins/main.js +35 -0
  23. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  24. package/dist/es2019/pm-plugins/types.js +1 -0
  25. package/dist/es2019/pm-plugins/utils.js +70 -0
  26. package/dist/es2019/ui/DatePicker/date-picker-input.js +242 -0
  27. package/dist/es2019/ui/DatePicker/index.js +154 -0
  28. package/dist/es2019/utils/formatParse.js +83 -0
  29. package/dist/es2019/utils/internal.js +151 -0
  30. package/dist/esm/actions.js +99 -0
  31. package/dist/esm/commands.js +112 -1
  32. package/dist/esm/index.js +1 -1
  33. package/dist/esm/nodeviews/date.js +37 -0
  34. package/dist/esm/plugin.js +185 -0
  35. package/dist/esm/pm-plugins/keymap.js +34 -0
  36. package/dist/esm/pm-plugins/main.js +34 -0
  37. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  38. package/dist/esm/pm-plugins/types.js +1 -0
  39. package/dist/esm/pm-plugins/utils.js +61 -0
  40. package/dist/esm/ui/DatePicker/date-picker-input.js +247 -0
  41. package/dist/esm/ui/DatePicker/index.js +164 -0
  42. package/dist/esm/utils/formatParse.js +79 -0
  43. package/dist/esm/utils/internal.js +165 -0
  44. package/dist/types/actions.d.ts +49 -0
  45. package/dist/types/commands.d.ts +12 -10
  46. package/dist/types/index.d.ts +1 -1
  47. package/dist/types/nodeviews/date.d.ts +3 -0
  48. package/dist/types/plugin.d.ts +3 -0
  49. package/dist/types/pm-plugins/keymap.d.ts +3 -0
  50. package/dist/types/pm-plugins/main.d.ts +6 -0
  51. package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
  52. package/dist/types/pm-plugins/types.d.ts +12 -0
  53. package/dist/types/pm-plugins/utils.d.ts +5 -0
  54. package/dist/types/types.d.ts +10 -2
  55. package/dist/types/ui/DatePicker/date-picker-input.d.ts +25 -0
  56. package/dist/types/ui/DatePicker/index.d.ts +36 -0
  57. package/dist/types/utils/formatParse.d.ts +27 -0
  58. package/dist/types/utils/internal.d.ts +32 -0
  59. package/dist/types-ts4.5/actions.d.ts +60 -0
  60. package/dist/types-ts4.5/commands.d.ts +14 -10
  61. package/dist/types-ts4.5/index.d.ts +1 -1
  62. package/dist/types-ts4.5/nodeviews/date.d.ts +3 -0
  63. package/dist/types-ts4.5/plugin.d.ts +3 -0
  64. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +3 -0
  65. package/dist/types-ts4.5/pm-plugins/main.d.ts +6 -0
  66. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
  67. package/dist/types-ts4.5/pm-plugins/types.d.ts +12 -0
  68. package/dist/types-ts4.5/pm-plugins/utils.d.ts +5 -0
  69. package/dist/types-ts4.5/types.d.ts +10 -2
  70. package/dist/types-ts4.5/ui/DatePicker/date-picker-input.d.ts +25 -0
  71. package/dist/types-ts4.5/ui/DatePicker/index.d.ts +36 -0
  72. package/dist/types-ts4.5/utils/formatParse.d.ts +27 -0
  73. package/dist/types-ts4.5/utils/internal.d.ts +32 -0
  74. package/package.json +29 -4
  75. package/report.api.md +5 -2
  76. package/tmp/api-report-tmp.d.ts +5 -2
@@ -0,0 +1,93 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { todayTimestampInUTC } from '@atlaskit/editor-common/utils';
3
+ import { Fragment } from '@atlaskit/editor-prosemirror/model';
4
+ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
5
+ import { pluginKey } from './pm-plugins/plugin-key';
6
+ import { isToday } from './utils/internal';
7
+ export const createDate = isQuickInsertAction => (insert, state) => {
8
+ const dateNode = state.schema.nodes.date.createChecked({
9
+ timestamp: todayTimestampInUTC()
10
+ });
11
+ const space = state.schema.text(' ');
12
+ const tr = insert(Fragment.from([dateNode, space]), {
13
+ selectInlineNode: true
14
+ });
15
+ const newPluginState = {
16
+ isQuickInsertAction,
17
+ showDatePickerAt: tr.selection.from,
18
+ isNew: true,
19
+ isDateEmpty: false,
20
+ focusDateInput: false
21
+ };
22
+ return tr.setMeta(pluginKey, newPluginState);
23
+ };
24
+
25
+ /** Focus input */
26
+ export const focusDateInput = () => (state, dispatch) => {
27
+ const pluginState = pluginKey.getState(state);
28
+ if (!pluginState || pluginState.showDatePickerAt === null) {
29
+ return false;
30
+ }
31
+ if (!dispatch) {
32
+ return false;
33
+ }
34
+ const tr = state.tr.setMeta(pluginKey, {
35
+ focusDateInput: true
36
+ });
37
+ dispatch(tr);
38
+ return true;
39
+ };
40
+ export const setDatePickerAt = showDatePickerAt => (state, dispatch) => {
41
+ dispatch(state.tr.setMeta(pluginKey, {
42
+ showDatePickerAt
43
+ }));
44
+ return true;
45
+ };
46
+ export const closeDatePicker = () => (state, dispatch) => {
47
+ const {
48
+ showDatePickerAt
49
+ } = pluginKey.getState(state) || {};
50
+ if (!dispatch) {
51
+ return false;
52
+ }
53
+ const tr = showDatePickerAt ? state.tr.setMeta(pluginKey, {
54
+ showDatePickerAt: null,
55
+ isNew: false
56
+ }).setSelection(Selection.near(state.tr.doc.resolve(showDatePickerAt + 2))) : state.tr.setMeta(pluginKey, {
57
+ isNew: false
58
+ });
59
+ dispatch(tr);
60
+ return false;
61
+ };
62
+ export const closeDatePickerWithAnalytics = ({
63
+ date,
64
+ pluginInjectionApi
65
+ }) => {
66
+ var _pluginInjectionApi$a, _pluginInjectionApi$a2;
67
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : (_pluginInjectionApi$a2 = _pluginInjectionApi$a.actions) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.attachAnalyticsEvent({
68
+ eventType: EVENT_TYPE.TRACK,
69
+ action: ACTION.COMMITTED,
70
+ actionSubject: ACTION_SUBJECT.DATE,
71
+ attributes: {
72
+ commitMethod: INPUT_METHOD.BLUR,
73
+ isValid: date !== undefined,
74
+ isToday: isToday(date)
75
+ }
76
+ });
77
+ return closeDatePicker();
78
+ };
79
+ export const openDatePicker = () => (state, dispatch) => {
80
+ const {
81
+ $from
82
+ } = state.selection;
83
+ const node = state.doc.nodeAt($from.pos);
84
+ if (node && node.type.name === state.schema.nodes.date.name) {
85
+ const showDatePickerAt = $from.pos;
86
+ if (dispatch) {
87
+ dispatch(state.tr.setMeta(pluginKey, {
88
+ showDatePickerAt
89
+ }).setSelection(NodeSelection.create(state.doc, showDatePickerAt)));
90
+ }
91
+ }
92
+ return false;
93
+ };
@@ -1 +1,113 @@
1
- export {};
1
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
+ import { todayTimestampInUTC } from '@atlaskit/editor-common/utils';
3
+ import { Fragment } from '@atlaskit/editor-prosemirror/model';
4
+ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
5
+ import { canInsert } from '@atlaskit/editor-prosemirror/utils';
6
+ import { pluginKey } from './pm-plugins/plugin-key';
7
+ import { isToday } from './utils/internal';
8
+ /** Delete the date and close the datepicker */
9
+ export const deleteDateCommand = pluginInjectionApi => ({
10
+ tr
11
+ }) => {
12
+ var _pluginInjectionApi$d, _pluginInjectionApi$d2;
13
+ const {
14
+ showDatePickerAt
15
+ } = (_pluginInjectionApi$d = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d2 = pluginInjectionApi.date) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.sharedState.currentState()) !== null && _pluginInjectionApi$d !== void 0 ? _pluginInjectionApi$d : {};
16
+ if (!showDatePickerAt) {
17
+ return tr;
18
+ }
19
+ tr.delete(showDatePickerAt, showDatePickerAt + 1).setMeta(pluginKey, {
20
+ showDatePickerAt: null,
21
+ isNew: false
22
+ });
23
+ return tr;
24
+ };
25
+ export const insertDateCommand = pluginInjectionApi => ({
26
+ date,
27
+ inputMethod,
28
+ commitMethod,
29
+ enterPressed = true
30
+ }) => ({
31
+ tr
32
+ }) => {
33
+ var _pluginInjectionApi$d3, _pluginInjectionApi$d4;
34
+ const {
35
+ schema
36
+ } = tr.doc.type;
37
+ let timestamp;
38
+ if (date) {
39
+ timestamp = Date.UTC(date.year, date.month - 1, date.day).toString();
40
+ } else {
41
+ timestamp = todayTimestampInUTC();
42
+ }
43
+ if (inputMethod) {
44
+ var _pluginInjectionApi$a, _pluginInjectionApi$a2;
45
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : (_pluginInjectionApi$a2 = _pluginInjectionApi$a.actions) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.attachAnalyticsEvent({
46
+ action: ACTION.INSERTED,
47
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
48
+ actionSubjectId: ACTION_SUBJECT_ID.DATE,
49
+ eventType: EVENT_TYPE.TRACK,
50
+ attributes: {
51
+ inputMethod
52
+ }
53
+ })(tr);
54
+ }
55
+ if (commitMethod) {
56
+ var _pluginInjectionApi$a3, _pluginInjectionApi$a4;
57
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 ? void 0 : (_pluginInjectionApi$a4 = _pluginInjectionApi$a3.actions) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.attachAnalyticsEvent({
58
+ eventType: EVENT_TYPE.TRACK,
59
+ action: ACTION.COMMITTED,
60
+ actionSubject: ACTION_SUBJECT.DATE,
61
+ attributes: {
62
+ commitMethod,
63
+ isValid: date !== undefined,
64
+ isToday: isToday(date)
65
+ }
66
+ })(tr);
67
+ }
68
+ const {
69
+ showDatePickerAt
70
+ } = (_pluginInjectionApi$d3 = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d4 = pluginInjectionApi.date) === null || _pluginInjectionApi$d4 === void 0 ? void 0 : _pluginInjectionApi$d4.sharedState.currentState()) !== null && _pluginInjectionApi$d3 !== void 0 ? _pluginInjectionApi$d3 : {};
71
+ if (!showDatePickerAt) {
72
+ const dateNode = schema.nodes.date.createChecked({
73
+ timestamp
74
+ });
75
+ const textNode = schema.text(' ');
76
+ const fragment = Fragment.fromArray([dateNode, textNode]);
77
+ const {
78
+ from,
79
+ to
80
+ } = tr.selection;
81
+ const insertable = canInsert(tr.selection.$from, fragment);
82
+ if (!insertable) {
83
+ const parentSelection = NodeSelection.create(tr.doc, tr.selection.from - tr.selection.$anchor.parentOffset - 1);
84
+ tr.insert(parentSelection.to, fragment).setSelection(NodeSelection.create(tr.doc, parentSelection.to + 1));
85
+ } else {
86
+ tr.replaceWith(from, to, fragment).setSelection(NodeSelection.create(tr.doc, from));
87
+ }
88
+ if (tr.docChanged) {
89
+ tr.scrollIntoView().setMeta(pluginKey, {
90
+ isNew: true
91
+ });
92
+ }
93
+ return tr;
94
+ }
95
+ if (tr.doc.nodeAt(showDatePickerAt)) {
96
+ if (enterPressed) {
97
+ // Setting selection to outside the date node causes showDatePickerAt
98
+ // to be set to null by the PM plugin (onSelectionChanged), which will
99
+ // immediately close the datepicker once a valid date is typed in.
100
+ // Adding this check forces it to stay open until the user presses Enter.
101
+ tr = tr.setSelection(Selection.near(tr.doc.resolve(showDatePickerAt + 2)));
102
+ }
103
+ tr = tr.setNodeMarkup(showDatePickerAt, schema.nodes.date, {
104
+ timestamp
105
+ }).setMeta(pluginKey, {
106
+ isNew: false
107
+ }).scrollIntoView();
108
+ if (!enterPressed) {
109
+ tr = tr.setSelection(NodeSelection.create(tr.doc, showDatePickerAt));
110
+ }
111
+ }
112
+ return tr;
113
+ };
@@ -1 +1 @@
1
- export {};
1
+ export { default as datePlugin } from './plugin';
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { Date } from '@atlaskit/date';
4
+ import { DateSharedCssClassName } from '@atlaskit/editor-common/styles';
5
+ import { isPastDate, timestampToString, timestampToTaskContext } from '@atlaskit/editor-common/utils';
6
+ import { setDatePickerAt } from '../actions';
7
+ export function DateNodeView(props) {
8
+ const {
9
+ node: {
10
+ attrs: {
11
+ timestamp
12
+ }
13
+ },
14
+ view: {
15
+ state: {
16
+ doc,
17
+ schema,
18
+ selection
19
+ }
20
+ },
21
+ getPos
22
+ } = props;
23
+ const intl = useIntl();
24
+ let pos = typeof getPos === 'function' ? getPos() : undefined;
25
+
26
+ // We fall back to selection.$from even though it does not cover all use cases
27
+ // eg. upon Editor init, selection is at the start, not at the Date node
28
+ const $nodePos = typeof pos === 'number' ? doc.resolve(pos) : selection.$from;
29
+ const parent = $nodePos.parent;
30
+ const withinIncompleteTask = parent.type === schema.nodes.taskItem && parent.attrs.state !== 'DONE';
31
+ const color = withinIncompleteTask && isPastDate(timestamp) ? 'red' : undefined;
32
+ return /*#__PURE__*/React.createElement("span", {
33
+ className: DateSharedCssClassName.DATE_WRAPPER,
34
+ onClick: handleClick
35
+ }, /*#__PURE__*/React.createElement(Date, {
36
+ color: color,
37
+ value: timestamp
38
+ }, withinIncompleteTask ? timestampToTaskContext(timestamp, intl) : timestampToString(timestamp, intl)));
39
+ function handleClick(event) {
40
+ event.nativeEvent.stopImmediatePropagation();
41
+ const {
42
+ state,
43
+ dispatch
44
+ } = props.view;
45
+ setDatePickerAt(state.selection.from)(state, dispatch);
46
+ }
47
+ }
@@ -0,0 +1,183 @@
1
+ import React from 'react';
2
+ import Loadable from 'react-loadable';
3
+ import { date } from '@atlaskit/adf-schema';
4
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
6
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
7
+ import { IconDate } from '@atlaskit/editor-common/quick-insert';
8
+ import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
9
+ import { closeDatePicker, closeDatePickerWithAnalytics, createDate } from './actions';
10
+ import { deleteDateCommand, insertDateCommand } from './commands';
11
+ import keymap from './pm-plugins/keymap';
12
+ import createDatePlugin from './pm-plugins/main';
13
+ import { pluginKey as datePluginKey } from './pm-plugins/plugin-key';
14
+ const DatePicker = Loadable({
15
+ loader: () => import( /* webpackChunkName: "@atlaskit-internal_editor-datepicker" */'./ui/DatePicker').then(mod => mod.default),
16
+ loading: () => null
17
+ });
18
+ function ContentComponent({
19
+ editorView,
20
+ dispatchAnalyticsEvent,
21
+ popupsMountPoint,
22
+ popupsBoundariesElement,
23
+ popupsScrollableElement,
24
+ dependencyApi,
25
+ weekStartDay
26
+ }) {
27
+ const {
28
+ dispatch
29
+ } = editorView;
30
+ const domAtPos = editorView.domAtPos.bind(editorView);
31
+ const {
32
+ editorDisabledState,
33
+ dateState
34
+ } = useSharedPluginState(dependencyApi, ['date', 'editorDisabled']);
35
+ if (!(dateState !== null && dateState !== void 0 && dateState.showDatePickerAt) || editorDisabledState !== null && editorDisabledState !== void 0 && editorDisabledState.editorDisabled) {
36
+ return null;
37
+ }
38
+ const {
39
+ showDatePickerAt,
40
+ isNew,
41
+ focusDateInput
42
+ } = dateState;
43
+ const element = findDomRefAtPos(showDatePickerAt, domAtPos);
44
+ return /*#__PURE__*/React.createElement(DatePicker, {
45
+ mountTo: popupsMountPoint,
46
+ boundariesElement: popupsBoundariesElement,
47
+ scrollableElement: popupsScrollableElement,
48
+ key: showDatePickerAt,
49
+ element: element,
50
+ isNew: isNew,
51
+ autoFocus: focusDateInput,
52
+ onDelete: () => {
53
+ dependencyApi === null || dependencyApi === void 0 ? void 0 : dependencyApi.core.actions.execute(deleteDateCommand(dependencyApi));
54
+ editorView.focus();
55
+ },
56
+ onSelect: (date, commitMethod) => {
57
+ // Undefined means couldn't parse date, null means invalid (out of bounds) date
58
+ if (date === undefined || date === null) {
59
+ return;
60
+ }
61
+ dependencyApi === null || dependencyApi === void 0 ? void 0 : dependencyApi.core.actions.execute(insertDateCommand(dependencyApi)({
62
+ date,
63
+ commitMethod
64
+ }));
65
+ editorView.focus();
66
+ },
67
+ onTextChanged: date => {
68
+ dependencyApi === null || dependencyApi === void 0 ? void 0 : dependencyApi.core.actions.execute(insertDateCommand(dependencyApi)({
69
+ date,
70
+ enterPressed: false
71
+ }));
72
+ },
73
+ closeDatePicker: () => {
74
+ closeDatePicker()(editorView.state, dispatch);
75
+ editorView.focus();
76
+ },
77
+ closeDatePickerWithAnalytics: ({
78
+ date
79
+ }) => {
80
+ closeDatePickerWithAnalytics({
81
+ date
82
+ })(editorView.state, dispatch);
83
+ editorView.focus();
84
+ },
85
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
86
+ weekStartDay: weekStartDay
87
+ });
88
+ }
89
+ const datePlugin = ({
90
+ config: options = {},
91
+ api
92
+ }) => ({
93
+ name: 'date',
94
+ getSharedState(editorState) {
95
+ if (!editorState) {
96
+ return {
97
+ showDatePickerAt: null,
98
+ isNew: false,
99
+ focusDateInput: false
100
+ };
101
+ }
102
+ const {
103
+ showDatePickerAt,
104
+ isNew,
105
+ focusDateInput
106
+ } = datePluginKey.getState(editorState) || {};
107
+ return {
108
+ showDatePickerAt,
109
+ isNew: !!isNew,
110
+ focusDateInput: !!focusDateInput
111
+ };
112
+ },
113
+ commands: {
114
+ insertDate: insertDateCommand(api),
115
+ deleteDate: deleteDateCommand(api)
116
+ },
117
+ nodes() {
118
+ return [{
119
+ name: 'date',
120
+ node: date
121
+ }];
122
+ },
123
+ pmPlugins() {
124
+ return [{
125
+ name: 'date',
126
+ plugin: options => {
127
+ DatePicker.preload();
128
+ return createDatePlugin(options);
129
+ }
130
+ }, {
131
+ name: 'dateKeymap',
132
+ plugin: () => {
133
+ DatePicker.preload();
134
+ return keymap();
135
+ }
136
+ }];
137
+ },
138
+ contentComponent({
139
+ editorView,
140
+ dispatchAnalyticsEvent,
141
+ popupsMountPoint,
142
+ popupsBoundariesElement,
143
+ popupsScrollableElement
144
+ }) {
145
+ return /*#__PURE__*/React.createElement(ContentComponent, {
146
+ dependencyApi: api,
147
+ editorView: editorView,
148
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
149
+ popupsMountPoint: popupsMountPoint,
150
+ popupsBoundariesElement: popupsBoundariesElement,
151
+ popupsScrollableElement: popupsScrollableElement,
152
+ weekStartDay: options.weekStartDay
153
+ });
154
+ },
155
+ pluginsOptions: {
156
+ quickInsert: ({
157
+ formatMessage
158
+ }) => [{
159
+ id: 'date',
160
+ title: formatMessage(messages.date),
161
+ description: formatMessage(messages.dateDescription),
162
+ priority: 800,
163
+ keywords: ['calendar', 'day', 'time', 'today', '/'],
164
+ keyshortcut: '//',
165
+ icon: () => /*#__PURE__*/React.createElement(IconDate, null),
166
+ action(insert, state) {
167
+ var _api$analytics, _api$analytics$action, _api$analytics$action2;
168
+ const tr = createDate(true)(insert, state);
169
+ api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : (_api$analytics$action2 = _api$analytics$action.attachAnalyticsEvent) === null || _api$analytics$action2 === void 0 ? void 0 : _api$analytics$action2.call(_api$analytics$action, {
170
+ action: ACTION.INSERTED,
171
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
172
+ actionSubjectId: ACTION_SUBJECT_ID.DATE,
173
+ eventType: EVENT_TYPE.TRACK,
174
+ attributes: {
175
+ inputMethod: INPUT_METHOD.QUICK_INSERT
176
+ }
177
+ })(tr);
178
+ return tr;
179
+ }
180
+ }]
181
+ }
182
+ });
183
+ export default datePlugin;
@@ -0,0 +1,34 @@
1
+ import { bindKeymapWithCommand, enter, keymap, tab } from '@atlaskit/editor-common/keymaps';
2
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
+ import { closeDatePicker, focusDateInput, openDatePicker } from '../actions';
4
+ import { getPluginState } from './main';
5
+ export function keymapPlugin() {
6
+ const list = {};
7
+ bindKeymapWithCommand(enter.common, (state, dispatch) => {
8
+ const datePlugin = getPluginState(state);
9
+ const isDateNode = state.selection instanceof NodeSelection ? state.selection.node.type === state.schema.nodes.date : false;
10
+ if (!isDateNode) {
11
+ return false;
12
+ }
13
+ if (!datePlugin.showDatePickerAt) {
14
+ openDatePicker()(state, dispatch);
15
+ return true;
16
+ }
17
+ closeDatePicker()(state, dispatch);
18
+ return true;
19
+ }, list);
20
+ bindKeymapWithCommand(tab.common, (state, dispatch) => {
21
+ const datePlugin = getPluginState(state);
22
+ const isDateNode = state.selection instanceof NodeSelection ? state.selection.node.type === state.schema.nodes.date : false;
23
+ if (!isDateNode) {
24
+ return false;
25
+ }
26
+ if (datePlugin.showDatePickerAt) {
27
+ focusDateInput()(state, dispatch);
28
+ return true;
29
+ }
30
+ return false;
31
+ }, list);
32
+ return keymap(list);
33
+ }
34
+ export default keymapPlugin;
@@ -0,0 +1,35 @@
1
+ import { getInlineNodeViewProducer } from '@atlaskit/editor-common/react-node-view';
2
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import { pluginFactory } from '@atlaskit/editor-common/utils';
4
+ import { DateNodeView } from '../nodeviews/date';
5
+ import { pluginKey } from './plugin-key';
6
+ import { mapping, onSelectionChanged, reducer } from './utils';
7
+ const {
8
+ createPluginState,
9
+ getPluginState
10
+ } = pluginFactory(pluginKey, reducer, {
11
+ mapping,
12
+ onSelectionChanged
13
+ });
14
+ const createPlugin = pmPluginFactoryParams => {
15
+ const newPluginState = {
16
+ showDatePickerAt: null,
17
+ isNew: false,
18
+ isDateEmpty: false,
19
+ focusDateInput: false
20
+ };
21
+ return new SafePlugin({
22
+ state: createPluginState(pmPluginFactoryParams.dispatch, newPluginState),
23
+ key: pluginKey,
24
+ props: {
25
+ nodeViews: {
26
+ date: getInlineNodeViewProducer({
27
+ pmPluginFactoryParams,
28
+ Component: DateNodeView
29
+ })
30
+ }
31
+ }
32
+ });
33
+ };
34
+ export { getPluginState };
35
+ export default createPlugin;
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export const pluginKey = new PluginKey('datePlugin');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export function reducer(pluginState, meta) {
3
+ // If the same nodeview is clicked twice, calendar should close
4
+ if (meta.showDatePickerAt === pluginState.showDatePickerAt) {
5
+ return {
6
+ ...pluginState,
7
+ showDatePickerAt: null
8
+ };
9
+ }
10
+ const {
11
+ showDatePickerAt,
12
+ isNew
13
+ } = pluginState;
14
+ const {
15
+ showDatePickerAt: showDatePickerAtMeta
16
+ } = meta;
17
+ // If date picker position has changed, it is no longer new
18
+ if (showDatePickerAt && showDatePickerAtMeta && showDatePickerAt !== showDatePickerAtMeta && isNew) {
19
+ return {
20
+ ...pluginState,
21
+ ...meta,
22
+ isNew: false
23
+ };
24
+ }
25
+ return {
26
+ ...pluginState,
27
+ ...meta
28
+ };
29
+ }
30
+ export function mapping(tr, pluginState) {
31
+ if (!pluginState.showDatePickerAt) {
32
+ return pluginState;
33
+ }
34
+ const {
35
+ pos
36
+ } = tr.mapping.mapResult(pluginState.showDatePickerAt);
37
+ return {
38
+ showDatePickerAt: pos,
39
+ isNew: pluginState.isNew,
40
+ isDateEmpty: pluginState.isDateEmpty,
41
+ focusDateInput: pluginState.focusDateInput
42
+ };
43
+ }
44
+ export function onSelectionChanged(tr, pluginState) {
45
+ if (tr.docChanged && isDateNodeSelection(tr.selection)) {
46
+ return {
47
+ ...pluginState,
48
+ isQuickInsertAction: false,
49
+ showDatePickerAt: tr.selection.from
50
+ };
51
+ } else if (!isDateNodeSelection(tr.selection) && !pluginState.isQuickInsertAction) {
52
+ if (pluginState.showDatePickerAt) {
53
+ return {
54
+ showDatePickerAt: null,
55
+ isNew: false,
56
+ isDateEmpty: false,
57
+ focusDateInput: false
58
+ };
59
+ }
60
+ return pluginState;
61
+ }
62
+ return pluginState;
63
+ }
64
+ const isDateNodeSelection = selection => {
65
+ if (selection instanceof NodeSelection) {
66
+ const nodeTypeName = selection.node.type.name;
67
+ return nodeTypeName === 'date';
68
+ }
69
+ return false;
70
+ };