@atlaskit/editor-core 187.34.2 → 187.35.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 +11 -0
- package/dist/cjs/index.js +10 -42
- package/dist/cjs/plugins/block-type/commands/block-type.js +19 -211
- package/dist/cjs/plugins/block-type/commands/index.js +2 -28
- package/dist/cjs/plugins/block-type/index.js +21 -4
- package/dist/cjs/plugins/block-type/pm-plugins/input-rule.js +9 -64
- package/dist/cjs/plugins/block-type/pm-plugins/keymap.js +1 -1
- package/dist/cjs/plugins/code-block/actions.js +83 -6
- package/dist/cjs/plugins/code-block/index.js +27 -12
- package/dist/cjs/plugins/code-block/pm-plugins/input-rule.js +68 -0
- package/dist/cjs/plugins/date/ui/DatePicker/index.js +3 -2
- package/dist/cjs/plugins/expand/commands.js +3 -3
- package/dist/cjs/plugins/expand/index.js +2 -2
- package/dist/cjs/plugins/index.js +1 -7
- package/dist/cjs/plugins/insert-block/index.js +34 -29
- package/dist/cjs/plugins/panel/actions.js +26 -2
- package/dist/cjs/plugins/panel/index.js +9 -5
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/index.js +16 -2
- package/dist/es2019/plugins/block-type/commands/block-type.js +15 -217
- package/dist/es2019/plugins/block-type/commands/index.js +1 -3
- package/dist/es2019/plugins/block-type/index.js +21 -4
- package/dist/es2019/plugins/block-type/pm-plugins/input-rule.js +3 -56
- package/dist/es2019/plugins/block-type/pm-plugins/keymap.js +2 -2
- package/dist/es2019/plugins/code-block/actions.js +84 -3
- package/dist/es2019/plugins/code-block/index.js +22 -7
- package/dist/es2019/plugins/code-block/pm-plugins/input-rule.js +60 -0
- package/dist/es2019/plugins/date/ui/DatePicker/index.js +3 -2
- package/dist/es2019/plugins/expand/commands.js +1 -1
- package/dist/es2019/plugins/expand/index.js +1 -1
- package/dist/es2019/plugins/index.js +0 -1
- package/dist/es2019/plugins/insert-block/index.js +47 -42
- package/dist/es2019/plugins/panel/actions.js +26 -2
- package/dist/es2019/plugins/panel/index.js +8 -4
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/index.js +16 -2
- package/dist/esm/plugins/block-type/commands/block-type.js +17 -205
- package/dist/esm/plugins/block-type/commands/index.js +1 -3
- package/dist/esm/plugins/block-type/index.js +21 -4
- package/dist/esm/plugins/block-type/pm-plugins/input-rule.js +3 -58
- package/dist/esm/plugins/block-type/pm-plugins/keymap.js +2 -2
- package/dist/esm/plugins/code-block/actions.js +76 -3
- package/dist/esm/plugins/code-block/index.js +25 -11
- package/dist/esm/plugins/code-block/pm-plugins/input-rule.js +62 -0
- package/dist/esm/plugins/date/ui/DatePicker/index.js +3 -2
- package/dist/esm/plugins/expand/commands.js +1 -1
- package/dist/esm/plugins/expand/index.js +1 -1
- package/dist/esm/plugins/index.js +0 -1
- package/dist/esm/plugins/insert-block/index.js +27 -22
- package/dist/esm/plugins/panel/actions.js +24 -2
- package/dist/esm/plugins/panel/index.js +8 -4
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/index.d.ts +16 -3
- package/dist/types/labs/next/presets/default.d.ts +6 -0
- package/dist/types/plugins/block-type/commands/block-type.d.ts +1 -25
- package/dist/types/plugins/block-type/commands/index.d.ts +1 -3
- package/dist/types/plugins/block-type/index.d.ts +10 -2
- package/dist/types/plugins/code-block/actions.d.ts +11 -0
- package/dist/types/plugins/code-block/index.d.ts +6 -1
- package/dist/types/plugins/code-block/pm-plugins/input-rule.d.ts +3 -0
- package/dist/types/plugins/date/ui/DatePicker/index.d.ts +2 -2
- package/dist/types/plugins/index.d.ts +0 -2
- package/dist/types/plugins/insert-block/types.d.ts +7 -1
- package/dist/types/plugins/panel/actions.d.ts +4 -1
- package/dist/types/plugins/panel/index.d.ts +11 -2
- package/dist/types-ts4.5/index.d.ts +16 -3
- package/dist/types-ts4.5/labs/next/presets/default.d.ts +6 -0
- package/dist/types-ts4.5/plugins/block-type/commands/block-type.d.ts +1 -25
- package/dist/types-ts4.5/plugins/block-type/commands/index.d.ts +1 -3
- package/dist/types-ts4.5/plugins/block-type/index.d.ts +10 -2
- package/dist/types-ts4.5/plugins/code-block/actions.d.ts +11 -0
- package/dist/types-ts4.5/plugins/code-block/index.d.ts +6 -1
- package/dist/types-ts4.5/plugins/code-block/pm-plugins/input-rule.d.ts +3 -0
- package/dist/types-ts4.5/plugins/date/ui/DatePicker/index.d.ts +2 -2
- package/dist/types-ts4.5/plugins/index.d.ts +0 -2
- package/dist/types-ts4.5/plugins/insert-block/types.d.ts +7 -1
- package/dist/types-ts4.5/plugins/panel/actions.d.ts +4 -1
- package/dist/types-ts4.5/plugins/panel/index.d.ts +9 -2
- package/package.json +3 -3
- package/report.api.md +62 -23
- package/tmp/api-report-tmp.d.ts +49 -15
- package/dist/cjs/plugins/block-type/commands/insert-block.js +0 -60
- package/dist/es2019/plugins/block-type/commands/insert-block.js +0 -55
- package/dist/esm/plugins/block-type/commands/insert-block.js +0 -53
- package/dist/types/plugins/block-type/commands/insert-block.d.ts +0 -5
- package/dist/types-ts4.5/plugins/block-type/commands/insert-block.d.ts +0 -5
- /package/dist/cjs/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
- /package/dist/es2019/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
- /package/dist/esm/plugins/{block-type/commands → code-block}/transform-to-code-block.js +0 -0
- /package/dist/types/plugins/{block-type/commands → code-block}/transform-to-code-block.d.ts +0 -0
- /package/dist/types-ts4.5/plugins/{block-type/commands → code-block}/transform-to-code-block.d.ts +0 -0
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
-
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
-
import { PanelType } from '@atlaskit/adf-schema';
|
|
4
1
|
import { CellSelection } from '@atlaskit/editor-tables';
|
|
5
|
-
import { shouldSplitSelectedNodeOnNodeInsertion } from '@atlaskit/editor-common/insert';
|
|
6
2
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
7
3
|
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
|
8
|
-
import { filterChildrenBetween,
|
|
9
|
-
import {
|
|
10
|
-
import { transformToCodeBlockAction } from './transform-to-code-block';
|
|
4
|
+
import { filterChildrenBetween, wrapSelectionIn } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { HEADINGS_BY_NAME, NORMAL_TEXT } from '../types';
|
|
11
6
|
export function setBlockType(name) {
|
|
12
7
|
return (state, dispatch) => {
|
|
13
8
|
const {
|
|
@@ -132,27 +127,13 @@ export const setHeadingWithAnalytics = (newHeadingLevel, inputMethod, editorAnal
|
|
|
132
127
|
}
|
|
133
128
|
})(setHeading(newHeadingLevel)));
|
|
134
129
|
};
|
|
135
|
-
|
|
130
|
+
function insertBlockQuote() {
|
|
136
131
|
return function (state, dispatch) {
|
|
137
132
|
const {
|
|
138
133
|
nodes
|
|
139
134
|
} = state.schema;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (nodes.paragraph && nodes.blockquote) {
|
|
143
|
-
return wrapSelectionIn(nodes.blockquote)(state, dispatch);
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
case CODE_BLOCK.name:
|
|
147
|
-
if (nodes.codeBlock) {
|
|
148
|
-
return insertCodeBlock()(state, dispatch);
|
|
149
|
-
}
|
|
150
|
-
break;
|
|
151
|
-
case PANEL.name:
|
|
152
|
-
if (nodes.panel && nodes.paragraph) {
|
|
153
|
-
return wrapSelectionIn(nodes.panel)(state, dispatch);
|
|
154
|
-
}
|
|
155
|
-
break;
|
|
135
|
+
if (nodes.paragraph && nodes.blockquote) {
|
|
136
|
+
return wrapSelectionIn(nodes.blockquote)(state, dispatch);
|
|
156
137
|
}
|
|
157
138
|
return false;
|
|
158
139
|
};
|
|
@@ -166,200 +147,17 @@ export function insertBlockType(name) {
|
|
|
166
147
|
* otherwise Editor becomes very sad and crashes
|
|
167
148
|
* @returns - command that inserts block type
|
|
168
149
|
*/
|
|
169
|
-
export const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
attributes: {
|
|
178
|
-
inputMethod
|
|
179
|
-
}
|
|
180
|
-
})(insertBlockType(name));
|
|
181
|
-
case CODE_BLOCK.name:
|
|
182
|
-
return withAnalytics(editorAnalyticsApi, {
|
|
183
|
-
action: ACTION.INSERTED,
|
|
184
|
-
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
185
|
-
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
186
|
-
attributes: {
|
|
187
|
-
inputMethod: inputMethod
|
|
188
|
-
},
|
|
189
|
-
eventType: EVENT_TYPE.TRACK
|
|
190
|
-
})(insertBlockType(name));
|
|
191
|
-
case PANEL.name:
|
|
192
|
-
return withAnalytics(editorAnalyticsApi, {
|
|
193
|
-
action: ACTION.INSERTED,
|
|
194
|
-
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
195
|
-
actionSubjectId: ACTION_SUBJECT_ID.PANEL,
|
|
196
|
-
attributes: {
|
|
197
|
-
inputMethod: inputMethod,
|
|
198
|
-
panelType: PanelType.INFO // only info panels can be inserted from toolbar
|
|
199
|
-
},
|
|
200
|
-
|
|
201
|
-
eventType: EVENT_TYPE.TRACK
|
|
202
|
-
})(insertBlockType(name));
|
|
203
|
-
default:
|
|
204
|
-
return insertBlockType(name);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* This function creates a new transaction that wraps the current selection
|
|
210
|
-
* in the specified node type if it results in a valid transaction.
|
|
211
|
-
* If not valid, it performs a safe insert operation.
|
|
212
|
-
*
|
|
213
|
-
* Example of when wrapping might not be valid is when attempting to wrap
|
|
214
|
-
* content that is already inside a panel with another panel
|
|
215
|
-
*/
|
|
216
|
-
export function createWrapSelectionTransaction({
|
|
217
|
-
state,
|
|
218
|
-
type,
|
|
219
|
-
nodeAttributes
|
|
220
|
-
}) {
|
|
221
|
-
let {
|
|
222
|
-
tr
|
|
223
|
-
} = state;
|
|
224
|
-
const {
|
|
225
|
-
alignment,
|
|
226
|
-
indentation
|
|
227
|
-
} = state.schema.marks;
|
|
228
|
-
|
|
229
|
-
/** Alignment or Indentation is not valid inside block types */
|
|
230
|
-
const removeAlignTr = removeBlockMarks(state, [alignment, indentation]);
|
|
231
|
-
tr = removeAlignTr || tr;
|
|
232
|
-
|
|
233
|
-
/**Get range and wrapping needed for the selection*/
|
|
234
|
-
const {
|
|
235
|
-
range,
|
|
236
|
-
wrapping
|
|
237
|
-
} = getWrappingOptions(state, type, nodeAttributes);
|
|
238
|
-
if (wrapping) {
|
|
239
|
-
tr.wrap(range, wrapping).scrollIntoView();
|
|
240
|
-
} else {
|
|
241
|
-
/** We always want to append a block type */
|
|
242
|
-
safeInsert(type.createAndFill(nodeAttributes))(tr).scrollIntoView();
|
|
243
|
-
}
|
|
244
|
-
return tr;
|
|
245
|
-
}
|
|
246
|
-
function getWrappingOptions(state, type, nodeAttributes) {
|
|
247
|
-
const {
|
|
248
|
-
$from,
|
|
249
|
-
$to
|
|
250
|
-
} = state.selection;
|
|
251
|
-
const range = $from.blockRange($to);
|
|
252
|
-
let isAllowedChild = true;
|
|
253
|
-
/**
|
|
254
|
-
* Added a check to avoid wrapping codeblock
|
|
255
|
-
*/
|
|
256
|
-
if (state.selection.empty) {
|
|
257
|
-
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
|
258
|
-
if (!isAllowedChild) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
return isAllowedChild = node.type !== state.schema.nodes.codeBlock;
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
const wrapping = isAllowedChild && range && findWrapping(range, type, nodeAttributes);
|
|
265
|
-
return {
|
|
266
|
-
range,
|
|
267
|
-
wrapping
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Function will add wrapping node.
|
|
273
|
-
* 1. If currently selected blocks can be wrapped in the wrapper type it will wrap them.
|
|
274
|
-
* 2. If current block can not be wrapped inside wrapping block it will create a new block below selection,
|
|
275
|
-
* and set selection on it.
|
|
276
|
-
*/
|
|
277
|
-
function wrapSelectionIn(type) {
|
|
278
|
-
return function (state, dispatch) {
|
|
279
|
-
let tr = createWrapSelectionTransaction({
|
|
280
|
-
state,
|
|
281
|
-
type
|
|
282
|
-
});
|
|
283
|
-
if (dispatch) {
|
|
284
|
-
dispatch(tr);
|
|
285
|
-
}
|
|
286
|
-
return true;
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* This function creates a new transaction that inserts a code block,
|
|
292
|
-
* if there is text selected it will wrap the current selection if not it will
|
|
293
|
-
* append the codeblock to the end of the document.
|
|
294
|
-
*/
|
|
295
|
-
export function createInsertCodeBlockTransaction({
|
|
296
|
-
state
|
|
297
|
-
}) {
|
|
298
|
-
var _state$selection$$fro;
|
|
299
|
-
let {
|
|
300
|
-
tr
|
|
301
|
-
} = state;
|
|
302
|
-
const {
|
|
303
|
-
from
|
|
304
|
-
} = state.selection;
|
|
305
|
-
const {
|
|
306
|
-
codeBlock
|
|
307
|
-
} = state.schema.nodes;
|
|
308
|
-
const grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
|
|
309
|
-
const parentNodeType = state.selection.$from.parent.type;
|
|
310
|
-
|
|
311
|
-
/** We always want to append a codeBlock unless we're inserting into a paragraph
|
|
312
|
-
* AND it's a valid child of the grandparent node.
|
|
313
|
-
* Insert the current selection as codeBlock content unless it contains nodes other
|
|
314
|
-
* than paragraphs and inline.
|
|
315
|
-
*/
|
|
316
|
-
const canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
|
|
317
|
-
parentNodeType,
|
|
318
|
-
grandParentNodeType,
|
|
319
|
-
content: codeBlock.createAndFill()
|
|
320
|
-
}) && contentAllowedInCodeBlock(state);
|
|
321
|
-
if (canInsertCodeBlock) {
|
|
322
|
-
tr = transformToCodeBlockAction(state, from);
|
|
323
|
-
} else {
|
|
324
|
-
safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
|
|
325
|
-
}
|
|
326
|
-
return tr;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Function will insert code block at current selection if block is empty or below current selection and set focus on it.
|
|
331
|
-
*/
|
|
332
|
-
function insertCodeBlock() {
|
|
333
|
-
return function (state, dispatch) {
|
|
334
|
-
let tr = createInsertCodeBlockTransaction({
|
|
335
|
-
state
|
|
336
|
-
});
|
|
337
|
-
if (dispatch) {
|
|
338
|
-
dispatch(tr);
|
|
339
|
-
}
|
|
340
|
-
return true;
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Check if the current selection contains any nodes that are not permitted
|
|
346
|
-
* as codeBlock child nodes. Note that this allows paragraphs and inline nodes
|
|
347
|
-
* as we extract their text content.
|
|
348
|
-
*/
|
|
349
|
-
function contentAllowedInCodeBlock(state) {
|
|
350
|
-
const {
|
|
351
|
-
$from,
|
|
352
|
-
$to
|
|
353
|
-
} = state.selection;
|
|
354
|
-
let isAllowedChild = true;
|
|
355
|
-
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
|
356
|
-
if (!isAllowedChild) {
|
|
357
|
-
return false;
|
|
150
|
+
export const insertBlockQuoteWithAnalytics = (inputMethod, editorAnalyticsApi) => {
|
|
151
|
+
return withAnalytics(editorAnalyticsApi, {
|
|
152
|
+
action: ACTION.FORMATTED,
|
|
153
|
+
actionSubject: ACTION_SUBJECT.TEXT,
|
|
154
|
+
eventType: EVENT_TYPE.TRACK,
|
|
155
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_BLOCK_QUOTE,
|
|
156
|
+
attributes: {
|
|
157
|
+
inputMethod: inputMethod
|
|
358
158
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return isAllowedChild;
|
|
362
|
-
}
|
|
159
|
+
})(insertBlockQuote());
|
|
160
|
+
};
|
|
363
161
|
export const cleanUpAtTheStartOfDocument = (state, dispatch) => {
|
|
364
162
|
const {
|
|
365
163
|
$cursor
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export { cleanUpAtTheStartOfDocument,
|
|
2
|
-
export { insertBlock } from './insert-block';
|
|
3
|
-
export { isConvertableToCodeBlock, transformToCodeBlockAction } from './transform-to-code-block';
|
|
1
|
+
export { cleanUpAtTheStartOfDocument, insertBlockQuoteWithAnalytics, setBlockType, setBlockTypeWithAnalytics, setHeading, setHeadingWithAnalytics, setNormalText, setNormalTextWithAnalytics } from './block-type';
|
|
4
2
|
export { deleteAndMoveCursor } from './delete-and-move-cursor';
|
|
5
3
|
export { deleteBlockContent } from './delete-block-content';
|
|
@@ -11,6 +11,7 @@ import inputRulePlugin from './pm-plugins/input-rule';
|
|
|
11
11
|
import ToolbarBlockType from './ui/ToolbarBlockType';
|
|
12
12
|
import { setBlockTypeWithAnalytics } from './commands';
|
|
13
13
|
import { messages } from './messages';
|
|
14
|
+
import { insertBlockQuoteWithAnalytics } from './commands/block-type';
|
|
14
15
|
const headingPluginOptions = ({
|
|
15
16
|
formatMessage
|
|
16
17
|
}, isAllowed, editorAnalyticsApi) => {
|
|
@@ -135,6 +136,22 @@ const blockTypePlugin = ({
|
|
|
135
136
|
}
|
|
136
137
|
}];
|
|
137
138
|
},
|
|
139
|
+
actions: {
|
|
140
|
+
insertBlockQuote(inputMethod) {
|
|
141
|
+
var _api$analytics4;
|
|
142
|
+
return insertBlockQuoteWithAnalytics(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions);
|
|
143
|
+
},
|
|
144
|
+
setBlockType(name, inputMethod) {
|
|
145
|
+
var _api$analytics5;
|
|
146
|
+
return setBlockTypeWithAnalytics(name, inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
getSharedState(editorState) {
|
|
150
|
+
if (!editorState) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
return pluginKey.getState(editorState);
|
|
154
|
+
},
|
|
138
155
|
primaryToolbarComponent({
|
|
139
156
|
editorView,
|
|
140
157
|
popupsMountPoint,
|
|
@@ -147,8 +164,8 @@ const blockTypePlugin = ({
|
|
|
147
164
|
}) {
|
|
148
165
|
const isSmall = options && options.isUndoRedoButtonsEnabled ? toolbarSize < ToolbarSize.XXL : toolbarSize < ToolbarSize.XL;
|
|
149
166
|
const boundSetBlockType = name => {
|
|
150
|
-
var _api$
|
|
151
|
-
return setBlockTypeWithAnalytics(name, INPUT_METHOD.TOOLBAR, api === null || api === void 0 ? void 0 : (_api$
|
|
167
|
+
var _api$analytics6;
|
|
168
|
+
return setBlockTypeWithAnalytics(name, INPUT_METHOD.TOOLBAR, api === null || api === void 0 ? void 0 : (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions)(editorView.state, editorView.dispatch);
|
|
152
169
|
};
|
|
153
170
|
return /*#__PURE__*/React.createElement(WithPluginState, {
|
|
154
171
|
editorView: editorView,
|
|
@@ -174,9 +191,9 @@ const blockTypePlugin = ({
|
|
|
174
191
|
},
|
|
175
192
|
pluginsOptions: {
|
|
176
193
|
quickInsert: intl => {
|
|
177
|
-
var _api$
|
|
194
|
+
var _api$analytics7, _api$analytics8;
|
|
178
195
|
const exclude = options && options.allowBlockType && options.allowBlockType.exclude ? options.allowBlockType.exclude : [];
|
|
179
|
-
return [...blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 ? void 0 : (_api$
|
|
196
|
+
return [...blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 ? void 0 : (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions), ...headingPluginOptions(intl, exclude.indexOf('heading') === -1, api === null || api === void 0 ? void 0 : (_api$analytics8 = api.analytics) === null || _api$analytics8 === void 0 ? void 0 : _api$analytics8.actions)];
|
|
180
197
|
}
|
|
181
198
|
}
|
|
182
199
|
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
2
1
|
import { createRule, createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
|
|
3
2
|
import { INPUT_METHOD, ACTION, ACTION_SUBJECT, EVENT_TYPE, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
4
3
|
import { inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
5
|
-
import {
|
|
6
|
-
import { insertBlock } from '../commands/insert-block';
|
|
4
|
+
import { insertBlock } from '@atlaskit/editor-common/commands';
|
|
7
5
|
import { createJoinNodesRule, createWrappingTextBlockRule } from '../utils';
|
|
8
6
|
const MAX_HEADING_LEVEL = 6;
|
|
9
7
|
function getHeadingLevel(match) {
|
|
@@ -33,7 +31,7 @@ function getHeadingRules(editorAnalyticsAPI, schema) {
|
|
|
33
31
|
const hashRule = headingRule(schema.nodes.heading, MAX_HEADING_LEVEL);
|
|
34
32
|
const leftNodeReplacementHashRule = createRule(new RegExp(`${leafNodeReplacementCharacter}(#{1,6})\\s$`), (state, match, start, end) => {
|
|
35
33
|
const level = match[1].length;
|
|
36
|
-
return insertBlock(state, schema.nodes.heading,
|
|
34
|
+
return insertBlock(state, schema.nodes.heading, start, end, {
|
|
37
35
|
level
|
|
38
36
|
});
|
|
39
37
|
});
|
|
@@ -62,7 +60,7 @@ function getBlockQuoteRules(editorAnalyticsAPI, schema) {
|
|
|
62
60
|
// '> ' for blockquote
|
|
63
61
|
const greatherThanRule = blockQuoteRule(schema.nodes.blockquote);
|
|
64
62
|
const leftNodeReplacementGreatherRule = createRule(new RegExp(`${leafNodeReplacementCharacter}\\s*>\\s$`), (state, _match, start, end) => {
|
|
65
|
-
return insertBlock(state, schema.nodes.blockquote,
|
|
63
|
+
return insertBlock(state, schema.nodes.blockquote, start, end);
|
|
66
64
|
});
|
|
67
65
|
|
|
68
66
|
// Analytics V3 handler
|
|
@@ -77,54 +75,6 @@ function getBlockQuoteRules(editorAnalyticsAPI, schema) {
|
|
|
77
75
|
}, editorAnalyticsAPI);
|
|
78
76
|
return [ruleWithBlockQuoteAnalytics(greatherThanRule), ruleWithBlockQuoteAnalytics(leftNodeReplacementGreatherRule)];
|
|
79
77
|
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Get all code block input rules
|
|
83
|
-
*
|
|
84
|
-
* @param {Schema} schema
|
|
85
|
-
* @returns {InputRuleWithHandler[]}
|
|
86
|
-
*/
|
|
87
|
-
function getCodeBlockRules(editorAnalyticsAPI, schema) {
|
|
88
|
-
const ruleAnalytics = inputRuleWithAnalytics({
|
|
89
|
-
action: ACTION.INSERTED,
|
|
90
|
-
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
91
|
-
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
92
|
-
attributes: {
|
|
93
|
-
inputMethod: INPUT_METHOD.FORMATTING
|
|
94
|
-
},
|
|
95
|
-
eventType: EVENT_TYPE.TRACK
|
|
96
|
-
}, editorAnalyticsAPI);
|
|
97
|
-
const validMatchLength = match => match.length > 0 && match[0].length === 3;
|
|
98
|
-
const threeTildeRule = createRule(/(?!\s)(`{3,})$/, (state, match, start, end) => {
|
|
99
|
-
if (!validMatchLength(match)) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
const attributes = {};
|
|
103
|
-
if (match[4]) {
|
|
104
|
-
attributes.language = match[4];
|
|
105
|
-
}
|
|
106
|
-
if (isConvertableToCodeBlock(state)) {
|
|
107
|
-
return transformToCodeBlockAction(state, start, attributes);
|
|
108
|
-
}
|
|
109
|
-
const tr = state.tr;
|
|
110
|
-
tr.delete(start, end);
|
|
111
|
-
const codeBlock = tr.doc.type.schema.nodes.codeBlock.createChecked();
|
|
112
|
-
safeInsert(codeBlock)(tr);
|
|
113
|
-
return tr;
|
|
114
|
-
});
|
|
115
|
-
const leftNodeReplacementThreeTildeRule = createRule(new RegExp(`((${leafNodeReplacementCharacter}\`{3,})|^\\s(\`{3,}))(\\S*)$`), (state, match, start, end) => {
|
|
116
|
-
if (!validMatchLength(match)) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
const attributes = {};
|
|
120
|
-
if (match[4]) {
|
|
121
|
-
attributes.language = match[4];
|
|
122
|
-
}
|
|
123
|
-
const inlineStart = Math.max(match.index + state.selection.$from.start(), 1);
|
|
124
|
-
return insertBlock(state, schema.nodes.codeBlock, 'codeblock', inlineStart, end, attributes);
|
|
125
|
-
});
|
|
126
|
-
return [ruleAnalytics(threeTildeRule), ruleAnalytics(leftNodeReplacementThreeTildeRule)];
|
|
127
|
-
}
|
|
128
78
|
function inputRulePlugin(editorAnalyticsAPI, schema, featureFlags) {
|
|
129
79
|
const rules = [];
|
|
130
80
|
if (schema.nodes.heading) {
|
|
@@ -133,9 +83,6 @@ function inputRulePlugin(editorAnalyticsAPI, schema, featureFlags) {
|
|
|
133
83
|
if (schema.nodes.blockquote) {
|
|
134
84
|
rules.push(...getBlockQuoteRules(editorAnalyticsAPI, schema));
|
|
135
85
|
}
|
|
136
|
-
if (schema.nodes.codeBlock) {
|
|
137
|
-
rules.push(...getCodeBlockRules(editorAnalyticsAPI, schema));
|
|
138
|
-
}
|
|
139
86
|
if (rules.length !== 0) {
|
|
140
87
|
return createPlugin('block-type', rules, {
|
|
141
88
|
isBlockNodeRule: true
|
|
@@ -4,7 +4,7 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
|
4
4
|
import { bindKeymapWithCommand, moveUp, moveDown, findKeyMapForBrowser, undo as undoKeymap, redo as redoKeymap, backspace, deleteKey, forwardDelete, toggleBlockQuote, keymap, insertNewLine, findShortcutByKeymap } from '@atlaskit/editor-common/keymaps';
|
|
5
5
|
import { insertNewLineWithAnalytics, createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphAndMoveBlockUp } from '@atlaskit/editor-common/utils';
|
|
6
6
|
import * as blockTypes from '../types';
|
|
7
|
-
import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, deleteBlockContent,
|
|
7
|
+
import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, deleteBlockContent, insertBlockQuoteWithAnalytics } from '../commands';
|
|
8
8
|
import { isNodeAWrappingBlockNode } from '../utils';
|
|
9
9
|
const backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
10
10
|
const del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
|
@@ -19,7 +19,7 @@ export default function keymapPlugin(editorAnalyticsApi, schema, _featureFlags)
|
|
|
19
19
|
bindKeymapWithCommand(deleteKey.common, del, list);
|
|
20
20
|
bindKeymapWithCommand(forwardDelete.mac, del, list);
|
|
21
21
|
if (schema.nodes[blockTypes.BLOCK_QUOTE.nodeName]) {
|
|
22
|
-
bindKeymapWithCommand(findShortcutByKeymap(toggleBlockQuote),
|
|
22
|
+
bindKeymapWithCommand(findShortcutByKeymap(toggleBlockQuote), insertBlockQuoteWithAnalytics(INPUT_METHOD.KEYBOARD, editorAnalyticsApi), list);
|
|
23
23
|
}
|
|
24
24
|
return keymap(list);
|
|
25
25
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { findParentNodeOfType, findSelectedNodeOfType, removeSelectedNode, removeParentNodeOfType, isNodeSelection } from '@atlaskit/editor-prosemirror/utils';
|
|
1
|
+
import { findParentNodeOfType, findSelectedNodeOfType, removeSelectedNode, removeParentNodeOfType, isNodeSelection, safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
2
2
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import { pluginKey } from './plugin-key';
|
|
4
4
|
import { copySelectionPluginKey } from './pm-plugins/codeBlockCopySelectionPlugin';
|
|
5
5
|
import { ACTIONS } from './pm-plugins/actions';
|
|
6
6
|
import { copyToClipboard } from '../../utils/clipboard';
|
|
7
7
|
import { addAnalytics } from '../analytics/utils';
|
|
8
|
-
import {
|
|
8
|
+
import { shouldSplitSelectedNodeOnNodeInsertion } from '@atlaskit/editor-common/insert';
|
|
9
|
+
import { transformToCodeBlockAction } from './transform-to-code-block';
|
|
10
|
+
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
|
11
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
9
12
|
export const removeCodeBlock = (state, dispatch) => {
|
|
10
13
|
const {
|
|
11
14
|
schema: {
|
|
@@ -127,4 +130,82 @@ export const resetShouldIgnoreFollowingMutations = (state, dispatch) => {
|
|
|
127
130
|
dispatch(ignoreFollowingMutationsTr);
|
|
128
131
|
}
|
|
129
132
|
return true;
|
|
130
|
-
};
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* This function creates a new transaction that inserts a code block,
|
|
137
|
+
* if there is text selected it will wrap the current selection if not it will
|
|
138
|
+
* append the codeblock to the end of the document.
|
|
139
|
+
*/
|
|
140
|
+
export function createInsertCodeBlockTransaction({
|
|
141
|
+
state
|
|
142
|
+
}) {
|
|
143
|
+
var _state$selection$$fro;
|
|
144
|
+
let {
|
|
145
|
+
tr
|
|
146
|
+
} = state;
|
|
147
|
+
const {
|
|
148
|
+
from
|
|
149
|
+
} = state.selection;
|
|
150
|
+
const {
|
|
151
|
+
codeBlock
|
|
152
|
+
} = state.schema.nodes;
|
|
153
|
+
const grandParentNodeType = (_state$selection$$fro = state.selection.$from.node(-1)) === null || _state$selection$$fro === void 0 ? void 0 : _state$selection$$fro.type;
|
|
154
|
+
const parentNodeType = state.selection.$from.parent.type;
|
|
155
|
+
|
|
156
|
+
/** We always want to append a codeBlock unless we're inserting into a paragraph
|
|
157
|
+
* AND it's a valid child of the grandparent node.
|
|
158
|
+
* Insert the current selection as codeBlock content unless it contains nodes other
|
|
159
|
+
* than paragraphs and inline.
|
|
160
|
+
*/
|
|
161
|
+
const canInsertCodeBlock = shouldSplitSelectedNodeOnNodeInsertion({
|
|
162
|
+
parentNodeType,
|
|
163
|
+
grandParentNodeType,
|
|
164
|
+
content: codeBlock.createAndFill()
|
|
165
|
+
}) && contentAllowedInCodeBlock(state);
|
|
166
|
+
if (canInsertCodeBlock) {
|
|
167
|
+
tr = transformToCodeBlockAction(state, from);
|
|
168
|
+
} else {
|
|
169
|
+
safeInsert(codeBlock.createAndFill())(tr).scrollIntoView();
|
|
170
|
+
}
|
|
171
|
+
return tr;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Check if the current selection contains any nodes that are not permitted
|
|
176
|
+
* as codeBlock child nodes. Note that this allows paragraphs and inline nodes
|
|
177
|
+
* as we extract their text content.
|
|
178
|
+
*/
|
|
179
|
+
function contentAllowedInCodeBlock(state) {
|
|
180
|
+
const {
|
|
181
|
+
$from,
|
|
182
|
+
$to
|
|
183
|
+
} = state.selection;
|
|
184
|
+
let isAllowedChild = true;
|
|
185
|
+
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
|
186
|
+
if (!isAllowedChild) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
return isAllowedChild = node.type === state.schema.nodes.listItem || node.type === state.schema.nodes.bulletList || node.type === state.schema.nodes.orderedList || node.type === state.schema.nodes.paragraph || node.isInline || node.isText;
|
|
190
|
+
});
|
|
191
|
+
return isAllowedChild;
|
|
192
|
+
}
|
|
193
|
+
export function insertCodeBlockWithAnalytics(inputMethod, analyticsAPI) {
|
|
194
|
+
return withAnalytics(analyticsAPI, {
|
|
195
|
+
action: ACTION.INSERTED,
|
|
196
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
197
|
+
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
198
|
+
attributes: {
|
|
199
|
+
inputMethod: inputMethod
|
|
200
|
+
},
|
|
201
|
+
eventType: EVENT_TYPE.TRACK
|
|
202
|
+
})(function (state, dispatch) {
|
|
203
|
+
let tr = createInsertCodeBlockTransaction({
|
|
204
|
+
state
|
|
205
|
+
});
|
|
206
|
+
if (dispatch) {
|
|
207
|
+
dispatch(tr);
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
@@ -9,10 +9,8 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, INPUT_METHOD, EVENT_TYPE } f
|
|
|
9
9
|
import { IconCode } from '@atlaskit/editor-common/quick-insert';
|
|
10
10
|
import { messages } from '../block-type/messages';
|
|
11
11
|
import refreshBrowserSelectionOnChange from './refresh-browser-selection';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// tslint-ignore-next-line
|
|
15
|
-
import { createInsertCodeBlockTransaction } from '../block-type/commands/block-type';
|
|
12
|
+
import { createInsertCodeBlockTransaction, insertCodeBlockWithAnalytics } from './actions';
|
|
13
|
+
import { createCodeBlockInputRule } from './pm-plugins/input-rule';
|
|
16
14
|
const codeBlockPlugin = ({
|
|
17
15
|
config: options,
|
|
18
16
|
api
|
|
@@ -37,6 +35,14 @@ const codeBlockPlugin = ({
|
|
|
37
35
|
appearance: (_options$appearance = options === null || options === void 0 ? void 0 : options.appearance) !== null && _options$appearance !== void 0 ? _options$appearance : 'comment'
|
|
38
36
|
});
|
|
39
37
|
}
|
|
38
|
+
}, {
|
|
39
|
+
name: 'codeBlockInputRule',
|
|
40
|
+
plugin: ({
|
|
41
|
+
schema
|
|
42
|
+
}) => {
|
|
43
|
+
var _api$analytics;
|
|
44
|
+
return createCodeBlockInputRule(schema, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
45
|
+
}
|
|
40
46
|
}, {
|
|
41
47
|
name: 'codeBlockIDEKeyBindings',
|
|
42
48
|
plugin: () => ideUX(api)
|
|
@@ -55,6 +61,15 @@ const codeBlockPlugin = ({
|
|
|
55
61
|
onEditorViewStateUpdated(props) {
|
|
56
62
|
refreshBrowserSelectionOnChange(props.originalTransaction, props.newEditorState);
|
|
57
63
|
},
|
|
64
|
+
actions: {
|
|
65
|
+
/*
|
|
66
|
+
* Function will insert code block at current selection if block is empty or below current selection and set focus on it.
|
|
67
|
+
*/
|
|
68
|
+
insertCodeBlock: inputMethod => {
|
|
69
|
+
var _api$analytics2;
|
|
70
|
+
return insertCodeBlockWithAnalytics(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
58
73
|
pluginsOptions: {
|
|
59
74
|
quickInsert: ({
|
|
60
75
|
formatMessage
|
|
@@ -66,12 +81,12 @@ const codeBlockPlugin = ({
|
|
|
66
81
|
priority: 700,
|
|
67
82
|
keyshortcut: '```',
|
|
68
83
|
icon: () => /*#__PURE__*/React.createElement(IconCode, null),
|
|
69
|
-
action(
|
|
70
|
-
var _api$
|
|
84
|
+
action(_insert, state) {
|
|
85
|
+
var _api$analytics3;
|
|
71
86
|
const tr = createInsertCodeBlockTransaction({
|
|
72
87
|
state
|
|
73
88
|
});
|
|
74
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
89
|
+
api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.attachAnalyticsEvent({
|
|
75
90
|
action: ACTION.INSERTED,
|
|
76
91
|
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
77
92
|
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
2
|
+
import { createRule, createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
|
|
3
|
+
import { INPUT_METHOD, ACTION, ACTION_SUBJECT, EVENT_TYPE, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { isConvertableToCodeBlock, transformToCodeBlockAction } from '../transform-to-code-block';
|
|
6
|
+
import { insertBlock } from '@atlaskit/editor-common/commands';
|
|
7
|
+
export function createCodeBlockInputRule(schema, editorAnalyticsAPI) {
|
|
8
|
+
const rules = getCodeBlockRules(editorAnalyticsAPI, schema);
|
|
9
|
+
return createPlugin('code-block-input-rule', rules, {
|
|
10
|
+
isBlockNodeRule: true
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get all code block input rules
|
|
16
|
+
*
|
|
17
|
+
* @param {Schema} schema
|
|
18
|
+
* @returns {InputRuleWithHandler[]}
|
|
19
|
+
*/
|
|
20
|
+
function getCodeBlockRules(editorAnalyticsAPI, schema) {
|
|
21
|
+
const ruleAnalytics = inputRuleWithAnalytics({
|
|
22
|
+
action: ACTION.INSERTED,
|
|
23
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
24
|
+
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
|
|
25
|
+
attributes: {
|
|
26
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
27
|
+
},
|
|
28
|
+
eventType: EVENT_TYPE.TRACK
|
|
29
|
+
}, editorAnalyticsAPI);
|
|
30
|
+
const validMatchLength = match => match.length > 0 && match[0].length === 3;
|
|
31
|
+
const threeTildeRule = createRule(/(?!\s)(`{3,})$/, (state, match, start, end) => {
|
|
32
|
+
if (!validMatchLength(match)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const attributes = {};
|
|
36
|
+
if (match[4]) {
|
|
37
|
+
attributes.language = match[4];
|
|
38
|
+
}
|
|
39
|
+
if (isConvertableToCodeBlock(state)) {
|
|
40
|
+
return transformToCodeBlockAction(state, start, attributes);
|
|
41
|
+
}
|
|
42
|
+
const tr = state.tr;
|
|
43
|
+
tr.delete(start, end);
|
|
44
|
+
const codeBlock = tr.doc.type.schema.nodes.codeBlock.createChecked();
|
|
45
|
+
safeInsert(codeBlock)(tr);
|
|
46
|
+
return tr;
|
|
47
|
+
});
|
|
48
|
+
const leftNodeReplacementThreeTildeRule = createRule(new RegExp(`((${leafNodeReplacementCharacter}\`{3,})|^\\s(\`{3,}))(\\S*)$`), (state, match, start, end) => {
|
|
49
|
+
if (!validMatchLength(match)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const attributes = {};
|
|
53
|
+
if (match[4]) {
|
|
54
|
+
attributes.language = match[4];
|
|
55
|
+
}
|
|
56
|
+
const inlineStart = Math.max(match.index + state.selection.$from.start(), 1);
|
|
57
|
+
return insertBlock(state, schema.nodes.codeBlock, inlineStart, end, attributes);
|
|
58
|
+
});
|
|
59
|
+
return [ruleAnalytics(threeTildeRule), ruleAnalytics(leftNodeReplacementThreeTildeRule)];
|
|
60
|
+
}
|
|
@@ -15,7 +15,7 @@ import { INPUT_METHOD } from '../../../analytics/types/enums';
|
|
|
15
15
|
import { injectIntl } from 'react-intl-next';
|
|
16
16
|
import DatePickerInput from './date-picker-input';
|
|
17
17
|
const popupContentWrapper = css`
|
|
18
|
-
padding: 2px;
|
|
18
|
+
padding: ${"var(--ds-space-025, 2px)"};
|
|
19
19
|
border-radius: ${borderRadius()}px;
|
|
20
20
|
box-shadow: ${`var(--ds-shadow-overlay, ${`0 4px 8px -2px ${N60A}, 0 0 1px ${N60A}`})`};
|
|
21
21
|
background-color: ${`var(--ds-surface-overlay, ${N0})`};
|
|
@@ -143,7 +143,8 @@ class DatePicker extends React.Component {
|
|
|
143
143
|
year: year,
|
|
144
144
|
selected: selected,
|
|
145
145
|
ref: this.handleRef,
|
|
146
|
-
weekStartDay: weekStartDay
|
|
146
|
+
weekStartDay: weekStartDay,
|
|
147
|
+
testId: 'datepicker'
|
|
147
148
|
})));
|
|
148
149
|
}
|
|
149
150
|
}
|