@atlaskit/editor-plugin-insert-block 0.2.18 → 0.2.20
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 +12 -0
- package/dist/cjs/ui/ToolbarInsertBlock/index.js +99 -39
- package/dist/cjs/ui/ToolbarInsertBlock/table-selector-popup-with-listeners.js +114 -0
- package/dist/cjs/ui/ToolbarInsertBlock/table-selector-popup.js +109 -0
- package/dist/es2019/ui/ToolbarInsertBlock/index.js +87 -30
- package/dist/es2019/ui/ToolbarInsertBlock/table-selector-popup-with-listeners.js +101 -0
- package/dist/es2019/ui/ToolbarInsertBlock/table-selector-popup.js +102 -0
- package/dist/esm/ui/ToolbarInsertBlock/index.js +99 -39
- package/dist/esm/ui/ToolbarInsertBlock/table-selector-popup-with-listeners.js +104 -0
- package/dist/esm/ui/ToolbarInsertBlock/table-selector-popup.js +102 -0
- package/dist/types/ui/ToolbarInsertBlock/index.d.ts +11 -1
- package/dist/types/ui/ToolbarInsertBlock/table-selector-popup-with-listeners.d.ts +15 -0
- package/dist/types/ui/ToolbarInsertBlock/table-selector-popup.d.ts +25 -0
- package/dist/types-ts4.5/ui/ToolbarInsertBlock/index.d.ts +11 -1
- package/dist/types-ts4.5/ui/ToolbarInsertBlock/table-selector-popup-with-listeners.d.ts +15 -0
- package/dist/types-ts4.5/ui/ToolbarInsertBlock/table-selector-popup.d.ts +25 -0
- package/package.json +6 -4
|
@@ -15,6 +15,7 @@ import * as colors from '@atlaskit/theme/colors';
|
|
|
15
15
|
import { BlockInsertMenu } from './block-insert-menu';
|
|
16
16
|
import { createItems } from './create-items';
|
|
17
17
|
import { messages } from './messages';
|
|
18
|
+
import TableSelectorPopup from './table-selector-popup-with-listeners';
|
|
18
19
|
/**
|
|
19
20
|
* Checks if an element is detached (i.e. not in the current document)
|
|
20
21
|
*/
|
|
@@ -31,10 +32,13 @@ const getHoverStyles = selector => `&:hover ${selector} {
|
|
|
31
32
|
background: ${`var(--ds-background-neutral-hovered, ${colors.N30A})`};
|
|
32
33
|
}
|
|
33
34
|
}`;
|
|
34
|
-
export const tableButtonWrapper =
|
|
35
|
+
export const tableButtonWrapper = ({
|
|
36
|
+
isTableSelectorOpen,
|
|
37
|
+
isButtonDisabled
|
|
38
|
+
}) => css`
|
|
35
39
|
display: flex;
|
|
36
|
-
${getHoverStyles('.table-selector-toolbar-btn')}
|
|
37
|
-
${getHoverStyles('.table-toolbar-btn')}
|
|
40
|
+
${!isTableSelectorOpen && !isButtonDisabled && getHoverStyles('.table-selector-toolbar-btn')}
|
|
41
|
+
${!isTableSelectorOpen && !isButtonDisabled && getHoverStyles('.table-toolbar-btn')}
|
|
38
42
|
|
|
39
43
|
.table-toolbar-btn {
|
|
40
44
|
border-top-right-radius: ${"var(--ds-border-radius-200, 0px)"};
|
|
@@ -42,6 +46,7 @@ export const tableButtonWrapper = css`
|
|
|
42
46
|
margin-right: ${"var(--ds-space-025, 1px)"};
|
|
43
47
|
padding: ${"var(--ds-space-0, 0px)"};
|
|
44
48
|
& > span {
|
|
49
|
+
min-width: 16px;
|
|
45
50
|
margin: ${"var(--ds-space-0, 0px)"};
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -63,6 +68,8 @@ export const tableButtonWrapper = css`
|
|
|
63
68
|
export class ToolbarInsertBlock extends React.PureComponent {
|
|
64
69
|
constructor(...args) {
|
|
65
70
|
super(...args);
|
|
71
|
+
_defineProperty(this, "tableButtonRef", /*#__PURE__*/React.createRef());
|
|
72
|
+
_defineProperty(this, "tableSelectorButtonRef", /*#__PURE__*/React.createRef());
|
|
66
73
|
_defineProperty(this, "state", {
|
|
67
74
|
isPlusMenuOpen: false,
|
|
68
75
|
emojiPickerOpen: false,
|
|
@@ -169,6 +176,26 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
169
176
|
this.dropdownButtonRef = ref;
|
|
170
177
|
}
|
|
171
178
|
});
|
|
179
|
+
_defineProperty(this, "toggleTableSelector", (inputMethod = INPUT_METHOD.TOOLBAR) => {
|
|
180
|
+
this.setState(prevState => ({
|
|
181
|
+
isTableSelectorOpen: !prevState.isTableSelectorOpen
|
|
182
|
+
}));
|
|
183
|
+
});
|
|
184
|
+
_defineProperty(this, "handleSelectedTableSize", (rowsCount, colsCount) => {
|
|
185
|
+
this.insertTableWithSize(INPUT_METHOD.TOOLBAR, rowsCount, colsCount)();
|
|
186
|
+
this.toggleTableSelector();
|
|
187
|
+
});
|
|
188
|
+
_defineProperty(this, "handleTableSelectorPressEscape", () => {
|
|
189
|
+
var _this$tableSelectorBu;
|
|
190
|
+
this.toggleTableSelector(INPUT_METHOD.KEYBOARD);
|
|
191
|
+
(_this$tableSelectorBu = this.tableSelectorButtonRef.current) === null || _this$tableSelectorBu === void 0 ? void 0 : _this$tableSelectorBu.focus();
|
|
192
|
+
});
|
|
193
|
+
_defineProperty(this, "handleTableSelectorClickOutside", e => {
|
|
194
|
+
// Ignore click events for detached elements.
|
|
195
|
+
if (e.target && !isDetachedElement(e.target)) {
|
|
196
|
+
this.toggleTableSelector(INPUT_METHOD.TOOLBAR);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
172
199
|
_defineProperty(this, "handleClick", () => {
|
|
173
200
|
this.togglePlusMenuVisibility();
|
|
174
201
|
});
|
|
@@ -183,11 +210,11 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
183
210
|
}
|
|
184
211
|
});
|
|
185
212
|
_defineProperty(this, "toggleLinkPanel", inputMethod => {
|
|
186
|
-
var _pluginInjectionApi$c, _pluginInjectionApi$h;
|
|
213
|
+
var _pluginInjectionApi$c, _pluginInjectionApi$c2, _pluginInjectionApi$h;
|
|
187
214
|
const {
|
|
188
215
|
pluginInjectionApi
|
|
189
216
|
} = this.props;
|
|
190
|
-
return (_pluginInjectionApi$c = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.core.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$h = pluginInjectionApi.hyperlink) === null || _pluginInjectionApi$h === void 0 ? void 0 : _pluginInjectionApi$h.commands.showLinkToolbar(inputMethod))) !== null && _pluginInjectionApi$c !== void 0 ? _pluginInjectionApi$c : false;
|
|
217
|
+
return (_pluginInjectionApi$c = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c2 = pluginInjectionApi.core) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$h = pluginInjectionApi.hyperlink) === null || _pluginInjectionApi$h === void 0 ? void 0 : _pluginInjectionApi$h.commands.showLinkToolbar(inputMethod))) !== null && _pluginInjectionApi$c !== void 0 ? _pluginInjectionApi$c : false;
|
|
191
218
|
});
|
|
192
219
|
_defineProperty(this, "insertMention", inputMethod => {
|
|
193
220
|
var _pluginInjectionApi$m, _pluginInjectionApi$m2, _pluginInjectionApi$m3;
|
|
@@ -225,18 +252,18 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
225
252
|
})(state, dispatch)) !== null && _pluginInjectionApi$t !== void 0 ? _pluginInjectionApi$t : false;
|
|
226
253
|
});
|
|
227
254
|
_defineProperty(this, "insertTableWithSize", (inputMethod, rowsCount, colsCount) => () => {
|
|
228
|
-
var _pluginInjectionApi$t5;
|
|
255
|
+
var _pluginInjectionApi$c3, _pluginInjectionApi$t5;
|
|
229
256
|
const {
|
|
230
257
|
pluginInjectionApi
|
|
231
258
|
} = this.props;
|
|
232
|
-
return pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.core.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$t5 = pluginInjectionApi.table) === null || _pluginInjectionApi$t5 === void 0 ? void 0 : _pluginInjectionApi$t5.commands.insertTableWithSize(rowsCount, colsCount, INPUT_METHOD.PICKER));
|
|
259
|
+
return pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c3 = pluginInjectionApi.core) === null || _pluginInjectionApi$c3 === void 0 ? void 0 : _pluginInjectionApi$c3.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$t5 = pluginInjectionApi.table) === null || _pluginInjectionApi$t5 === void 0 ? void 0 : _pluginInjectionApi$t5.commands.insertTableWithSize(rowsCount, colsCount, INPUT_METHOD.PICKER));
|
|
233
260
|
});
|
|
234
261
|
_defineProperty(this, "createDate", inputMethod => {
|
|
235
|
-
var _pluginInjectionApi$d, _pluginInjectionApi$d2;
|
|
262
|
+
var _pluginInjectionApi$c4, _pluginInjectionApi$d, _pluginInjectionApi$d2;
|
|
236
263
|
const {
|
|
237
264
|
pluginInjectionApi
|
|
238
265
|
} = this.props;
|
|
239
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.core.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.date) === null || _pluginInjectionApi$d === void 0 ? void 0 : (_pluginInjectionApi$d2 = _pluginInjectionApi$d.commands) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.insertDate({
|
|
266
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c4 = pluginInjectionApi.core) === null || _pluginInjectionApi$c4 === void 0 ? void 0 : _pluginInjectionApi$c4.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.date) === null || _pluginInjectionApi$d === void 0 ? void 0 : (_pluginInjectionApi$d2 = _pluginInjectionApi$d.commands) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.insertDate({
|
|
240
267
|
inputMethod
|
|
241
268
|
}));
|
|
242
269
|
return true;
|
|
@@ -335,21 +362,21 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
335
362
|
return true;
|
|
336
363
|
});
|
|
337
364
|
_defineProperty(this, "handleSelectedEmoji", emojiId => {
|
|
338
|
-
var _pluginInjectionApi$e3;
|
|
365
|
+
var _pluginInjectionApi$c5, _pluginInjectionApi$e3;
|
|
339
366
|
const {
|
|
340
367
|
pluginInjectionApi
|
|
341
368
|
} = this.props;
|
|
342
369
|
this.props.editorView.focus();
|
|
343
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.core.actions.execute((_pluginInjectionApi$e3 = pluginInjectionApi.emoji) === null || _pluginInjectionApi$e3 === void 0 ? void 0 : _pluginInjectionApi$e3.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
|
|
370
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c5 = pluginInjectionApi.core) === null || _pluginInjectionApi$c5 === void 0 ? void 0 : _pluginInjectionApi$c5.actions.execute((_pluginInjectionApi$e3 = pluginInjectionApi.emoji) === null || _pluginInjectionApi$e3 === void 0 ? void 0 : _pluginInjectionApi$e3.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
|
|
344
371
|
this.toggleEmojiPicker();
|
|
345
372
|
return true;
|
|
346
373
|
});
|
|
347
374
|
_defineProperty(this, "openElementBrowser", () => {
|
|
348
|
-
var _pluginInjectionApi$q;
|
|
375
|
+
var _pluginInjectionApi$c6, _pluginInjectionApi$q;
|
|
349
376
|
const {
|
|
350
377
|
pluginInjectionApi
|
|
351
378
|
} = this.props;
|
|
352
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.core.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q === void 0 ? void 0 : _pluginInjectionApi$q.commands.openElementBrowserModal);
|
|
379
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c6 = pluginInjectionApi.core) === null || _pluginInjectionApi$c6 === void 0 ? void 0 : _pluginInjectionApi$c6.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q === void 0 ? void 0 : _pluginInjectionApi$q.commands.openElementBrowserModal);
|
|
353
380
|
});
|
|
354
381
|
_defineProperty(this, "onItemActivated", ({
|
|
355
382
|
item,
|
|
@@ -374,7 +401,7 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
374
401
|
this.insertTable(inputMethod);
|
|
375
402
|
break;
|
|
376
403
|
case 'table selector':
|
|
377
|
-
this.
|
|
404
|
+
this.toggleTableSelector(inputMethod);
|
|
378
405
|
break;
|
|
379
406
|
case 'image upload':
|
|
380
407
|
if (handleImageUpload) {
|
|
@@ -490,10 +517,11 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
490
517
|
};
|
|
491
518
|
}
|
|
492
519
|
componentDidUpdate(prevProps) {
|
|
493
|
-
// If number of visible buttons changed, close emoji picker
|
|
520
|
+
// If number of visible buttons changed, close emoji picker and table selector
|
|
494
521
|
if (prevProps.buttons !== this.props.buttons) {
|
|
495
522
|
this.setState({
|
|
496
|
-
emojiPickerOpen: false
|
|
523
|
+
emojiPickerOpen: false,
|
|
524
|
+
isTableSelectorOpen: false
|
|
497
525
|
});
|
|
498
526
|
}
|
|
499
527
|
if (this.state.isOpenedByKeyboard) {
|
|
@@ -547,12 +575,37 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
547
575
|
handleEscapeKeydown: this.handleEmojiPressEscape
|
|
548
576
|
}));
|
|
549
577
|
}
|
|
578
|
+
renderTableSelectorPopup() {
|
|
579
|
+
var _this$tableButtonRef$;
|
|
580
|
+
const {
|
|
581
|
+
isTableSelectorOpen
|
|
582
|
+
} = this.state;
|
|
583
|
+
const {
|
|
584
|
+
popupsMountPoint,
|
|
585
|
+
popupsBoundariesElement,
|
|
586
|
+
popupsScrollableElement
|
|
587
|
+
} = this.props;
|
|
588
|
+
const ref = (_this$tableButtonRef$ = this.tableButtonRef.current) !== null && _this$tableButtonRef$ !== void 0 ? _this$tableButtonRef$ : undefined;
|
|
589
|
+
if (!isTableSelectorOpen) {
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
return jsx(TableSelectorPopup, {
|
|
593
|
+
target: ref,
|
|
594
|
+
onSelection: this.handleSelectedTableSize,
|
|
595
|
+
popupsMountPoint: popupsMountPoint,
|
|
596
|
+
popupsBoundariesElement: popupsBoundariesElement,
|
|
597
|
+
popupsScrollableElement: popupsScrollableElement,
|
|
598
|
+
handleClickOutside: this.handleTableSelectorClickOutside,
|
|
599
|
+
handleEscapeKeydown: this.handleTableSelectorPressEscape
|
|
600
|
+
});
|
|
601
|
+
}
|
|
550
602
|
render() {
|
|
551
|
-
var _tableButton, _tableButton2, _tableButton3, _tableButton4, _tableButton5, _tableButton6, _tableSelectorButton, _tableSelectorButton2, _tableSelectorButton3, _tableSelectorButton4, _tableSelectorButton5, _tableSelectorButton6, _this$props$isDisable, _this$props$replacePl;
|
|
603
|
+
var _tableButton, _tableButton2, _tableButton3, _tableButton4, _tableButton5, _tableButton6, _tableButton7, _tableSelectorButton, _tableSelectorButton2, _tableSelectorButton3, _tableSelectorButton4, _tableSelectorButton5, _tableSelectorButton6, _this$props$isDisable, _this$props$replacePl;
|
|
552
604
|
const {
|
|
553
605
|
buttons,
|
|
554
606
|
dropdownItems,
|
|
555
|
-
emojiPickerOpen
|
|
607
|
+
emojiPickerOpen,
|
|
608
|
+
isTableSelectorOpen
|
|
556
609
|
} = this.state;
|
|
557
610
|
const {
|
|
558
611
|
isDisabled,
|
|
@@ -595,20 +648,23 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
595
648
|
"aria-keyshortcuts": btn['aria-keyshortcuts'],
|
|
596
649
|
onItemClick: this.insertToolbarMenuItem
|
|
597
650
|
});
|
|
598
|
-
}), this.props.tableSelectorSupported &&
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
651
|
+
}), this.props.tableSelectorSupported && jsx("div", {
|
|
652
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
653
|
+
css: tableButtonWrapper({
|
|
654
|
+
isTableSelectorOpen,
|
|
655
|
+
isButtonDisabled: (_tableButton = tableButton) === null || _tableButton === void 0 ? void 0 : _tableButton.isDisabled
|
|
656
|
+
})
|
|
602
657
|
}, jsx(ToolbarButton, {
|
|
603
658
|
className: "table-toolbar-btn",
|
|
604
659
|
item: tableButton,
|
|
605
|
-
|
|
606
|
-
|
|
660
|
+
ref: this.tableButtonRef,
|
|
661
|
+
testId: String((_tableButton2 = tableButton) === null || _tableButton2 === void 0 ? void 0 : _tableButton2.content),
|
|
662
|
+
key: (_tableButton3 = tableButton) === null || _tableButton3 === void 0 ? void 0 : _tableButton3.value.name,
|
|
607
663
|
spacing: isReducedSpacing ? 'none' : 'default',
|
|
608
|
-
disabled: isDisabled || ((
|
|
609
|
-
iconBefore: (
|
|
610
|
-
selected: (
|
|
611
|
-
title: (
|
|
664
|
+
disabled: isDisabled || ((_tableButton4 = tableButton) === null || _tableButton4 === void 0 ? void 0 : _tableButton4.isDisabled),
|
|
665
|
+
iconBefore: (_tableButton5 = tableButton) === null || _tableButton5 === void 0 ? void 0 : _tableButton5.elemBefore,
|
|
666
|
+
selected: ((_tableButton6 = tableButton) === null || _tableButton6 === void 0 ? void 0 : _tableButton6.isActive) || isTableSelectorOpen,
|
|
667
|
+
title: (_tableButton7 = tableButton) === null || _tableButton7 === void 0 ? void 0 : _tableButton7.title,
|
|
612
668
|
"aria-label": tableButton ? tableButton['aria-label'] : undefined,
|
|
613
669
|
"aria-haspopup": tableButton ? tableButton['aria-haspopup'] : undefined,
|
|
614
670
|
"aria-keyshortcuts": tableButton ? tableButton['aria-keyshortcuts'] : undefined,
|
|
@@ -618,10 +674,11 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
618
674
|
item: tableSelectorButton,
|
|
619
675
|
testId: String((_tableSelectorButton = tableSelectorButton) === null || _tableSelectorButton === void 0 ? void 0 : _tableSelectorButton.content),
|
|
620
676
|
key: (_tableSelectorButton2 = tableSelectorButton) === null || _tableSelectorButton2 === void 0 ? void 0 : _tableSelectorButton2.value.name,
|
|
677
|
+
ref: this.tableSelectorButtonRef,
|
|
621
678
|
spacing: isReducedSpacing ? 'none' : 'default',
|
|
622
679
|
disabled: isDisabled || ((_tableSelectorButton3 = tableSelectorButton) === null || _tableSelectorButton3 === void 0 ? void 0 : _tableSelectorButton3.isDisabled),
|
|
623
680
|
iconBefore: (_tableSelectorButton4 = tableSelectorButton) === null || _tableSelectorButton4 === void 0 ? void 0 : _tableSelectorButton4.elemBefore,
|
|
624
|
-
selected: (_tableSelectorButton5 = tableSelectorButton) === null || _tableSelectorButton5 === void 0 ? void 0 : _tableSelectorButton5.isActive,
|
|
681
|
+
selected: ((_tableSelectorButton5 = tableSelectorButton) === null || _tableSelectorButton5 === void 0 ? void 0 : _tableSelectorButton5.isActive) || isTableSelectorOpen,
|
|
625
682
|
title: (_tableSelectorButton6 = tableSelectorButton) === null || _tableSelectorButton6 === void 0 ? void 0 : _tableSelectorButton6.title,
|
|
626
683
|
"aria-label": tableSelectorButton ? tableSelectorButton['aria-label'] : undefined,
|
|
627
684
|
"aria-haspopup": tableSelectorButton ? tableSelectorButton['aria-haspopup'] : undefined,
|
|
@@ -629,7 +686,7 @@ export class ToolbarInsertBlock extends React.PureComponent {
|
|
|
629
686
|
onItemClick: this.insertToolbarMenuItem
|
|
630
687
|
})), jsx("span", {
|
|
631
688
|
css: wrapperStyle
|
|
632
|
-
}, this.renderPopup(), jsx(BlockInsertMenu, {
|
|
689
|
+
}, this.renderPopup(), this.renderTableSelectorPopup(), jsx(BlockInsertMenu, {
|
|
633
690
|
popupsMountPoint: this.props.popupsMountPoint,
|
|
634
691
|
popupsBoundariesElement: this.props.popupsBoundariesElement,
|
|
635
692
|
popupsScrollableElement: this.props.popupsScrollableElement,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { css, jsx } from '@emotion/react';
|
|
5
|
+
import { bind } from 'bind-event-listener';
|
|
6
|
+
import { Popup } from '@atlaskit/editor-common/ui';
|
|
7
|
+
import { withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react';
|
|
8
|
+
import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
|
+
import { N0, N30A, N60A } from '@atlaskit/theme/colors';
|
|
10
|
+
import tableSelectorPopup, { TABLE_SELECTOR_BUTTON_GAP, TABLE_SELECTOR_BUTTON_SIZE } from './table-selector-popup';
|
|
11
|
+
const TABLE_SELECTOR_PADDING_TOP = 8;
|
|
12
|
+
const TABLE_SELECTOR_PADDING_SIDE = 10;
|
|
13
|
+
const DEFAULT_TABLE_SELECTOR_ROWS = 5;
|
|
14
|
+
const DEFAULT_TABLE_SELECTOR_COLS = 10;
|
|
15
|
+
const DEFAULT_TABLE_SELECTOR_SELECTION_SIZE = 1;
|
|
16
|
+
const TableSelectorWithListeners = withOuterListeners(tableSelectorPopup);
|
|
17
|
+
const tableSelectorPopupWrapperStyles = css({
|
|
18
|
+
borderRadius: "var(--ds-border-radius, 3px)",
|
|
19
|
+
backgroundColor: `var(--ds-surface-overlay, ${N0})`,
|
|
20
|
+
boxShadow: `var(--ds-shadow-overlay, ${`0 0 0 1px ${N30A}, 0 2px 1px ${N30A}, 0 0 20px -6px ${N60A}`})`,
|
|
21
|
+
padding: `${`var(--ds-space-100, ${`${TABLE_SELECTOR_PADDING_TOP}px`})`} ${TABLE_SELECTOR_PADDING_SIDE}px`
|
|
22
|
+
});
|
|
23
|
+
export const TableSelectorPopup = props => {
|
|
24
|
+
const [size, setSize] = useState({
|
|
25
|
+
col: DEFAULT_TABLE_SELECTOR_SELECTION_SIZE,
|
|
26
|
+
row: DEFAULT_TABLE_SELECTOR_SELECTION_SIZE,
|
|
27
|
+
maxCol: DEFAULT_TABLE_SELECTOR_COLS,
|
|
28
|
+
maxRow: DEFAULT_TABLE_SELECTOR_ROWS
|
|
29
|
+
});
|
|
30
|
+
const tablePopupRef = useRef(null);
|
|
31
|
+
|
|
32
|
+
// Mouse move is used to allow selection changes outside of the popup and is more reactive to changes.
|
|
33
|
+
const handleMouseMove = useCallback(e => {
|
|
34
|
+
if (!tablePopupRef.current) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const tablePopup = tablePopupRef.current;
|
|
38
|
+
const {
|
|
39
|
+
left,
|
|
40
|
+
top
|
|
41
|
+
} = tablePopup.getBoundingClientRect();
|
|
42
|
+
|
|
43
|
+
// Mouse position on popup
|
|
44
|
+
const selectedWidth = e.clientX - left;
|
|
45
|
+
const selectedHeight = e.clientY - top;
|
|
46
|
+
|
|
47
|
+
// Calculate number grid cells selected
|
|
48
|
+
let selectedGridCols = Math.ceil((selectedWidth - TABLE_SELECTOR_PADDING_SIDE + TABLE_SELECTOR_BUTTON_GAP) / (TABLE_SELECTOR_BUTTON_GAP + TABLE_SELECTOR_BUTTON_SIZE));
|
|
49
|
+
let selectedGridRows = Math.ceil((selectedHeight - TABLE_SELECTOR_PADDING_TOP + TABLE_SELECTOR_BUTTON_GAP) / (TABLE_SELECTOR_BUTTON_GAP + TABLE_SELECTOR_BUTTON_SIZE));
|
|
50
|
+
|
|
51
|
+
// Keep the selected rows and columns within the defined bounds
|
|
52
|
+
if (selectedGridCols < 1) {
|
|
53
|
+
selectedGridCols = 1;
|
|
54
|
+
}
|
|
55
|
+
if (selectedGridCols > size.maxCol) {
|
|
56
|
+
selectedGridCols = size.maxCol;
|
|
57
|
+
}
|
|
58
|
+
if (selectedGridRows < 1) {
|
|
59
|
+
selectedGridRows = 1;
|
|
60
|
+
}
|
|
61
|
+
if (selectedGridRows > size.maxRow) {
|
|
62
|
+
selectedGridRows = size.maxRow;
|
|
63
|
+
}
|
|
64
|
+
if (selectedGridCols !== size.col || selectedGridRows !== size.row) {
|
|
65
|
+
setSize({
|
|
66
|
+
col: selectedGridCols,
|
|
67
|
+
row: selectedGridRows,
|
|
68
|
+
maxCol: DEFAULT_TABLE_SELECTOR_COLS,
|
|
69
|
+
maxRow: DEFAULT_TABLE_SELECTOR_ROWS
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}, [size, setSize]);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const unbind = bind(window, {
|
|
75
|
+
type: 'mousemove',
|
|
76
|
+
listener: handleMouseMove
|
|
77
|
+
});
|
|
78
|
+
return unbind;
|
|
79
|
+
}, [handleMouseMove]);
|
|
80
|
+
return jsx(Popup, {
|
|
81
|
+
target: props.target,
|
|
82
|
+
offset: [0, 3],
|
|
83
|
+
mountTo: props.popupsMountPoint,
|
|
84
|
+
boundariesElement: props.popupsBoundariesElement,
|
|
85
|
+
scrollableElement: props.popupsScrollableElement,
|
|
86
|
+
focusTrap: true,
|
|
87
|
+
zIndex: akEditorMenuZIndex
|
|
88
|
+
}, jsx("div", {
|
|
89
|
+
css: tableSelectorPopupWrapperStyles,
|
|
90
|
+
ref: tablePopupRef
|
|
91
|
+
}, jsx(TableSelectorWithListeners, {
|
|
92
|
+
handleClickOutside: props.handleClickOutside,
|
|
93
|
+
handleEscapeKeydown: props.handleEscapeKeydown,
|
|
94
|
+
maxCols: size.maxCol,
|
|
95
|
+
maxRows: size.maxRow,
|
|
96
|
+
onSelection: props.onSelection,
|
|
97
|
+
selectedCol: size.col,
|
|
98
|
+
selectedRow: size.row
|
|
99
|
+
})));
|
|
100
|
+
};
|
|
101
|
+
export default TableSelectorPopup;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { css, jsx } from '@emotion/react';
|
|
4
|
+
import { injectIntl } from 'react-intl-next';
|
|
5
|
+
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { Stack } from '@atlaskit/primitives';
|
|
7
|
+
export const TABLE_SELECTOR_BUTTON_GAP = 2;
|
|
8
|
+
export const TABLE_SELECTOR_BUTTON_SIZE = 17;
|
|
9
|
+
const selectedButtonStyles = css({
|
|
10
|
+
backgroundColor: "var(--ds-background-accent-blue-subtlest, #579DFF)",
|
|
11
|
+
border: `1px solid ${"var(--ds-background-accent-blue-subtle, #579DFF)"}`
|
|
12
|
+
});
|
|
13
|
+
const buttonStyles = css({
|
|
14
|
+
height: `${TABLE_SELECTOR_BUTTON_SIZE}px`,
|
|
15
|
+
width: `${TABLE_SELECTOR_BUTTON_SIZE}px`,
|
|
16
|
+
border: `1px solid ${"var(--ds-border, #091e4224)"}`,
|
|
17
|
+
backgroundColor: "var(--ds-background-input, #ffffff)",
|
|
18
|
+
borderRadius: '3px',
|
|
19
|
+
cursor: 'pointer',
|
|
20
|
+
display: 'block',
|
|
21
|
+
'&:hover': {
|
|
22
|
+
backgroundColor: "var(--ds-background-accent-blue-subtlest, #579DFF)",
|
|
23
|
+
border: `1px solid ${"var(--ds-background-accent-blue-subtle, #579DFF)"}`
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const selectionSizeTextStyles = css({
|
|
27
|
+
lineHeight: '14px',
|
|
28
|
+
display: 'flex',
|
|
29
|
+
justifyContent: 'center',
|
|
30
|
+
marginTop: "var(--ds-space-075, 5px)",
|
|
31
|
+
padding: "var(--ds-space-075, 10px)"
|
|
32
|
+
});
|
|
33
|
+
const TableSelectorButton = ({
|
|
34
|
+
row,
|
|
35
|
+
col,
|
|
36
|
+
isActive,
|
|
37
|
+
onClick,
|
|
38
|
+
label
|
|
39
|
+
}) => {
|
|
40
|
+
return jsx("button", {
|
|
41
|
+
css: [buttonStyles, isActive ? selectedButtonStyles : undefined],
|
|
42
|
+
onClick: () => onClick(row, col),
|
|
43
|
+
"aria-label": label
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const createArray = (maxCols, maxRows) => {
|
|
47
|
+
const arr = [];
|
|
48
|
+
for (let i = 1; i < maxRows + 1; i++) {
|
|
49
|
+
for (let j = 1; j < maxCols + 1; j++) {
|
|
50
|
+
arr.push({
|
|
51
|
+
col: j,
|
|
52
|
+
row: i
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return arr;
|
|
57
|
+
};
|
|
58
|
+
const gridWrapperStyles = ({
|
|
59
|
+
maxCols,
|
|
60
|
+
maxRows
|
|
61
|
+
}) => css({
|
|
62
|
+
display: 'grid',
|
|
63
|
+
gridTemplateColumns: `repeat(${maxCols}, 1fr)`,
|
|
64
|
+
gridTemplateRows: `repeat(${maxRows}, 1fr)`,
|
|
65
|
+
gap: `${`var(--ds-space-025, ${`${TABLE_SELECTOR_BUTTON_GAP}px`})`}`
|
|
66
|
+
});
|
|
67
|
+
const TableSelectorPopup = ({
|
|
68
|
+
maxCols,
|
|
69
|
+
maxRows,
|
|
70
|
+
onSelection,
|
|
71
|
+
selectedCol,
|
|
72
|
+
selectedRow,
|
|
73
|
+
intl
|
|
74
|
+
}) => {
|
|
75
|
+
const buttons = useMemo(() => {
|
|
76
|
+
return createArray(maxCols, maxRows);
|
|
77
|
+
}, [maxCols, maxRows]);
|
|
78
|
+
return jsx(Stack, null, jsx("div", {
|
|
79
|
+
css:
|
|
80
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
81
|
+
gridWrapperStyles({
|
|
82
|
+
maxCols: maxCols,
|
|
83
|
+
maxRows: maxRows
|
|
84
|
+
})
|
|
85
|
+
}, buttons.map(({
|
|
86
|
+
col,
|
|
87
|
+
row
|
|
88
|
+
}, index) => {
|
|
89
|
+
const isActive = selectedCol >= col && selectedRow >= row ? true : false;
|
|
90
|
+
return jsx(TableSelectorButton, {
|
|
91
|
+
key: index,
|
|
92
|
+
isActive: isActive,
|
|
93
|
+
col: col,
|
|
94
|
+
row: row,
|
|
95
|
+
onClick: onSelection,
|
|
96
|
+
label: `${intl.formatMessage(messages.tableSizeSelectorButton)} ${row} x ${col}`
|
|
97
|
+
});
|
|
98
|
+
})), jsx("span", {
|
|
99
|
+
css: selectionSizeTextStyles
|
|
100
|
+
}, `${selectedRow} x ${selectedCol}`));
|
|
101
|
+
};
|
|
102
|
+
export default injectIntl(TableSelectorPopup);
|