@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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
@@ -12,33 +13,23 @@ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits
12
13
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
13
14
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
14
15
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
- var _react = _interopRequireDefault(require("react"));
16
+ var _react = _interopRequireWildcard(require("react"));
16
17
  var _react2 = require("@emotion/react");
17
18
  var _reactIntlNext = require("react-intl-next");
18
19
  var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button"));
19
20
  var _analytics = require("@atlaskit/editor-common/analytics");
21
+ var _messages = require("@atlaskit/editor-common/messages");
22
+ var _form = require("@atlaskit/form");
23
+ var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-down"));
24
+ var _chevronUp = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-up"));
25
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
20
26
  var _textfield = _interopRequireDefault(require("@atlaskit/textfield"));
27
+ var _FindReplaceTooltipButton = require("./FindReplaceTooltipButton");
21
28
  var _styles = require("./styles");
29
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
30
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
22
31
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
23
32
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /* eslint-disable @atlaskit/design-system/consistent-css-prop-usage */ /** @jsx jsx */
24
- var messages = (0, _reactIntlNext.defineMessages)({
25
- replaceWith: {
26
- id: 'fabric.editor.replaceWith',
27
- defaultMessage: 'Replace with',
28
- description: 'The value that will replace the word or phrase that was searched for'
29
- },
30
- replace: {
31
- id: 'fabric.editor.replace',
32
- defaultMessage: 'Replace',
33
- description: 'Replace only the currently selected instance of the word or phrase'
34
- },
35
- replaceAll: {
36
- id: 'fabric.editor.replaceAll',
37
- defaultMessage: 'Replace all',
38
- description: 'Replace all instances of the word or phrase throughout the entire document'
39
- }
40
- });
41
-
42
33
  // eslint-disable-next-line @repo/internal/react/no-class-components
43
34
  var Replace = /*#__PURE__*/function (_React$PureComponent) {
44
35
  (0, _inherits2.default)(Replace, _React$PureComponent);
@@ -48,6 +39,8 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
48
39
  (0, _classCallCheck2.default)(this, Replace);
49
40
  _this = _super.call(this, props);
50
41
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "replaceTextfieldRef", /*#__PURE__*/_react.default.createRef());
42
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "successReplacementMessageRef", /*#__PURE__*/_react.default.createRef());
43
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isComposing", false);
51
44
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "skipWhileComposing", function (fn) {
52
45
  if (_this.state.isComposing) {
53
46
  return;
@@ -60,6 +53,14 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
60
53
  triggerMethod: _analytics.TRIGGER_METHOD.BUTTON,
61
54
  replaceText: _this.state.replaceText
62
55
  });
56
+ // for replace button replaceCount always 1;
57
+ var replaceCount = 1;
58
+ _this.triggerSuccessReplacementMessageUpdate(replaceCount);
59
+ _this.setState({
60
+ isHelperMessageVisible: true,
61
+ replaceCount: replaceCount
62
+ });
63
+ _this.props.setFindTyped(false);
63
64
  });
64
65
  });
65
66
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleReplaceChange", function (event) {
@@ -98,6 +99,14 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
98
99
  _this.props.onReplaceAll({
99
100
  replaceText: _this.state.replaceText
100
101
  });
102
+ _this.setState({
103
+ isHelperMessageVisible: true
104
+ });
105
+ _this.triggerSuccessReplacementMessageUpdate(_this.props.count.total);
106
+ _this.setState({
107
+ replaceCount: _this.props.count.total
108
+ });
109
+ _this.props.setFindTyped(false);
101
110
  });
102
111
  });
103
112
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleCompositionStart", function () {
@@ -112,15 +121,49 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
112
121
  // type for React.CompositionEvent doesn't set type for target correctly
113
122
  _this.updateReplaceValue(event.target.value);
114
123
  });
