@atlaskit/editor-plugin-find-replace 0.2.0 → 0.3.1
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 +13 -0
- package/dist/cjs/styles.js +16 -3
- package/dist/cjs/ui/Find.js +108 -103
- package/dist/cjs/ui/FindReplace.js +68 -9
- package/dist/cjs/ui/FindReplaceToolbarButton.js +33 -11
- package/dist/cjs/ui/FindReplaceTooltipButton.js +6 -3
- package/dist/cjs/ui/Replace.js +168 -26
- package/dist/cjs/ui/styles.js +30 -4
- package/dist/es2019/styles.js +17 -10
- package/dist/es2019/ui/Find.js +102 -97
- package/dist/es2019/ui/FindReplace.js +61 -7
- package/dist/es2019/ui/FindReplaceToolbarButton.js +33 -11
- package/dist/es2019/ui/FindReplaceTooltipButton.js +6 -3
- package/dist/es2019/ui/Replace.js +162 -25
- package/dist/es2019/ui/styles.js +67 -3
- package/dist/esm/styles.js +17 -4
- package/dist/esm/ui/Find.js +103 -98
- package/dist/esm/ui/FindReplace.js +69 -10
- package/dist/esm/ui/FindReplaceToolbarButton.js +33 -11
- package/dist/esm/ui/FindReplaceTooltipButton.js +6 -3
- package/dist/esm/ui/Replace.js +164 -25
- package/dist/esm/ui/styles.js +32 -4
- package/dist/types/ui/Find.d.ts +6 -0
- package/dist/types/ui/FindReplace.d.ts +10 -0
- package/dist/types/ui/FindReplaceTooltipButton.d.ts +2 -0
- package/dist/types/ui/Replace.d.ts +19 -0
- package/dist/types/ui/styles.d.ts +10 -0
- package/dist/types-ts4.5/ui/Find.d.ts +6 -0
- package/dist/types-ts4.5/ui/FindReplace.d.ts +10 -0
- package/dist/types-ts4.5/ui/FindReplaceTooltipButton.d.ts +2 -0
- package/dist/types-ts4.5/ui/Replace.d.ts +19 -0
- package/dist/types-ts4.5/ui/styles.d.ts +10 -0
- package/package.json +7 -4
|
@@ -4,15 +4,45 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
4
4
|
/** @jsx jsx */
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { jsx } from '@emotion/react';
|
|
7
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import Find from './Find';
|
|
8
9
|
import Replace from './Replace';
|
|
9
|
-
import { ruleStyles, wrapperStyles } from './styles';
|
|
10
|
+
import { ruleStyles, wrapperPaddingStyles, wrapperStyles } from './styles';
|
|
10
11
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
11
12
|
class FindReplace extends React.PureComponent {
|
|
12
|
-
constructor(
|
|
13
|
-
super(
|
|
13
|
+
constructor(props) {
|
|
14
|
+
super(props);
|
|
14
15
|
_defineProperty(this, "findTextfield", null);
|
|
15
16
|
_defineProperty(this, "replaceTextfield", null);
|
|
17
|
+
_defineProperty(this, "handleTabNavigation", event => {
|
|
18
|
+
if (event.key === 'Tab') {
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
const modalFindReplace = this.modalRef.current;
|
|
21
|
+
if (!modalFindReplace || !modalFindReplace.contains(document.activeElement)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const focusableElements = Array.from(modalFindReplace.querySelectorAll('[tabindex]:not([tabindex="-1"]), input, button')).filter(el => el.getAttribute('tabindex') !== '-1');
|
|
25
|
+
const currentIndex = focusableElements.findIndex(el => el === document.activeElement);
|
|
26
|
+
const isShiftPressed = event.shiftKey;
|
|
27
|
+
if (isShiftPressed) {
|
|
28
|
+
const prevIndex = (currentIndex - 1 + focusableElements.length) % focusableElements.length;
|
|
29
|
+
focusableElements[prevIndex].focus();
|
|
30
|
+
} else {
|
|
31
|
+
const nextIndex = (currentIndex + 1) % focusableElements.length;
|
|
32
|
+
focusableElements[nextIndex].focus();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
_defineProperty(this, "state", {
|
|
37
|
+
findTyped: false
|
|
38
|
+
});
|
|
39
|
+
_defineProperty(this, "setFindTyped", value => {
|
|
40
|
+
if (getBooleanFF('platform.editor.a11y-find-replace')) {
|
|
41
|
+
this.setState({
|
|
42
|
+
findTyped: value
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
16
46
|
_defineProperty(this, "setFindTextfieldRef", findTextfieldRef => {
|
|
17
47
|
this.findTextfield = findTextfieldRef.current;
|
|
18
48
|
});
|
|
@@ -29,6 +59,19 @@ class FindReplace extends React.PureComponent {
|
|
|
29
59
|
this.replaceTextfield.focus();
|
|
30
60
|
}
|
|
31
61
|
});
|
|
62
|
+
this.modalRef = /*#__PURE__*/React.createRef();
|
|
63
|
+
}
|
|
64
|
+
componentDidMount() {
|
|
65
|
+
if (getBooleanFF('platform.editor.a11y-find-replace')) {
|
|
66
|
+
// eslint-disable-next-line
|
|
67
|
+
window.addEventListener('keydown', this.handleTabNavigation);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
componentWillUnmount() {
|
|
71
|
+
if (getBooleanFF('platform.editor.a11y-find-replace')) {
|
|
72
|
+
// eslint-disable-next-line
|
|
73
|
+
window.removeEventListener('keydown', this.handleTabNavigation);
|
|
74
|
+
}
|
|
32
75
|
}
|
|
33
76
|
render() {
|
|
34
77
|
const {
|
|
@@ -48,8 +91,10 @@ class FindReplace extends React.PureComponent {
|
|
|
48
91
|
shouldMatchCase,
|
|
49
92
|
onToggleMatchCase
|
|
50
93
|
} = this.props;
|
|
94
|
+
const focusToolbarButton = getBooleanFF('platform.editor.a11y-find-replace') ? this.props.focusToolbarButton || (() => {}) : () => {};
|
|
51
95
|
return jsx("div", {
|
|
52
|
-
|
|
96
|
+
ref: this.modalRef,
|
|
97
|
+
css: getBooleanFF('platform.editor.a11y-find-replace') ? [wrapperStyles, wrapperPaddingStyles] : wrapperStyles
|
|
53
98
|
}, jsx(Find, {
|
|
54
99
|
allowMatchCase: allowMatchCase,
|
|
55
100
|
shouldMatchCase: shouldMatchCase,
|
|
@@ -63,8 +108,10 @@ class FindReplace extends React.PureComponent {
|
|
|
63
108
|
onFindNext: onFindNext,
|
|
64
109
|
onFindTextfieldRefSet: this.setFindTextfieldRef,
|
|
65
110
|
onCancel: onCancel,
|
|
66
|
-
onArrowDown: this.setFocusToReplace
|
|
67
|
-
|
|
111
|
+
onArrowDown: this.setFocusToReplace,
|
|
112
|
+
findTyped: this.state.findTyped,
|
|
113
|
+
setFindTyped: this.setFindTyped
|
|
114
|
+
}), !getBooleanFF('platform.editor.a11y-find-replace') && jsx("hr", {
|
|
68
115
|
css: ruleStyles,
|
|
69
116
|
id: "replace-hr-element"
|
|
70
117
|
}), jsx(Replace, {
|
|
@@ -74,7 +121,14 @@ class FindReplace extends React.PureComponent {
|
|
|
74
121
|
onReplaceAll: onReplaceAll,
|
|
75
122
|
onReplaceTextfieldRefSet: this.setReplaceTextfieldRef,
|
|
76
123
|
onArrowUp: this.setFocusToFind,
|
|
77
|
-
|
|
124
|
+
onCancel: onCancel,
|
|
125
|
+
count: count,
|
|
126
|
+
onFindPrev: onFindPrev,
|
|
127
|
+
onFindNext: onFindNext,
|
|
128
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
129
|
+
findTyped: this.state.findTyped,
|
|
130
|
+
setFindTyped: this.setFindTyped,
|
|
131
|
+
focusToolbarButton: focusToolbarButton
|
|
78
132
|
}));
|
|
79
133
|
}
|
|
80
134
|
}
|
|
@@ -4,12 +4,14 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
4
4
|
/** @jsx jsx */
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { css, jsx } from '@emotion/react';
|
|
7
|
-
import {
|
|
7
|
+
import { injectIntl } from 'react-intl-next';
|
|
8
8
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
9
9
|
import { findKeymapByDescription, getAriaKeyshortcuts, tooltip, ToolTipContent } from '@atlaskit/editor-common/keymaps';
|
|
10
|
+
import { findReplaceMessages as messages } from '@atlaskit/editor-common/messages';
|
|
10
11
|
import { ArrowKeyNavigationType, Dropdown, TOOLBAR_BUTTON, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
11
12
|
import { akEditorFloatingPanelZIndex, akEditorMobileMaxWidth } from '@atlaskit/editor-shared-styles';
|
|
12
13
|
import EditorSearchIcon from '@atlaskit/icon/glyph/editor/search';
|
|
14
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
13
15
|
import FindReplace from './FindReplace';
|
|
14
16
|
const toolbarButtonWrapper = css`
|
|
15
17
|
display: flex;
|
|
@@ -30,26 +32,36 @@ const wrapper = css`
|
|
|
30
32
|
display: flex;
|
|
31
33
|
flex-direction: column;
|
|
32
34
|
`;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
id: 'fabric.editor.findReplaceToolbarButton',
|
|
36
|
-
defaultMessage: 'Find and replace',
|
|
37
|
-
description: '"Find" highlights all instances of a word or phrase on the document, and "Replace" changes one or all of those instances to something else'
|
|
38
|
-
}
|
|
39
|
-
});
|
|
35
|
+
const dropdownWidthNewDesign = 382;
|
|
36
|
+
const dropdownWidthOldDesign = 352;
|
|
40
37
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
41
38
|
class FindReplaceToolbarButton extends React.PureComponent {
|
|
42
39
|
constructor(...args) {
|
|
43
40
|
super(...args);
|
|
41
|
+
_defineProperty(this, "state", {
|
|
42
|
+
openedByClick: false
|
|
43
|
+
});
|
|
44
44
|
_defineProperty(this, "toggleOpen", () => {
|
|
45
45
|
if (this.props.isActive) {
|
|
46
46
|
this.props.onCancel({
|
|
47
47
|
triggerMethod: TRIGGER_METHOD.TOOLBAR
|
|
48
48
|
});
|
|
49
49
|
} else {
|
|
50
|
+
this.setState({
|
|
51
|
+
openedByClick: true
|
|
52
|
+
});
|
|
50
53
|
this.props.onActivate();
|
|
51
54
|
}
|
|
52
55
|
});
|
|
56
|
+
_defineProperty(this, "focusToolbarButton", () => {
|
|
57
|
+
if (this.state.openedByClick && this.toolbarButtonRef.current) {
|
|
58
|
+
this.toolbarButtonRef.current.focus();
|
|
59
|
+
}
|
|
60
|
+
this.setState({
|
|
61
|
+
openedByClick: false
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
_defineProperty(this, "toolbarButtonRef", /*#__PURE__*/React.createRef());
|
|
53
65
|
}
|
|
54
66
|
render() {
|
|
55
67
|
const {
|
|
@@ -82,9 +94,17 @@ class FindReplaceToolbarButton extends React.PureComponent {
|
|
|
82
94
|
this.props.onCancel({
|
|
83
95
|
triggerMethod: TRIGGER_METHOD.KEYBOARD
|
|
84
96
|
});
|
|
97
|
+
if (getBooleanFF('platform.editor.a11y-find-replace')) {
|
|
98
|
+
if (this.state.openedByClick && this.toolbarButtonRef.current) {
|
|
99
|
+
this.toolbarButtonRef.current.focus();
|
|
100
|
+
}
|
|
101
|
+
this.setState({
|
|
102
|
+
openedByClick: false
|
|
103
|
+
});
|
|
104
|
+
}
|
|
85
105
|
}
|
|
86
106
|
},
|
|
87
|
-
fitWidth:
|
|
107
|
+
fitWidth: getBooleanFF('platform.editor.a11y-find-replace') ? dropdownWidthNewDesign : dropdownWidthOldDesign,
|
|
88
108
|
zIndex: stackBelowOtherEditorFloatingPanels,
|
|
89
109
|
arrowKeyNavigationProviderOptions: {
|
|
90
110
|
type: ArrowKeyNavigationType.MENU,
|
|
@@ -105,7 +125,8 @@ class FindReplaceToolbarButton extends React.PureComponent {
|
|
|
105
125
|
"aria-expanded": isActive,
|
|
106
126
|
"aria-haspopup": true,
|
|
107
127
|
"aria-label": keymap ? tooltip(keymap, title) : title,
|
|
108
|
-
"aria-keyshortcuts": getAriaKeyshortcuts(keymap)
|
|
128
|
+
"aria-keyshortcuts": getAriaKeyshortcuts(keymap),
|
|
129
|
+
ref: getBooleanFF('platform.editor.a11y-find-replace') ? this.toolbarButtonRef : null
|
|
109
130
|
})
|
|
110
131
|
}, jsx("div", {
|
|
111
132
|
css: wrapper
|
|
@@ -115,7 +136,8 @@ class FindReplaceToolbarButton extends React.PureComponent {
|
|
|
115
136
|
count: {
|
|
116
137
|
index,
|
|
117
138
|
total: numMatches
|
|
118
|
-
}
|
|
139
|
+
},
|
|
140
|
+
focusToolbarButton: this.focusToolbarButton
|
|
119
141
|
}, this.props)))));
|
|
120
142
|
}
|
|
121
143
|
}
|
|
@@ -19,7 +19,8 @@ export class FindReplaceTooltipButton extends React.PureComponent {
|
|
|
19
19
|
icon,
|
|
20
20
|
keymapDescription,
|
|
21
21
|
disabled,
|
|
22
|
-
isPressed
|
|
22
|
+
isPressed,
|
|
23
|
+
appearance
|
|
23
24
|
} = this.props;
|
|
24
25
|
const pressedProps = {
|
|
25
26
|
...(typeof isPressed === 'boolean' && {
|
|
@@ -34,8 +35,9 @@ export class FindReplaceTooltipButton extends React.PureComponent {
|
|
|
34
35
|
hideTooltipOnClick: true,
|
|
35
36
|
position: 'top'
|
|
36
37
|
}, /*#__PURE__*/React.createElement(Button, _extends({
|
|
38
|
+
id: "afterInputSection",
|
|
37
39
|
label: title,
|
|
38
|
-
appearance:
|
|
40
|
+
appearance: appearance,
|
|
39
41
|
testId: title,
|
|
40
42
|
ref: this.buttonRef,
|
|
41
43
|
iconBefore: icon,
|
|
@@ -47,5 +49,6 @@ export class FindReplaceTooltipButton extends React.PureComponent {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
_defineProperty(FindReplaceTooltipButton, "defaultProps", {
|
|
50
|
-
keymapDescription: 'no-keymap'
|
|
52
|
+
keymapDescription: 'no-keymap',
|
|
53
|
+
appearance: 'subtle'
|
|
51
54
|
});
|
|
@@ -1,36 +1,26 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
/* eslint-disable @atlaskit/design-system/consistent-css-prop-usage */
|
|
3
3
|
/** @jsx jsx */
|
|
4
|
-
import React from 'react';
|
|
4
|
+
import React, { Fragment } from 'react';
|
|
5
5
|
import { jsx } from '@emotion/react';
|
|
6
|
-
import {
|
|
6
|
+
import { injectIntl } from 'react-intl-next';
|
|
7
7
|
import Button from '@atlaskit/button/standard-button';
|
|
8
8
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
9
|
+
import { findReplaceMessages as messages } from '@atlaskit/editor-common/messages';
|
|
10
|
+
import { Label, ValidMessage } from '@atlaskit/form';
|
|
11
|
+
import ChevronDownIcon from '@atlaskit/icon/glyph/hipchat/chevron-down';
|
|
12
|
+
import ChevronUpIcon from '@atlaskit/icon/glyph/hipchat/chevron-up';
|
|
13
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
9
14
|
import Textfield from '@atlaskit/textfield';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
replaceWith: {
|
|
13
|
-
id: 'fabric.editor.replaceWith',
|
|
14
|
-
defaultMessage: 'Replace with',
|
|
15
|
-
description: 'The value that will replace the word or phrase that was searched for'
|
|
16
|
-
},
|
|
17
|
-
replace: {
|
|
18
|
-
id: 'fabric.editor.replace',
|
|
19
|
-
defaultMessage: 'Replace',
|
|
20
|
-
description: 'Replace only the currently selected instance of the word or phrase'
|
|
21
|
-
},
|
|
22
|
-
replaceAll: {
|
|
23
|
-
id: 'fabric.editor.replaceAll',
|
|
24
|
-
defaultMessage: 'Replace all',
|
|
25
|
-
description: 'Replace all instances of the word or phrase throughout the entire document'
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
15
|
+
import { FindReplaceTooltipButton } from './FindReplaceTooltipButton';
|
|
16
|
+
import { NextPreviousItem, orderOneStyles, orderZeroStyles, replaceSectionButtonStyles, sectionWrapperJustified, sectionWrapperStyles, sectionWrapperStylesAlternate, textFieldWrapper } from './styles';
|
|
29
17
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
30
18
|
class Replace extends React.PureComponent {
|
|
31
19
|
constructor(props) {
|
|
32
20
|
super(props);
|
|
33
21
|
_defineProperty(this, "replaceTextfieldRef", /*#__PURE__*/React.createRef());
|
|
22
|
+
_defineProperty(this, "successReplacementMessageRef", /*#__PURE__*/React.createRef());
|
|
23
|
+
_defineProperty(this, "isComposing", false);
|
|
34
24
|
_defineProperty(this, "skipWhileComposing", fn => {
|
|
35
25
|
if (this.state.isComposing) {
|
|
36
26
|
return;
|
|
@@ -42,6 +32,14 @@ class Replace extends React.PureComponent {
|
|
|
42
32
|
triggerMethod: TRIGGER_METHOD.BUTTON,
|
|
43
33
|
replaceText: this.state.replaceText
|
|
44
34
|
});
|
|
35
|
+
// for replace button replaceCount always 1;
|
|
36
|
+
const replaceCount = 1;
|
|
37
|
+
this.triggerSuccessReplacementMessageUpdate(replaceCount);
|
|
38
|
+
this.setState({
|
|
39
|
+
isHelperMessageVisible: true,
|
|
40
|
+
replaceCount
|
|
41
|
+
});
|
|
42
|
+
this.props.setFindTyped(false);
|
|
45
43
|
}));
|
|
46
44
|
_defineProperty(this, "handleReplaceChange", event => this.skipWhileComposing(() => {
|
|
47
45
|
this.updateReplaceValue(event.target.value);
|
|
@@ -76,6 +74,14 @@ class Replace extends React.PureComponent {
|
|
|
76
74
|
this.props.onReplaceAll({
|
|
77
75
|
replaceText: this.state.replaceText
|
|
78
76
|
});
|
|
77
|
+
this.setState({
|
|
78
|
+
isHelperMessageVisible: true
|
|
79
|
+
});
|
|
80
|
+
this.triggerSuccessReplacementMessageUpdate(this.props.count.total);
|
|
81
|
+
this.setState({
|
|
82
|
+
replaceCount: this.props.count.total
|
|
83
|
+
});
|
|
84
|
+
this.props.setFindTyped(false);
|
|
79
85
|
}));
|
|
80
86
|
_defineProperty(this, "handleCompositionStart", () => {
|
|
81
87
|
this.setState({
|
|
@@ -89,6 +95,28 @@ class Replace extends React.PureComponent {
|
|
|
89
95
|
// type for React.CompositionEvent doesn't set type for target correctly
|
|
90
96
|
this.updateReplaceValue(event.target.value);
|
|
91
97
|
});
|
|
98
|
+
_defineProperty(this, "clearSearch", () => {
|
|
99
|
+
this.props.onCancel({
|
|
100
|
+
triggerMethod: TRIGGER_METHOD.BUTTON
|
|
101
|
+
});
|
|
102
|
+
this.props.focusToolbarButton && this.props.focusToolbarButton();
|
|
103
|
+
});
|
|
104
|
+
_defineProperty(this, "handleFindNextClick", () => {
|
|
105
|
+
if (this.isComposing) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.props.onFindNext({
|
|
109
|
+
triggerMethod: TRIGGER_METHOD.BUTTON
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
_defineProperty(this, "handleFindPrevClick", () => {
|
|
113
|
+
if (this.isComposing) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.props.onFindPrev({
|
|
117
|
+
triggerMethod: TRIGGER_METHOD.BUTTON
|
|
118
|
+
});
|
|
119
|
+
});
|
|
92
120
|
const {
|
|
93
121
|
replaceText: _replaceText,
|
|
94
122
|
intl: {
|
|
@@ -97,11 +125,23 @@ class Replace extends React.PureComponent {
|
|
|
97
125
|
} = props;
|
|
98
126
|
this.state = {
|
|
99
127
|
replaceText: _replaceText || '',
|
|
100
|
-
isComposing: false
|
|
128
|
+
isComposing: false,
|
|
129
|
+
isHelperMessageVisible: false,
|
|
130
|
+
fakeSuccessReplacementMessageUpdate: false,
|
|
131
|
+
replaceCount: 0
|
|
101
132
|
};
|
|
102
133
|
this.replaceWith = formatMessage(messages.replaceWith);
|
|
103
134
|
this.replace = formatMessage(messages.replace);
|
|
104
135
|
this.replaceAll = formatMessage(messages.replaceAll);
|
|
136
|
+
this.findNext = formatMessage(messages.findNext);
|
|
137
|
+
this.findPrevious = formatMessage(messages.findPrevious);
|
|
138
|
+
this.findNextIcon = jsx(ChevronDownIcon, {
|
|
139
|
+
label: this.findNext
|
|
140
|
+
});
|
|
141
|
+
this.findPrevIcon = jsx(ChevronUpIcon, {
|
|
142
|
+
label: this.findPrevious
|
|
143
|
+
});
|
|
144
|
+
this.closeFindReplaceDialog = formatMessage(messages.closeFindReplaceDialog);
|
|
105
145
|
}
|
|
106
146
|
componentDidMount() {
|
|
107
147
|
this.props.onReplaceTextfieldRefSet(this.replaceTextfieldRef);
|
|
@@ -118,15 +158,112 @@ class Replace extends React.PureComponent {
|
|
|
118
158
|
isComposing: false
|
|
119
159
|
});
|
|
120
160
|
}
|
|
161
|
+
if (getBooleanFF('platform.editor.a11y-find-replace')) {
|
|
162
|
+
const findTextField = document.getElementById('find-text-field');
|
|
163
|
+
const replaceButton = document.getElementById('replace-button');
|
|
164
|
+
const replaceAllButton = document.getElementById('replaceAll-button');
|
|
165
|
+
if (((replaceButton === null || replaceButton === void 0 ? void 0 : replaceButton.tabIndex) === -1 || (replaceAllButton === null || replaceAllButton === void 0 ? void 0 : replaceAllButton.tabIndex) === -1) && findTextField) {
|
|
166
|
+
findTextField.focus();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
triggerSuccessReplacementMessageUpdate(currentReplaceCount) {
|
|
171
|
+
var _this$state;
|
|
172
|
+
if (((_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.replaceCount) === currentReplaceCount) {
|
|
173
|
+
this.setState({
|
|
174
|
+
fakeSuccessReplacementMessageUpdate: !this.state.fakeSuccessReplacementMessageUpdate
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (this.successReplacementMessageRef && this.successReplacementMessageRef.current) {
|
|
178
|
+
const ariaLiveRegion = this.successReplacementMessageRef.current.querySelector('[aria-live="polite"]');
|
|
179
|
+
ariaLiveRegion === null || ariaLiveRegion === void 0 ? void 0 : ariaLiveRegion.removeAttribute('aria-live');
|
|
180
|
+
ariaLiveRegion === null || ariaLiveRegion === void 0 ? void 0 : ariaLiveRegion.setAttribute('aria-live', 'polite');
|
|
181
|
+
}
|
|
121
182
|
}
|
|
122
183
|
render() {
|
|
123
184
|
const {
|
|
124
|
-
replaceText
|
|
185
|
+
replaceText,
|
|
186
|
+
isHelperMessageVisible,
|
|
187
|
+
replaceCount
|
|
125
188
|
} = this.state;
|
|
126
189
|
const {
|
|
127
|
-
canReplace
|
|
190
|
+
canReplace,
|
|
191
|
+
count,
|
|
192
|
+
intl: {
|
|
193
|
+
formatMessage
|
|
194
|
+
}
|
|
128
195
|
} = this.props;
|
|
129
|
-
|
|
196
|
+
const resultsReplace = formatMessage(messages.replaceSuccess, {
|
|
197
|
+
numberOfMatches: replaceCount,
|
|
198
|
+
matchPluralSingularNoun: replaceCount > 1 ? formatMessage(messages.matchPluralNoun) : formatMessage(messages.matchSingularNoun)
|
|
199
|
+
});
|
|
200
|
+
return getBooleanFF('platform.editor.a11y-find-replace') ? jsx(Fragment, null, jsx("div", {
|
|
201
|
+
css: [sectionWrapperStyles, sectionWrapperStylesAlternate]
|
|
202
|
+
}, jsx("div", {
|
|
203
|
+
css: textFieldWrapper
|
|
204
|
+
}, jsx(Label, {
|
|
205
|
+
htmlFor: "replace-text-field"
|
|
206
|
+
}, "Replace with"), jsx(Textfield, {
|
|
207
|
+
name: "replace",
|
|
208
|
+
id: "replace-text-field",
|
|
209
|
+
appearance: "standard",
|
|
210
|
+
defaultValue: replaceText,
|
|
211
|
+
ref: this.replaceTextfieldRef,
|
|
212
|
+
autoComplete: "off",
|
|
213
|
+
onChange: this.handleReplaceChange,
|
|
214
|
+
onKeyDown: this.handleReplaceKeyDown,
|
|
215
|
+
onCompositionStart: this.handleCompositionStart,
|
|
216
|
+
onCompositionEnd: this.handleCompositionEnd
|
|
217
|
+
}), isHelperMessageVisible && this.props.findTyped === false && jsx("div", {
|
|
218
|
+
ref: this.successReplacementMessageRef
|
|
219
|
+
}, jsx(ValidMessage, {
|
|
220
|
+
testId: "message-success-replacement"
|
|
221
|
+
},
|
|
222
|
+
/*
|
|
223
|
+
Replacement needed to trigger the SR announcement if message hasn't changed. e.g Replace button clicked twice.
|
|
224
|
+
'\u00a0' is value for  
|
|
225
|
+
*/
|
|
226
|
+
this.state.fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(/ /, '\u00a0') : resultsReplace)))), jsx("div", {
|
|
227
|
+
css: [sectionWrapperStyles, sectionWrapperStylesAlternate, sectionWrapperJustified]
|
|
228
|
+
}, jsx("div", {
|
|
229
|
+
css: orderOneStyles
|
|
230
|
+
}, jsx("div", {
|
|
231
|
+
css: NextPreviousItem
|
|
232
|
+
}, jsx(FindReplaceTooltipButton, {
|
|
233
|
+
title: this.findNext,
|
|
234
|
+
icon: this.findNextIcon,
|
|
235
|
+
keymapDescription: 'Enter',
|
|
236
|
+
onClick: this.handleFindNextClick,
|
|
237
|
+
disabled: count.total <= 1
|
|
238
|
+
})), jsx("div", {
|
|
239
|
+
css: NextPreviousItem
|
|
240
|
+
}, jsx(FindReplaceTooltipButton, {
|
|
241
|
+
title: this.findPrevious,
|
|
242
|
+
icon: this.findPrevIcon,
|
|
243
|
+
keymapDescription: 'Shift Enter',
|
|
244
|
+
onClick: this.handleFindPrevClick,
|
|
245
|
+
disabled: count.total <= 1
|
|
246
|
+
})), jsx(Button, {
|
|
247
|
+
css: replaceSectionButtonStyles,
|
|
248
|
+
testId: this.replace,
|
|
249
|
+
id: "replace-button",
|
|
250
|
+
onClick: this.handleReplaceClick,
|
|
251
|
+
isDisabled: !canReplace
|
|
252
|
+
}, this.replace), jsx(Button, {
|
|
253
|
+
css: replaceSectionButtonStyles,
|
|
254
|
+
appearance: "primary",
|
|
255
|
+
testId: this.replaceAll,
|
|
256
|
+
id: "replaceAll-button",
|
|
257
|
+
onClick: this.handleReplaceAllClick,
|
|
258
|
+
isDisabled: !canReplace
|
|
259
|
+
}, this.replaceAll)), jsx("div", {
|
|
260
|
+
css: orderZeroStyles
|
|
261
|
+
}, jsx(Button, {
|
|
262
|
+
css: replaceSectionButtonStyles,
|
|
263
|
+
appearance: "subtle",
|
|
264
|
+
testId: this.closeFindReplaceDialog,
|
|
265
|
+
onClick: this.clearSearch
|
|
266
|
+
}, this.closeFindReplaceDialog)))) : jsx("div", {
|
|
130
267
|
css: sectionWrapperStyles
|
|
131
268
|
}, jsx(Textfield, {
|
|
132
269
|
name: "replace",
|
package/dist/es2019/ui/styles.js
CHANGED
|
@@ -3,8 +3,17 @@
|
|
|
3
3
|
/** @jsx jsx */
|
|
4
4
|
import { css } from '@emotion/react';
|
|
5
5
|
import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
7
|
+
import { N30A } from '@atlaskit/theme/colors';
|
|
8
|
+
import { fontSize as getFontSize,
|
|
9
|
+
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
10
|
+
gridSize as getGridSize } from '@atlaskit/theme/constants';
|
|
11
|
+
const fontSize = getFontSize();
|
|
12
|
+
const gridSize = getGridSize();
|
|
13
|
+
export const replaceSectionButtonStyles = getBooleanFF('platform.editor.a11y-find-replace') ? css({
|
|
14
|
+
marginLeft: "var(--ds-space-050, 4px)",
|
|
15
|
+
marginRight: "var(--ds-space-050, 2px)"
|
|
16
|
+
}) : css({
|
|
8
17
|
marginLeft: "var(--ds-space-050, 4px)"
|
|
9
18
|
});
|
|
10
19
|
export const ruleStyles = css({
|
|
@@ -22,6 +31,9 @@ export const wrapperStyles = css({
|
|
|
22
31
|
margin: `0px ${"var(--ds-space-050, 4px)"}`
|
|
23
32
|
}
|
|
24
33
|
});
|
|
34
|
+
export const wrapperPaddingStyles = css({
|
|
35
|
+
padding: `${"var(--ds-space-050, 4px)"} ${"var(--ds-space-050, 4px)"}`
|
|
36
|
+
});
|
|
25
37
|
export const sectionWrapperStyles = css`
|
|
26
38
|
display: flex;
|
|
27
39
|
|
|
@@ -36,8 +48,50 @@ export const sectionWrapperStyles = css`
|
|
|
36
48
|
flex: 1 1 auto;
|
|
37
49
|
}
|
|
38
50
|
`;
|
|
51
|
+
export const sectionWrapperStylesAlternate = css`
|
|
52
|
+
display: flex;
|
|
53
|
+
padding: ${"var(--ds-space-100, 8px)"};
|
|
54
|
+
|
|
55
|
+
& > * {
|
|
56
|
+
height: unset;
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
export const sectionWrapperJustified = css`
|
|
60
|
+
justify-content: space-between;
|
|
61
|
+
font-size: ${relativeFontSizeToBase16(14)};
|
|
62
|
+
`;
|
|
63
|
+
export const textFieldWrapper = css`
|
|
64
|
+
flex: 1 100%;
|
|
65
|
+
flex-wrap: wrap;
|
|
66
|
+
|
|
67
|
+
#find-text-field,
|
|
68
|
+
#replace-text-field {
|
|
69
|
+
height: ${gridSize * 4.5 / fontSize}em;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
label {
|
|
73
|
+
font-size: ${relativeFontSizeToBase16(14)};
|
|
74
|
+
line-height: ${gridSize * 2}px;
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
export const afterInputSection = css`
|
|
78
|
+
display: flex;
|
|
79
|
+
flex: 0 0 auto;
|
|
80
|
+
align-items: center;
|
|
81
|
+
`;
|
|
82
|
+
export const matchCaseSection = css`
|
|
83
|
+
padding-right: ${"var(--ds-space-100, 8px)"};
|
|
84
|
+
|
|
85
|
+
button {
|
|
86
|
+
width: 20px;
|
|
87
|
+
height: 20px;
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
90
|
+
export const NextPreviousItem = css`
|
|
91
|
+
padding: 0px 3px;
|
|
92
|
+
`;
|
|
39
93
|
export const countStyles = css({
|
|
40
|
-
color: `${
|
|
94
|
+
color: `${"var(--ds-text-subtlest, #626F86)"}`,
|
|
41
95
|
fontSize: `${relativeFontSizeToBase16(12)}`,
|
|
42
96
|
flex: '0 0 auto',
|
|
43
97
|
justifyContent: 'center',
|
|
@@ -45,6 +99,16 @@ export const countStyles = css({
|
|
|
45
99
|
marginLeft: "var(--ds-space-050, 4px)",
|
|
46
100
|
marginRight: "var(--ds-space-100, 8px)"
|
|
47
101
|
});
|
|
102
|
+
export const countStylesAlternateStyles = css({
|
|
103
|
+
display: 'inline-flex',
|
|
104
|
+
height: '32px'
|
|
105
|
+
});
|
|
48
106
|
export const countWrapperStyles = css({
|
|
49
107
|
alignItems: 'center'
|
|
108
|
+
});
|
|
109
|
+
export const orderZeroStyles = css({
|
|
110
|
+
order: '0'
|
|
111
|
+
});
|
|
112
|
+
export const orderOneStyles = css({
|
|
113
|
+
order: '1'
|
|
50
114
|
});
|
package/dist/esm/styles.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
var
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
var _css;
|
|
3
3
|
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage/preview */
|
|
4
4
|
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
|
|
5
|
+
/* eslint-disable */
|
|
5
6
|
|
|
6
7
|
// TODO: https://product-fabric.atlassian.net/browse/DSP-4290
|
|
7
8
|
import { css } from '@emotion/react';
|
|
8
|
-
import { B200, B75 } from '@atlaskit/theme/colors';
|
|
9
|
+
import { B200, B75, N40A, N50A, N60A } from '@atlaskit/theme/colors';
|
|
10
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
9
11
|
export var searchMatchClass = 'search-match';
|
|
10
12
|
export var selectedSearchMatchClass = 'selected-search-match';
|
|
11
|
-
export var findReplaceStyles = css(
|
|
13
|
+
export var findReplaceStyles = css((_css = {}, _defineProperty(_css, ".".concat(searchMatchClass), getBooleanFF('platform.editor.a11y-find-replace') ? {
|
|
14
|
+
borderRadius: '3px',
|
|
15
|
+
backgroundColor: "var(--ds-background-accent-teal-subtlest, #E7F9FF)",
|
|
16
|
+
boxShadow: "var(--ds-shadow-raised, ".concat("0 1px 1px 0 ".concat(N50A, ", 0 0 1px 0 ").concat(N60A), ")") + ', inset 0 0 0 1px ' + "var(--ds-border-input, ".concat("".concat(N40A), ")")
|
|
17
|
+
} : {
|
|
18
|
+
backgroundColor: B75
|
|
19
|
+
}), _defineProperty(_css, ".".concat(selectedSearchMatchClass), getBooleanFF('platform.editor.a11y-find-replace') ? {
|
|
20
|
+
backgroundColor: "var(--ds-background-accent-teal-subtle, #6CC3E0)"
|
|
21
|
+
} : {
|
|
22
|
+
backgroundColor: B200,
|
|
23
|
+
color: 'white'
|
|
24
|
+
}), _css));
|