@atlaskit/editor-plugin-expand 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.
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +30 -0
- package/dist/cjs/commands.js +184 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/nodeviews/index.js +494 -0
- package/dist/cjs/plugin.js +101 -0
- package/dist/cjs/pm-plugins/keymap.js +170 -0
- package/dist/cjs/pm-plugins/main.js +85 -0
- package/dist/cjs/pm-plugins/plugin-factory.js +15 -0
- package/dist/cjs/reducer.js +20 -0
- package/dist/cjs/toolbar.js +59 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/ui/ExpandIconButton.js +107 -0
- package/dist/cjs/utils.js +24 -0
- package/dist/es2019/commands.js +161 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/nodeviews/index.js +484 -0
- package/dist/es2019/plugin.js +86 -0
- package/dist/es2019/pm-plugins/keymap.js +197 -0
- package/dist/es2019/pm-plugins/main.js +73 -0
- package/dist/es2019/pm-plugins/plugin-factory.js +9 -0
- package/dist/es2019/reducer.js +11 -0
- package/dist/es2019/toolbar.js +52 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/ExpandIconButton.js +88 -0
- package/dist/es2019/utils.js +1 -0
- package/dist/esm/commands.js +177 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/nodeviews/index.js +486 -0
- package/dist/esm/plugin.js +88 -0
- package/dist/esm/pm-plugins/keymap.js +165 -0
- package/dist/esm/pm-plugins/main.js +77 -0
- package/dist/esm/pm-plugins/plugin-factory.js +9 -0
- package/dist/esm/reducer.js +13 -0
- package/dist/esm/toolbar.js +52 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/ExpandIconButton.js +98 -0
- package/dist/esm/utils.js +1 -0
- package/dist/types/commands.d.ts +13 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/nodeviews/index.d.ts +55 -0
- package/dist/types/plugin.d.ts +24 -0
- package/dist/types/pm-plugins/keymap.d.ts +4 -0
- package/dist/types/pm-plugins/main.d.ts +7 -0
- package/dist/types/pm-plugins/plugin-factory.d.ts +3 -0
- package/dist/types/reducer.d.ts +3 -0
- package/dist/types/toolbar.d.ts +3 -0
- package/dist/types/types.d.ts +31 -0
- package/dist/types/ui/ExpandIconButton.d.ts +43 -0
- package/dist/types/utils.d.ts +1 -0
- package/dist/types-ts4.5/commands.d.ts +13 -0
- package/dist/types-ts4.5/index.d.ts +3 -0
- package/dist/types-ts4.5/nodeviews/index.d.ts +55 -0
- package/dist/types-ts4.5/plugin.d.ts +24 -0
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +3 -0
- package/dist/types-ts4.5/reducer.d.ts +3 -0
- package/dist/types-ts4.5/toolbar.d.ts +3 -0
- package/dist/types-ts4.5/types.d.ts +31 -0
- package/dist/types-ts4.5/ui/ExpandIconButton.d.ts +43 -0
- package/dist/types-ts4.5/utils.d.ts +1 -0
- package/package.json +104 -0
- package/report.api.md +93 -0
- package/tmp/api-report-tmp.d.ts +62 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { backspace, bindKeymapWithCommand, moveDown, moveLeft, moveRight, moveUp, tab } from '@atlaskit/editor-common/keymaps';
|
|
2
|
+
import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
|
|
3
|
+
import { expandClassNames } from '@atlaskit/editor-common/styles';
|
|
4
|
+
import { isPositionNearTableRow } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { isEmptyNode } from '@atlaskit/editor-common/utils';
|
|
6
|
+
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
7
|
+
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
8
|
+
import { deleteExpand, focusTitle } from '../commands';
|
|
9
|
+
import { findExpand } from '../utils';
|
|
10
|
+
const isExpandNode = node => {
|
|
11
|
+
return (node === null || node === void 0 ? void 0 : node.type.name) === 'expand' || (node === null || node === void 0 ? void 0 : node.type.name) === 'nestedExpand';
|
|
12
|
+
};
|
|
13
|
+
const isExpandSelected = selection => selection instanceof NodeSelection && isExpandNode(selection.node);
|
|
14
|
+
export function expandKeymap(api) {
|
|
15
|
+
const list = {};
|
|
16
|
+
bindKeymapWithCommand(moveRight.common, (state, dispatch, editorView) => {
|
|
17
|
+
if (!editorView) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const {
|
|
21
|
+
selection
|
|
22
|
+
} = state;
|
|
23
|
+
const selectionSharedState = (api === null || api === void 0 ? void 0 : api.selection.sharedState.currentState()) || {};
|
|
24
|
+
const {
|
|
25
|
+
selectionRelativeToNode
|
|
26
|
+
} = selectionSharedState;
|
|
27
|
+
if (isExpandSelected(selection) && selectionRelativeToNode === RelativeSelectionPos.Start) {
|
|
28
|
+
return focusTitle(selection.from + 1)(state, dispatch, editorView);
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}, list);
|
|
32
|
+
bindKeymapWithCommand(moveLeft.common, (state, dispatch, editorView) => {
|
|
33
|
+
if (!editorView) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const {
|
|
37
|
+
selection
|
|
38
|
+
} = state;
|
|
39
|
+
const selectionSharedState = (api === null || api === void 0 ? void 0 : api.selection.sharedState.currentState()) || {};
|
|
40
|
+
const {
|
|
41
|
+
selectionRelativeToNode
|
|
42
|
+
} = selectionSharedState;
|
|
43
|
+
if (isExpandSelected(selection) && (selectionRelativeToNode === undefined || selectionRelativeToNode === RelativeSelectionPos.End)) {
|
|
44
|
+
return focusTitle(selection.from + 1)(state, dispatch, editorView);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}, list);
|
|
48
|
+
bindKeymapWithCommand(tab.common, (state, dispatch, editorView) => {
|
|
49
|
+
if (state.selection instanceof NodeSelection && state.selection.node.type === state.schema.nodes.expand && editorView && editorView.dom instanceof HTMLElement) {
|
|
50
|
+
const {
|
|
51
|
+
from
|
|
52
|
+
} = state.selection;
|
|
53
|
+
const expand = editorView.nodeDOM(from);
|
|
54
|
+
if (!expand || !(expand instanceof HTMLElement)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const iconContainer = expand.querySelector(`.${expandClassNames.iconContainer}`);
|
|
58
|
+
if (iconContainer && iconContainer.focus) {
|
|
59
|
+
const {
|
|
60
|
+
tr
|
|
61
|
+
} = state;
|
|
62
|
+
const pos = state.selection.from;
|
|
63
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(pos)));
|
|
64
|
+
if (dispatch) {
|
|
65
|
+
dispatch(tr);
|
|
66
|
+
}
|
|
67
|
+
editorView.dom.blur();
|
|
68
|
+
iconContainer.focus();
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}, list);
|
|
74
|
+
bindKeymapWithCommand(moveUp.common, (state, dispatch, editorView) => {
|
|
75
|
+
if (!editorView) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const {
|
|
79
|
+
selection,
|
|
80
|
+
schema
|
|
81
|
+
} = state;
|
|
82
|
+
const {
|
|
83
|
+
nodeBefore
|
|
84
|
+
} = selection.$from;
|
|
85
|
+
if (selection instanceof GapCursorSelection && selection.side === Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand) && !nodeBefore.attrs.__expanded) {
|
|
86
|
+
const {
|
|
87
|
+
$from
|
|
88
|
+
} = selection;
|
|
89
|
+
return focusTitle(Math.max($from.pos - 1, 0))(state, dispatch, editorView);
|
|
90
|
+
}
|
|
91
|
+
const {
|
|
92
|
+
$from
|
|
93
|
+
} = state.selection;
|
|
94
|
+
if (editorView.endOfTextblock('up')) {
|
|
95
|
+
const expand = findExpand(state);
|
|
96
|
+
|
|
97
|
+
// Moving UP in a table should move the cursor to the row above
|
|
98
|
+
// however when an expand is in a table cell to the left of the
|
|
99
|
+
// current table cell, arrow UP moves the cursor to the left
|
|
100
|
+
// see ED-15425
|
|
101
|
+
if (isPositionNearTableRow($from, schema, 'before') && !expand) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const prevCursorPos = Math.max($from.pos - $from.parentOffset - 1, 0);
|
|
105
|
+
// move cursor from expand's content to its title
|
|
106
|
+
if (expand && expand.start === prevCursorPos) {
|
|
107
|
+
return focusTitle(expand.start)(state, dispatch, editorView);
|
|
108
|
+
}
|
|
109
|
+
const sel = Selection.findFrom(state.doc.resolve(prevCursorPos), -1);
|
|
110
|
+
const expandBefore = findExpand(state, sel);
|
|
111
|
+
if (sel && expandBefore) {
|
|
112
|
+
// moving cursor from outside of an expand to the title when it is collapsed
|
|
113
|
+
if (!expandBefore.node.attrs.__expanded) {
|
|
114
|
+
return focusTitle(expandBefore.start)(state, dispatch, editorView);
|
|
115
|
+
}
|
|
116
|
+
// moving cursor from outside of an expand to the content when it is expanded
|
|
117
|
+
else if (dispatch) {
|
|
118
|
+
dispatch(state.tr.setSelection(sel));
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}, list);
|
|
125
|
+
bindKeymapWithCommand(moveDown.common, (state, dispatch, editorView) => {
|
|
126
|
+
if (!editorView) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
const {
|
|
130
|
+
expand,
|
|
131
|
+
nestedExpand
|
|
132
|
+
} = state.schema.nodes;
|
|
133
|
+
const {
|
|
134
|
+
selection
|
|
135
|
+
} = state;
|
|
136
|
+
const {
|
|
137
|
+
nodeAfter
|
|
138
|
+
} = selection.$from;
|
|
139
|
+
if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand) && !nodeAfter.attrs.__expanded) {
|
|
140
|
+
const {
|
|
141
|
+
$from
|
|
142
|
+
} = selection;
|
|
143
|
+
return focusTitle($from.pos + 1)(state, dispatch, editorView);
|
|
144
|
+
}
|
|
145
|
+
if (editorView.endOfTextblock('down')) {
|
|
146
|
+
const {
|
|
147
|
+
$from
|
|
148
|
+
} = state.selection;
|
|
149
|
+
if ($from.depth === 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const $after = state.doc.resolve($from.after());
|
|
153
|
+
if ($after.nodeAfter && ($after.nodeAfter.type === expand || $after.nodeAfter.type === nestedExpand)) {
|
|
154
|
+
return focusTitle($after.pos + 1)(state, dispatch, editorView);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}, list);
|
|
159
|
+
bindKeymapWithCommand(backspace.common, (state, dispatch, editorView) => {
|
|
160
|
+
const {
|
|
161
|
+
selection
|
|
162
|
+
} = state;
|
|
163
|
+
const {
|
|
164
|
+
$from
|
|
165
|
+
} = selection;
|
|
166
|
+
if (!editorView || !selection.empty) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
const {
|
|
170
|
+
expand,
|
|
171
|
+
nestedExpand
|
|
172
|
+
} = state.schema.nodes;
|
|
173
|
+
const expandNode = findExpand(state);
|
|
174
|
+
if (!expandNode) {
|
|
175
|
+
// @see ED-7977
|
|
176
|
+
const sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
|
|
177
|
+
const expandBefore = findExpand(state, sel);
|
|
178
|
+
if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand) && !expandBefore.node.attrs.__expanded) {
|
|
179
|
+
return focusTitle(expandBefore.start)(state, dispatch, editorView);
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
const parentNode = state.doc.nodeAt($from.before(Math.max($from.depth - 1, 1)));
|
|
184
|
+
// ED-10012 catch cases where the expand has another node nested within it and
|
|
185
|
+
// the backspace should be applied only to the inner node instead of the expand
|
|
186
|
+
if (parentNode && !isExpandNode(parentNode)) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
const textSel = Selection.findFrom(state.doc.resolve(expandNode.pos), 1, true);
|
|
190
|
+
if (textSel && selection.$from.pos === textSel.$from.pos && isEmptyNode(state.schema)(expandNode.node) && dispatch) {
|
|
191
|
+
var _api$analytics;
|
|
192
|
+
return deleteExpand(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)(state, dispatch);
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}, list);
|
|
196
|
+
return keymap(list);
|
|
197
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
|
|
3
|
+
import { expandClassNames } from '@atlaskit/editor-common/styles';
|
|
4
|
+
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
5
|
+
import { setExpandRef } from '../commands';
|
|
6
|
+
import ExpandNodeView from '../nodeviews';
|
|
7
|
+
import { findExpand } from '../utils';
|
|
8
|
+
import { createPluginState, getPluginState, pluginKey } from './plugin-factory';
|
|
9
|
+
export function containsClass(element, className) {
|
|
10
|
+
var _element$classList;
|
|
11
|
+
return Boolean(element === null || element === void 0 ? void 0 : (_element$classList = element.classList) === null || _element$classList === void 0 ? void 0 : _element$classList.contains(className));
|
|
12
|
+
}
|
|
13
|
+
export const createPlugin = (dispatch, getIntl, appearance = 'full-page', useLongPressSelection = false, featureFlags, api) => {
|
|
14
|
+
const state = createPluginState(dispatch, {});
|
|
15
|
+
const isMobile = appearance === 'mobile';
|
|
16
|
+
return new SafePlugin({
|
|
17
|
+
state: state,
|
|
18
|
+
key: pluginKey,
|
|
19
|
+
props: {
|
|
20
|
+
nodeViews: {
|
|
21
|
+
expand: ExpandNodeView({
|
|
22
|
+
getIntl,
|
|
23
|
+
isMobile,
|
|
24
|
+
featureFlags,
|
|
25
|
+
api
|
|
26
|
+
}),
|
|
27
|
+
nestedExpand: ExpandNodeView({
|
|
28
|
+
getIntl,
|
|
29
|
+
isMobile,
|
|
30
|
+
featureFlags,
|
|
31
|
+
api
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
handleKeyDown(_view, event) {
|
|
35
|
+
return containsClass(event.target, expandClassNames.titleContainer);
|
|
36
|
+
},
|
|
37
|
+
handleKeyPress(_view, event) {
|
|
38
|
+
return containsClass(event.target, expandClassNames.titleContainer);
|
|
39
|
+
},
|
|
40
|
+
handleScrollToSelection() {
|
|
41
|
+
return containsClass(document.activeElement, expandClassNames.titleInput);
|
|
42
|
+
},
|
|
43
|
+
handleClickOn: createSelectionClickHandler(['expand', 'nestedExpand'], target => target.classList.contains(expandClassNames.prefix), {
|
|
44
|
+
useLongPressSelection
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
// @see ED-8027 to follow up on this work-around
|
|
48
|
+
filterTransaction(tr) {
|
|
49
|
+
if (containsClass(document.activeElement, expandClassNames.titleInput) && tr.selectionSet && (!tr.steps.length || tr.isGeneric)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
view: editorView => {
|
|
55
|
+
const domAtPos = editorView.domAtPos.bind(editorView);
|
|
56
|
+
return {
|
|
57
|
+
update: view => {
|
|
58
|
+
const {
|
|
59
|
+
state,
|
|
60
|
+
dispatch
|
|
61
|
+
} = view;
|
|
62
|
+
const node = findExpand(state);
|
|
63
|
+
if (node) {
|
|
64
|
+
const expandRef = findDomRefAtPos(node.pos, domAtPos);
|
|
65
|
+
if (getPluginState(state).expandRef !== expandRef) {
|
|
66
|
+
setExpandRef(expandRef)(state, dispatch);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { pluginFactory } from '@atlaskit/editor-common/utils';
|
|
2
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import reducer from '../reducer';
|
|
4
|
+
export const pluginKey = new PluginKey('expandPlugin');
|
|
5
|
+
export const {
|
|
6
|
+
createPluginState,
|
|
7
|
+
createCommand,
|
|
8
|
+
getPluginState
|
|
9
|
+
} = pluginFactory(pluginKey, reducer);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import commonMessages from '@atlaskit/editor-common/messages';
|
|
2
|
+
import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
|
|
3
|
+
import { deleteExpand } from './commands';
|
|
4
|
+
import { getPluginState } from './pm-plugins/plugin-factory';
|
|
5
|
+
export const getToolbarConfig = api => (state, {
|
|
6
|
+
formatMessage
|
|
7
|
+
}) => {
|
|
8
|
+
var _api$decorations$acti, _api$decorations, _api$analytics;
|
|
9
|
+
const {
|
|
10
|
+
hoverDecoration
|
|
11
|
+
} = (_api$decorations$acti = api === null || api === void 0 ? void 0 : (_api$decorations = api.decorations) === null || _api$decorations === void 0 ? void 0 : _api$decorations.actions) !== null && _api$decorations$acti !== void 0 ? _api$decorations$acti : {};
|
|
12
|
+
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
13
|
+
const {
|
|
14
|
+
expandRef
|
|
15
|
+
} = getPluginState(state);
|
|
16
|
+
if (expandRef) {
|
|
17
|
+
const {
|
|
18
|
+
nestedExpand,
|
|
19
|
+
expand
|
|
20
|
+
} = state.schema.nodes;
|
|
21
|
+
return {
|
|
22
|
+
title: 'Expand toolbar',
|
|
23
|
+
getDomRef: () => expandRef,
|
|
24
|
+
nodeType: [nestedExpand, expand],
|
|
25
|
+
offset: [0, 6],
|
|
26
|
+
items: [{
|
|
27
|
+
type: 'copy-button',
|
|
28
|
+
items: [{
|
|
29
|
+
state,
|
|
30
|
+
formatMessage,
|
|
31
|
+
nodeType: [nestedExpand, expand]
|
|
32
|
+
}, {
|
|
33
|
+
type: 'separator'
|
|
34
|
+
}]
|
|
35
|
+
}, {
|
|
36
|
+
id: 'editor.expand.delete',
|
|
37
|
+
type: 'button',
|
|
38
|
+
appearance: 'danger',
|
|
39
|
+
focusEditoronEnter: true,
|
|
40
|
+
icon: RemoveIcon,
|
|
41
|
+
onClick: deleteExpand(editorAnalyticsAPI),
|
|
42
|
+
onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], true),
|
|
43
|
+
onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], false),
|
|
44
|
+
onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], true),
|
|
45
|
+
onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], false),
|
|
46
|
+
title: formatMessage(commonMessages.remove),
|
|
47
|
+
tabIndex: null
|
|
48
|
+
}]
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import React, { useCallback } from 'react';
|
|
4
|
+
import { jsx } from '@emotion/react';
|
|
5
|
+
import Button from '@atlaskit/button/custom-theme-button';
|
|
6
|
+
import { expandClassNames } from '@atlaskit/editor-common/styles';
|
|
7
|
+
import { expandLayoutWrapperStyle, ExpandLayoutWrapperWithRef, expandMessages } from '@atlaskit/editor-common/ui';
|
|
8
|
+
import { akEditorSwoopCubicBezier } from '@atlaskit/editor-shared-styles';
|
|
9
|
+
import ChevronRightIcon from '@atlaskit/icon/glyph/chevron-right';
|
|
10
|
+
import Tooltip from '@atlaskit/tooltip';
|
|
11
|
+
export const withTooltip = WrapperComponent => {
|
|
12
|
+
return class WithSortableColumn extends React.Component {
|
|
13
|
+
constructor(props) {
|
|
14
|
+
super(props);
|
|
15
|
+
}
|
|
16
|
+
render() {
|
|
17
|
+
const {
|
|
18
|
+
label
|
|
19
|
+
} = this.props;
|
|
20
|
+
return jsx(Tooltip, {
|
|
21
|
+
content: label,
|
|
22
|
+
position: "top",
|
|
23
|
+
tag: ExpandLayoutWrapperWithRef
|
|
24
|
+
}, jsx(WrapperComponent, this.props));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export const CustomButton = props => {
|
|
29
|
+
const {
|
|
30
|
+
label,
|
|
31
|
+
allowInteractiveExpand
|
|
32
|
+
} = props;
|
|
33
|
+
const useTheme = useCallback((currentTheme, themeProps) => {
|
|
34
|
+
const {
|
|
35
|
+
buttonStyles,
|
|
36
|
+
...rest
|
|
37
|
+
} = currentTheme(themeProps);
|
|
38
|
+
return {
|
|
39
|
+
buttonStyles: {
|
|
40
|
+
...buttonStyles,
|
|
41
|
+
height: '100%',
|
|
42
|
+
'& svg': {
|
|
43
|
+
transform: props.expanded ? 'transform: rotate(90deg);' : 'transform: rotate(0deg);',
|
|
44
|
+
transition: `transform 0.2s ${akEditorSwoopCubicBezier};`
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
...rest
|
|
48
|
+
};
|
|
49
|
+
}, [props]);
|
|
50
|
+
return jsx(Button, {
|
|
51
|
+
appearance: "subtle",
|
|
52
|
+
className: expandClassNames.iconContainer,
|
|
53
|
+
iconBefore: jsx(ChevronRightIcon, {
|
|
54
|
+
label: label
|
|
55
|
+
}),
|
|
56
|
+
shouldFitContainer: true,
|
|
57
|
+
theme: useTheme,
|
|
58
|
+
isDisabled: !allowInteractiveExpand
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const ButtonWithTooltip = withTooltip(CustomButton);
|
|
62
|
+
const ButtonWithoutTooltip = CustomButton;
|
|
63
|
+
export const ExpandIconButton = props => {
|
|
64
|
+
const {
|
|
65
|
+
expanded,
|
|
66
|
+
intl
|
|
67
|
+
} = props;
|
|
68
|
+
const message = expanded ? expandMessages.collapseNode : expandMessages.expandNode;
|
|
69
|
+
const label = intl && intl.formatMessage(message) || message.defaultMessage;
|
|
70
|
+
// check to ensure device supports any-hover
|
|
71
|
+
const supportsAnyHover = !!window.matchMedia ? window.matchMedia('(any-hover: hover)').matches !== window.matchMedia('(any-hover: none)').matches : false;
|
|
72
|
+
const hoverEventCheck = supportsAnyHover ? window.matchMedia('(any-hover: hover)').matches : true;
|
|
73
|
+
|
|
74
|
+
// hoverEventCheck is to disable tooltips for mobile to prevent incorrect hover state causing issues on iOS
|
|
75
|
+
if (props.allowInteractiveExpand && hoverEventCheck) {
|
|
76
|
+
return jsx(ButtonWithTooltip, _extends({
|
|
77
|
+
label: label
|
|
78
|
+
}, props));
|
|
79
|
+
}
|
|
80
|
+
return (
|
|
81
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
82
|
+
jsx("div", {
|
|
83
|
+
css: expandLayoutWrapperStyle
|
|
84
|
+
}, jsx(ButtonWithoutTooltip, _extends({
|
|
85
|
+
label: label
|
|
86
|
+
}, props)))
|
|
87
|
+
);
|
|
88
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { findExpand, transformSliceToRemoveOpenExpand, transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
|
|
5
|
+
import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
6
|
+
import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
|
|
7
|
+
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
8
|
+
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
9
|
+
import { findTable } from '@atlaskit/editor-tables/utils';
|
|
10
|
+
import { createCommand } from './pm-plugins/plugin-factory';
|
|
11
|
+
import { findExpand } from './utils';
|
|
12
|
+
export var setExpandRef = function setExpandRef(ref) {
|
|
13
|
+
return createCommand({
|
|
14
|
+
type: 'SET_EXPAND_REF',
|
|
15
|
+
data: {
|
|
16
|
+
ref: ref
|
|
17
|
+
}
|
|
18
|
+
}, function (tr) {
|
|
19
|
+
return tr.setMeta('addToHistory', false);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export var deleteExpandAtPos = function deleteExpandAtPos(editorAnalyticsAPI) {
|
|
23
|
+
return function (expandNodePos, expandNode) {
|
|
24
|
+
return function (state, dispatch) {
|
|
25
|
+
if (!expandNode || isNaN(expandNodePos)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
var payload = {
|
|
29
|
+
action: ACTION.DELETED,
|
|
30
|
+
actionSubject: expandNode.type === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
|
|
31
|
+
attributes: {
|
|
32
|
+
inputMethod: INPUT_METHOD.TOOLBAR
|
|
33
|
+
},
|
|
34
|
+
eventType: EVENT_TYPE.TRACK
|
|
35
|
+
};
|
|
36
|
+
if (expandNode && dispatch) {
|
|
37
|
+
var tr = state.tr;
|
|
38
|
+
tr.delete(expandNodePos, expandNodePos + expandNode.nodeSize);
|
|
39
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
|
|
40
|
+
dispatch(tr);
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export var deleteExpand = function deleteExpand(editorAnalyticsAPI) {
|
|
47
|
+
return function (state, dispatch) {
|
|
48
|
+
var expandNode = findExpand(state);
|
|
49
|
+
if (!expandNode) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return deleteExpandAtPos(editorAnalyticsAPI)(expandNode.pos, expandNode.node)(state, dispatch);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export var updateExpandTitle = function updateExpandTitle(title, pos, nodeType) {
|
|
56
|
+
return function (state, dispatch) {
|
|
57
|
+
var node = state.doc.nodeAt(pos);
|
|
58
|
+
if (node && node.type === nodeType && dispatch) {
|
|
59
|
+
var tr = state.tr;
|
|
60
|
+
tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
|
|
61
|
+
title: title
|
|
62
|
+
}), node.marks);
|
|
63
|
+
dispatch(tr);
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
export var toggleExpandExpanded = function toggleExpandExpanded(editorAnalyticsAPI) {
|
|
69
|
+
return function (pos, nodeType) {
|
|
70
|
+
return function (state, dispatch) {
|
|
71
|
+
var node = state.doc.nodeAt(pos);
|
|
72
|
+
if (node && node.type === nodeType && dispatch) {
|
|
73
|
+
var tr = state.tr;
|
|
74
|
+
var isExpandedNext = !node.attrs.__expanded;
|
|
75
|
+
tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
|
|
76
|
+
__expanded: isExpandedNext
|
|
77
|
+
}), node.marks);
|
|
78
|
+
|
|
79
|
+
// If we're going to collapse the expand and our cursor is currently inside
|
|
80
|
+
// Move to a right gap cursor, if the toolbar is interacted (or an API),
|
|
81
|
+
// it will insert below rather than inside (which will be invisible).
|
|
82
|
+
if (isExpandedNext === false && findExpand(state)) {
|
|
83
|
+
tr.setSelection(new GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), Side.RIGHT));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// log when people open/close expands
|
|
87
|
+
// TODO: ED-8523 make platform/mode global attributes?
|
|
88
|
+
var payload = {
|
|
89
|
+
action: ACTION.TOGGLE_EXPAND,
|
|
90
|
+
actionSubject: nodeType === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
|
|
91
|
+
attributes: {
|
|
92
|
+
platform: PLATFORMS.WEB,
|
|
93
|
+
mode: MODE.EDITOR,
|
|
94
|
+
expanded: isExpandedNext
|
|
95
|
+
},
|
|
96
|
+
eventType: EVENT_TYPE.TRACK
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// `isRemote` meta prevents this step from being
|
|
100
|
+
// sync'd between sessions in collab edit
|
|
101
|
+
tr.setMeta('isRemote', true);
|
|
102
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
|
|
103
|
+
dispatch(tr);
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Creates either an expand or a nestedExpand node based on the current selection
|
|
111
|
+
export var createExpandNode = function createExpandNode(state) {
|
|
112
|
+
var _state$schema$nodes = state.schema.nodes,
|
|
113
|
+
expand = _state$schema$nodes.expand,
|
|
114
|
+
nestedExpand = _state$schema$nodes.nestedExpand;
|
|
115
|
+
var expandType = findTable(state.selection) ? nestedExpand : expand;
|
|
116
|
+
return expandType.createAndFill({});
|
|
117
|
+
};
|
|
118
|
+
export var insertExpand = function insertExpand(editorAnalyticsAPI) {
|
|
119
|
+
return function (state, dispatch) {
|
|
120
|
+
var expandNode = createExpandNode(state);
|
|
121
|
+
if (!expandNode) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
var tr = state.selection.empty ? safeInsert(expandNode)(state.tr).scrollIntoView() : createWrapSelectionTransaction({
|
|
125
|
+
state: state,
|
|
126
|
+
type: expandNode.type
|
|
127
|
+
});
|
|
128
|
+
var payload = {
|
|
129
|
+
action: ACTION.INSERTED,
|
|
130
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
131
|
+
actionSubjectId: (expandNode === null || expandNode === void 0 ? void 0 : expandNode.type) === state.schema.nodes.expand ? ACTION_SUBJECT_ID.EXPAND : ACTION_SUBJECT_ID.NESTED_EXPAND,
|
|
132
|
+
attributes: {
|
|
133
|
+
inputMethod: INPUT_METHOD.INSERT_MENU
|
|
134
|
+
},
|
|
135
|
+
eventType: EVENT_TYPE.TRACK
|
|
136
|
+
};
|
|
137
|
+
if (dispatch && expandNode) {
|
|
138
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
|
|
139
|
+
dispatch(tr);
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
export var focusTitle = function focusTitle(pos) {
|
|
145
|
+
return function (state, dispatch, editorView) {
|
|
146
|
+
if (editorView) {
|
|
147
|
+
var dom = editorView.domAtPos(pos);
|
|
148
|
+
var expandWrapper = dom.node.parentElement;
|
|
149
|
+
if (expandWrapper) {
|
|
150
|
+
setSelectionInsideExpand(pos)(state, dispatch, editorView);
|
|
151
|
+
var input = expandWrapper.querySelector('input');
|
|
152
|
+
if (input) {
|
|
153
|
+
input.focus();
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// Used to clear any node or cell selection when expand title is focused
|
|
163
|
+
export var setSelectionInsideExpand = function setSelectionInsideExpand(expandPos) {
|
|
164
|
+
return function (state, dispatch, editorView) {
|
|
165
|
+
if (editorView) {
|
|
166
|
+
if (!editorView.hasFocus()) {
|
|
167
|
+
editorView.focus();
|
|
168
|
+
}
|
|
169
|
+
var sel = Selection.findFrom(editorView.state.doc.resolve(expandPos), 1, true);
|
|
170
|
+
if (sel && dispatch) {
|
|
171
|
+
dispatch(editorView.state.tr.setSelection(sel));
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { expandPlugin } from './plugin';
|