124
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "clearSearch", function () {
125
+ _this.props.onCancel({
126
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
127
+ });
128
+ _this.props.focusToolbarButton && _this.props.focusToolbarButton();
129
+ });
130
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFindNextClick", function () {
131
+ if (_this.isComposing) {
132
+ return;
133
+ }
134
+ _this.props.onFindNext({
135
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
136
+ });
137
+ });
138
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFindPrevClick", function () {
139
+ if (_this.isComposing) {
140
+ return;
141
+ }
142
+ _this.props.onFindPrev({
143
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
144
+ });
145
+ });
115
146
  var _replaceText = props.replaceText,
116
147
  formatMessage = props.intl.formatMessage;
117
148
  _this.state = {
118
149
  replaceText: _replaceText || '',
119
- isComposing: false
150
+ isComposing: false,
151
+ isHelperMessageVisible: false,
152
+ fakeSuccessReplacementMessageUpdate: false,
153
+ replaceCount: 0
120
154
  };
121
- _this.replaceWith = formatMessage(messages.replaceWith);
122
- _this.replace = formatMessage(messages.replace);
123
- _this.replaceAll = formatMessage(messages.replaceAll);
155
+ _this.replaceWith = formatMessage(_messages.findReplaceMessages.replaceWith);
156
+ _this.replace = formatMessage(_messages.findReplaceMessages.replace);
157
+ _this.replaceAll = formatMessage(_messages.findReplaceMessages.replaceAll);
158
+ _this.findNext = formatMessage(_messages.findReplaceMessages.findNext);
159
+ _this.findPrevious = formatMessage(_messages.findReplaceMessages.findPrevious);
160
+ _this.findNextIcon = (0, _react2.jsx)(_chevronDown.default, {
161
+ label: _this.findNext
162
+ });
163
+ _this.findPrevIcon = (0, _react2.jsx)(_chevronUp.default, {
164
+ label: _this.findPrevious
165
+ });
166
+ _this.closeFindReplaceDialog = formatMessage(_messages.findReplaceMessages.closeFindReplaceDialog);
124
167
  return _this;
125
168
  }
126
169
  (0, _createClass2.default)(Replace, [{
@@ -139,13 +182,112 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
139
182
  isComposing: false
140
183
  });
141
184
  }
185
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-find-replace')) {
186
+ var findTextField = document.getElementById('find-text-field');
187
+ var replaceButton = document.getElementById('replace-button');
188
+ var replaceAllButton = document.getElementById('replaceAll-button');
189
+ if (((replaceButton === null || replaceButton === void 0 ? void 0 : replaceButton.tabIndex) === -1 || (replaceAllButton === null || replaceAllButton === void 0 ? void 0 : replaceAllButton.tabIndex) === -1) && findTextField) {
190
+ findTextField.focus();
191
+ }
192
+ }
193
+ }
194
+ }, {
195
+ key: "triggerSuccessReplacementMessageUpdate",
196
+ value: function triggerSuccessReplacementMessageUpdate(currentReplaceCount) {
197
+ var _this$state;
198
+ if (((_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.replaceCount) === currentReplaceCount) {
199
+ this.setState({
200
+ fakeSuccessReplacementMessageUpdate: !this.state.fakeSuccessReplacementMessageUpdate
201
+ });
202
+ }
203
+ if (this.successReplacementMessageRef && this.successReplacementMessageRef.current) {
204
+ var ariaLiveRegion = this.successReplacementMessageRef.current.querySelector('[aria-live="polite"]');
205
+ ariaLiveRegion === null || ariaLiveRegion === void 0 || ariaLiveRegion.removeAttribute('aria-live');
206
+ ariaLiveRegion === null || ariaLiveRegion === void 0 || ariaLiveRegion.setAttribute('aria-live', 'polite');
207
+ }
142
208
  }
143
209
  }, {
144
210
  key: "render",
145
211
  value: function render() {
146
- var replaceText = this.state.replaceText;
147
- var canReplace = this.props.canReplace;
148
- return (0, _react2.jsx)("div", {
212
+ var _this$state2 = this.state,
213
+ replaceText = _this$state2.replaceText,
214
+ isHelperMessageVisible = _this$state2.isHelperMessageVisible,
215
+ replaceCount = _this$state2.replaceCount;
216
+ var _this$props = this.props,
217
+ canReplace = _this$props.canReplace,
218
+ count = _this$props.count,
219
+ formatMessage = _this$props.intl.formatMessage;
220
+ var resultsReplace = formatMessage(_messages.findReplaceMessages.replaceSuccess, {
221
+ numberOfMatches: replaceCount,
222
+ matchPluralSingularNoun: replaceCount > 1 ? formatMessage(_messages.findReplaceMessages.matchPluralNoun) : formatMessage(_messages.findReplaceMessages.matchSingularNoun)
223
+ });
224
+ return (0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-find-replace') ? (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)("div", {
225
+ css: [_styles.sectionWrapperStyles, _styles.sectionWrapperStylesAlternate]
226
+ }, (0, _react2.jsx)("div", {
227
+ css: _styles.textFieldWrapper
228
+ }, (0, _react2.jsx)(_form.Label, {
229
+ htmlFor: "replace-text-field"
230
+ }, "Replace with"), (0, _react2.jsx)(_textfield.default, {
231
+ name: "replace",
232
+ id: "replace-text-field",
233
+ appearance: "standard",
234
+ defaultValue: replaceText,
235
+ ref: this.replaceTextfieldRef,
236
+ autoComplete: "off",
237
+ onChange: this.handleReplaceChange,
238
+ onKeyDown: this.handleReplaceKeyDown,
239
+ onCompositionStart: this.handleCompositionStart,
240
+ onCompositionEnd: this.handleCompositionEnd
241
+ }), isHelperMessageVisible && this.props.findTyped === false && (0, _react2.jsx)("div", {
242
+ ref: this.successReplacementMessageRef
243
+ }, (0, _react2.jsx)(_form.ValidMessage, {
244
+ testId: "message-success-replacement"
245
+ },
246
+ /*
247
+ Replacement needed to trigger the SR announcement if message hasn't changed. e.g Replace button clicked twice.
248
+ '\u00a0' is value for &nbsp
249
+ */
250
+ this.state.fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(/ /, "\xA0") : resultsReplace)))), (0, _react2.jsx)("div", {
251
+ css: [_styles.sectionWrapperStyles, _styles.sectionWrapperStylesAlternate, _styles.sectionWrapperJustified]
252
+ }, (0, _react2.jsx)("div", {
253
+ css: _styles.orderOneStyles
254
+ }, (0, _react2.jsx)("div", {
255
+ css: _styles.NextPreviousItem
256
+ }, (0, _react2.jsx)(_FindReplaceTooltipButton.FindReplaceTooltipButton, {
257
+ title: this.findNext,
258
+ icon: this.findNextIcon,
259
+ keymapDescription: 'Enter',
260
+ onClick: this.handleFindNextClick,
261
+ disabled: count.total <= 1
262
+ })), (0, _react2.jsx)("div", {
263
+ css: _styles.NextPreviousItem
264
+ }, (0, _react2.jsx)(_FindReplaceTooltipButton.FindReplaceTooltipButton, {
265
+ title: this.findPrevious,
266
+ icon: this.findPrevIcon,
267
+ keymapDescription: 'Shift Enter',
268
+ onClick: this.handleFindPrevClick,
269
+ disabled: count.total <= 1
270
+ })), (0, _react2.jsx)(_standardButton.default, {
271
+ css: _styles.replaceSectionButtonStyles,
272
+ testId: this.replace,
273
+ id: "replace-button",
274
+ onClick: this.handleReplaceClick,
275
+ isDisabled: !canReplace
276
+ }, this.replace), (0, _react2.jsx)(_standardButton.default, {
277
+ css: _styles.replaceSectionButtonStyles,
278
+ appearance: "primary",
279
+ testId: this.replaceAll,
280
+ id: "replaceAll-button",
281
+ onClick: this.handleReplaceAllClick,
282
+ isDisabled: !canReplace
283
+ }, this.replaceAll)), (0, _react2.jsx)("div", {
284
+ css: _styles.orderZeroStyles
285
+ }, (0, _react2.jsx)(_standardButton.default, {
286
+ css: _styles.replaceSectionButtonStyles,
287
+ appearance: "subtle",
288
+ testId: this.closeFindReplaceDialog,
289
+ onClick: this.clearSearch
290
+ }, this.closeFindReplaceDialog)))) : (0, _react2.jsx)("div", {
149
291
  css: _styles.sectionWrapperStyles
150
292
  }, (0, _react2.jsx)(_textfield.default, {
151
293
  name: "replace",
@@ -4,16 +4,23 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.wrapperStyles = exports.sectionWrapperStyles = exports.ruleStyles = exports.replaceSectionButtonStyles = exports.countWrapperStyles = exports.countStyles = void 0;
7
+ exports.wrapperStyles = exports.wrapperPaddingStyles = exports.textFieldWrapper = exports.sectionWrapperStylesAlternate = exports.sectionWrapperStyles = exports.sectionWrapperJustified = exports.ruleStyles = exports.replaceSectionButtonStyles = exports.orderZeroStyles = exports.orderOneStyles = exports.matchCaseSection = exports.countWrapperStyles = exports.countStylesAlternateStyles = exports.countStyles = exports.afterInputSection = exports.NextPreviousItem = void 0;
8
8
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
9
9
  var _react = require("@emotion/react");
10
10
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
11
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
12
  var _colors = require("@atlaskit/theme/colors");
12
- var _templateObject;
13
+ var _constants = require("@atlaskit/theme/constants");
14
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
13
15
  /* eslint-disable @atlaskit/design-system/no-nested-styles */
14
16
  /* eslint-disable @repo/internal/styles/no-exported-styles */
15
17
  /** @jsx jsx */
16
- var replaceSectionButtonStyles = exports.replaceSectionButtonStyles = (0, _react.css)({
18
+ var fontSize = (0, _constants.fontSize)();
19
+ var gridSize = (0, _constants.gridSize)();
20
+ var replaceSectionButtonStyles = exports.replaceSectionButtonStyles = (0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-find-replace') ? (0, _react.css)({
21
+ marginLeft: "var(--ds-space-050, 4px)",
22
+ marginRight: "var(--ds-space-050, 2px)"
23
+ }) : (0, _react.css)({
17
24
  marginLeft: "var(--ds-space-050, 4px)"
18
25
  });
19
26
  var ruleStyles = exports.ruleStyles = (0, _react.css)({
@@ -31,9 +38,18 @@ var wrapperStyles = exports.wrapperStyles = (0, _react.css)({
31
38
  margin: "0px ".concat("var(--ds-space-050, 4px)")
32
39
  }
33
40
  });
41
+ var wrapperPaddingStyles = exports.wrapperPaddingStyles = (0, _react.css)({
42
+ padding: "var(--ds-space-050, 4px)".concat(" ", "var(--ds-space-050, 4px)")
43
+ });
34
44
  var sectionWrapperStyles = exports.sectionWrapperStyles = (0, _react.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n\n & > * {\n display: inline-flex;\n height: 32px;\n flex: 0 0 auto;\n }\n\n & > [data-ds--text-field--container] {\n display: flex;\n flex: 1 1 auto;\n }\n"])));
45
+ var sectionWrapperStylesAlternate = exports.sectionWrapperStylesAlternate = (0, _react.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n padding: ", ";\n\n & > * {\n height: unset;\n }\n"])), "var(--ds-space-100, 8px)");
46
+ var sectionWrapperJustified = exports.sectionWrapperJustified = (0, _react.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n justify-content: space-between;\n font-size: ", ";\n"])), (0, _editorSharedStyles.relativeFontSizeToBase16)(14));
47
+ var textFieldWrapper = exports.textFieldWrapper = (0, _react.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n flex: 1 100%;\n flex-wrap: wrap;\n\n #find-text-field,\n #replace-text-field {\n height: ", "em;\n }\n\n label {\n font-size: ", ";\n line-height: ", "px;\n }\n"])), gridSize * 4.5 / fontSize, (0, _editorSharedStyles.relativeFontSizeToBase16)(14), gridSize * 2);
48
+ var afterInputSection = exports.afterInputSection = (0, _react.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n"])));
49
+ var matchCaseSection = exports.matchCaseSection = (0, _react.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n padding-right: ", ";\n\n button {\n width: 20px;\n height: 20px;\n }\n"])), "var(--ds-space-100, 8px)");
50
+ var NextPreviousItem = exports.NextPreviousItem = (0, _react.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n padding: 0px 3px;\n"])));
35
51
  var countStyles = exports.countStyles = (0, _react.css)({
36
- color: "".concat("var(--ds-text-subtlest, ".concat(_colors.N60, ")")),
52
+ color: "var(--ds-text-subtlest, #626F86)",
37
53
  fontSize: "".concat((0, _editorSharedStyles.relativeFontSizeToBase16)(12)),
38
54
  flex: '0 0 auto',
39
55
  justifyContent: 'center',
@@ -41,6 +57,16 @@ var countStyles = exports.countStyles = (0, _react.css)({
41
57
  marginLeft: "var(--ds-space-050, 4px)",
42
58
  marginRight: "var(--ds-space-100, 8px)"
43
59
  });
60
+ var countStylesAlternateStyles = exports.countStylesAlternateStyles = (0, _react.css)({
61
+ display: 'inline-flex',
62
+ height: '32px'
63
+ });
44
64
  var countWrapperStyles = exports.countWrapperStyles = (0, _react.css)({
45
65
  alignItems: 'center'
66
+ });
67
+ var orderZeroStyles = exports.orderZeroStyles = (0, _react.css)({
68
+ order: '0'
69
+ });
70
+ var orderOneStyles = exports.orderOneStyles = (0, _react.css)({
71
+ order: '1'
46
72
  });
@@ -1,18 +1,25 @@
1
1
  /* eslint-disable @atlaskit/design-system/ensure-design-token-usage/preview */
2
2
  /* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
3
+ /* eslint-disable */
3
4
 
4
5
  // TODO: https://product-fabric.atlassian.net/browse/DSP-4290
5
6
  import { css } from '@emotion/react';
6
- import { B200, B75 } from '@atlaskit/theme/colors';
7
+ import { B200, B75, N40A, N50A, N60A } from '@atlaskit/theme/colors';
8
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
9
  export const searchMatchClass = 'search-match';
8
10
  export const selectedSearchMatchClass = 'selected-search-match';
9
- export const findReplaceStyles = css`
10
- .${searchMatchClass} {
11
- background-color: ${B75};
11
+ export const findReplaceStyles = css({
12
+ [`.${searchMatchClass}`]: getBooleanFF('platform.editor.a11y-find-replace') ? {
13
+ borderRadius: '3px',
14
+ backgroundColor: "var(--ds-background-accent-teal-subtlest, #E7F9FF)",
15
+ boxShadow: `var(--ds-shadow-raised, ${`0 1px 1px 0 ${N50A}, 0 0 1px 0 ${N60A}`})` + ', inset 0 0 0 1px ' + `var(--ds-border-input, ${`${N40A}`})`
16
+ } : {
17
+ backgroundColor: B75
18
+ },
19
+ [`.${selectedSearchMatchClass}`]: getBooleanFF('platform.editor.a11y-find-replace') ? {
20
+ backgroundColor: "var(--ds-background-accent-teal-subtle, #6CC3E0)"
21
+ } : {
22
+ backgroundColor: B200,
23
+ color: 'white'
12
24
  }
13
-
14
- .${selectedSearchMatchClass} {
15
- background-color: ${B200};
16
- color: white;
17
- }
18
- `;
25
+ });
@@ -5,8 +5,10 @@ import React from 'react';
5
5
  import { jsx } from '@emotion/react';
6
6
  import debounce from 'lodash/debounce';
7
7
  import rafSchd from 'raf-schd';
8
- import { defineMessages, injectIntl } from 'react-intl-next';
8
+ import { injectIntl } from 'react-intl-next';
9
9
  import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
10
+ import { findReplaceMessages as messages } from '@atlaskit/editor-common/messages';
11
+ import { Label } from '@atlaskit/form';
10
12
  import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
11
13
  import MatchCaseIcon from '@atlaskit/icon/glyph/emoji/keyboard';
12
14
  import ChevronDownIcon from '@atlaskit/icon/glyph/hipchat/chevron-down';
@@ -14,45 +16,8 @@ import ChevronUpIcon from '@atlaskit/icon/glyph/hipchat/chevron-up';
14
16
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
15
17
  import Textfield from '@atlaskit/textfield';
16
18
  import { FindReplaceTooltipButton } from './FindReplaceTooltipButton';
17
- import { countStyles, countWrapperStyles, sectionWrapperStyles } from './styles';
19
+ import { afterInputSection, countStyles, countStylesAlternateStyles, countWrapperStyles, matchCaseSection, sectionWrapperStyles, sectionWrapperStylesAlternate, textFieldWrapper } from './styles';
18
20
  export const FIND_DEBOUNCE_MS = 100;
19
- const messages = defineMessages({
20
- find: {
21
- id: 'fabric.editor.find',
22
- defaultMessage: 'Find',
23
- description: 'The word or phrase to search for on the document'
24
- },
25
- matchCase: {
26
- id: 'fabric.editor.matchCase',
27
- defaultMessage: 'Match case',
28
- description: 'Toggle whether should also match case when searching for text'
29
- },
30
- findNext: {
31
- id: 'fabric.editor.findNext',
32
- defaultMessage: 'Find next',
33
- description: 'Locate the next occurrence of the word or phrase that was searched for'
34
- },
35
- findPrevious: {
36
- id: 'fabric.editor.findPrevious',
37
- defaultMessage: 'Find previous',
38
- description: 'Locate the previous occurrence of the word or phrase that was searched for'
39
- },
40
- closeFindReplaceDialog: {
41
- id: 'fabric.editor.closeFindReplaceDialog',
42
- defaultMessage: 'Close',
43
- description: 'Cancel search and close the "Find and Replace" dialog'
44
- },
45
- noResultsFound: {
46
- id: 'fabric.editor.noResultsFound',
47
- defaultMessage: 'No results',
48
- description: 'No matches were found for the word or phrase that was searched for'
49
- },
50
- resultsCount: {
51
- id: 'fabric.editor.resultsCount',
52
- description: 'Text for selected search match position and total results count',
53
- defaultMessage: '{selectedMatchPosition} of {totalResultsCount}'
54
- }
55
- });
56
21
  // eslint-disable-next-line @repo/internal/react/no-class-components
57
22
  class Find extends React.Component {
58
23
  constructor(props) {
@@ -93,6 +58,7 @@ class Find extends React.Component {
93
58
  onSynced && onSynced();
94
59
  this.debouncedFind(value);
95
60
  });
61
+ this.props.setFindTyped(true);
96
62
  });
97
63
  // throtlle between animation frames gives better experience on Enter compared to arbitrary value
98
64
  // it adjusts based on performance (and document size)
@@ -169,7 +135,8 @@ class Find extends React.Component {
169
135
  this.findPrevious = formatMessage(messages.findPrevious);
170
136
  this.matchCase = formatMessage(messages.matchCase);
171
137
  this.matchCaseIcon = jsx(MatchCaseIcon, {
172
- label: this.matchCase
138
+ label: this.matchCase,
139
+ size: getBooleanFF('platform.editor.a11y-find-replace') ? 'small' : 'medium'
173
140
  });
174
141
  this.findNextIcon = jsx(ChevronDownIcon, {
175
142
  label: this.findNext
@@ -203,20 +170,18 @@ class Find extends React.Component {
203
170
  });
204
171
  }
205
172
  componentDidUpdate(prevProps) {
173
+ var _this$state2;
206
174
  // focus on update if find text did not change
207
- if (!getBooleanFF('platform.editor.a11y-find-replace')) {
208
- var _this$state2;
209
- if (this.props.findText === ((_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.localFindText)) {
210
- this.focusFindTextfield();
211
- }
212
- if (this.props.findText !== prevProps.findText) {
213
- this.syncFindText(() => {
214
- // focus after input is synced if find text provided
215
- if (this.props.findText) {
216
- this.focusFindTextfield();
217
- }
218
- });
219
- }
175
+ if (this.props.findText === ((_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.localFindText)) {
176
+ this.focusFindTextfield();
177
+ }
178
+ if (this.props.findText !== prevProps.findText) {
179
+ this.syncFindText(() => {
180
+ // focus after input is synced if find text provided
181
+ if (this.props.findText) {
182
+ this.focusFindTextfield();
183
+ }
184
+ });
220
185
  }
221
186
  }
222
187
  componentWillUnmount() {
@@ -237,50 +202,90 @@ class Find extends React.Component {
237
202
  selectedMatchPosition: count.index + 1,
238
203
  totalResultsCount: count.total
239
204
  });
240
- return jsx("div", {
241
- css: sectionWrapperStyles
242
- }, jsx(Textfield, {
243
- name: "find",
244
- appearance: "none",
245
- placeholder: this.find,
246
- value: this.state.localFindText,
247
- ref: this.findTextfieldRef,
248
- autoComplete: "off",
249
- onChange: this.handleFindChange,
250
- onKeyDown: this.handleFindKeyDown,
251
- onKeyUp: this.handleFindKeyUp,
252
- onBlur: this.props.onFindBlur,
253
- onCompositionStart: this.handleCompositionStart,
254
- onCompositionEnd: this.handleCompositionEnd
255
- }), jsx("div", {
256
- css: countWrapperStyles,
257
- "aria-live": "polite"
258
- }, findText && jsx("span", {
259
- "data-testid": "textfield-count",
260
- css: countStyles
261
- }, count.total === 0 ? this.noResultsFound : resultsCount)), allowMatchCase && jsx(FindReplaceTooltipButton, {
262
- title: this.matchCase,
263
- icon: this.matchCaseIcon,
264
- onClick: this.handleMatchCaseClick,
265
- isPressed: shouldMatchCase
266
- }), jsx(FindReplaceTooltipButton, {
267
- title: this.findNext,
268
- icon: this.findNextIcon,
269
- keymapDescription: 'Enter',
270
- onClick: this.handleFindNextClick,
271
- disabled: count.total <= 1
272
- }), jsx(FindReplaceTooltipButton, {
273
- title: this.findPrevious,
274
- icon: this.findPrevIcon,
275
- keymapDescription: 'Shift Enter',
276
- onClick: this.handleFindPrevClick,
277
- disabled: count.total <= 1
278
- }), jsx(FindReplaceTooltipButton, {
279
- title: this.closeFindReplaceDialog,
280
- icon: this.closeIcon,
281
- keymapDescription: 'Escape',
282
- onClick: this.clearSearch
283
- }));
205
+ if (getBooleanFF('platform.editor.a11y-find-replace')) {
206
+ const elemAfterInput = jsx("div", {
207
+ css: afterInputSection
208
+ }, jsx("div", {
209
+ "aria-live": "polite"
210
+ }, findText && jsx("span", {
211
+ "data-testid": "textfield-count",
212
+ css: [countStyles, countStylesAlternateStyles]
213
+ }, count.total === 0 ? this.noResultsFound : resultsCount)), allowMatchCase && jsx("div", {
214
+ css: matchCaseSection
215
+ }, jsx(FindReplaceTooltipButton, {
216
+ title: this.matchCase,
217
+ appearance: "default",
218
+ icon: this.matchCaseIcon,
219
+ onClick: this.handleMatchCaseClick,
220
+ isPressed: shouldMatchCase
221
+ })));
222
+ return jsx("div", {
223
+ css: [sectionWrapperStyles, sectionWrapperStylesAlternate]
224
+ }, jsx("div", {
225
+ css: textFieldWrapper
226
+ }, jsx(Label, {
227
+ htmlFor: "find-text-field"
228
+ }, this.find), jsx(Textfield, {
229
+ name: "find",
230
+ id: "find-text-field",
231
+ appearance: "standard",
232
+ value: this.state.localFindText,
233
+ ref: this.findTextfieldRef,
234
+ autoComplete: "off",
235
+ onChange: this.handleFindChange,
236
+ onKeyDown: this.handleFindKeyDown,
237
+ onKeyUp: this.handleFindKeyUp,
238
+ onBlur: this.props.onFindBlur,
239
+ onCompositionStart: this.handleCompositionStart,
240
+ onCompositionEnd: this.handleCompositionEnd,
241
+ elemAfterInput: elemAfterInput
242
+ })));
243
+ } else {
244
+ return jsx("div", {
245
+ css: sectionWrapperStyles
246
+ }, jsx(Textfield, {
247
+ name: "find",
248
+ appearance: "none",
249
+ placeholder: this.find,
250
+ value: this.state.localFindText,
251
+ ref: this.findTextfieldRef,
252
+ autoComplete: "off",
253
+ onChange: this.handleFindChange,
254
+ onKeyDown: this.handleFindKeyDown,
255
+ onKeyUp: this.handleFindKeyUp,
256
+ onBlur: this.props.onFindBlur,
257
+ onCompositionStart: this.handleCompositionStart,
258
+ onCompositionEnd: this.handleCompositionEnd
259
+ }), jsx("div", {
260
+ css: countWrapperStyles,
261
+ "aria-live": "polite"
262
+ }, findText && jsx("span", {
263
+ "data-testid": "textfield-count",
264
+ css: countStyles
265
+ }, count.total === 0 ? this.noResultsFound : resultsCount)), allowMatchCase && jsx(FindReplaceTooltipButton, {
266
+ title: this.matchCase,
267
+ icon: this.matchCaseIcon,
268
+ onClick: this.handleMatchCaseClick,
269
+ isPressed: shouldMatchCase
270
+ }), jsx(FindReplaceTooltipButton, {
271
+ title: this.findNext,
272
+ icon: this.findNextIcon,
273
+ keymapDescription: 'Enter',
274
+ onClick: this.handleFindNextClick,
275
+ disabled: count.total <= 1
276
+ }), jsx(FindReplaceTooltipButton, {
277
+ title: this.findPrevious,
278
+ icon: this.findPrevIcon,
279
+ keymapDescription: 'Shift Enter',
280
+ onClick: this.handleFindPrevClick,
281
+ disabled: count.total <= 1
282
+ }), jsx(FindReplaceTooltipButton, {
283
+ title: this.closeFindReplaceDialog,
284
+ icon: this.closeIcon,
285
+ keymapDescription: 'Escape',
286
+ onClick: this.clearSearch
287
+ }));
288
+ }
284
289
  }
285
290
  }
286
291
  export default injectIntl(Find);