@atlaskit/editor-plugin-find-replace 0.2.0 → 0.3.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.
@@ -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,13 +13,20 @@ 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 _form = require("@atlaskit/form");
22
+ var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-down"));
23
+ var _chevronUp = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-up"));
24
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
20
25
  var _textfield = _interopRequireDefault(require("@atlaskit/textfield"));
26
+ var _FindReplaceTooltipButton = require("./FindReplaceTooltipButton");
21
27
  var _styles = require("./styles");
28
+ 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); }
29
+ 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
30
  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
31
  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
32
  var messages = (0, _reactIntlNext.defineMessages)({
@@ -36,6 +44,36 @@ var messages = (0, _reactIntlNext.defineMessages)({
36
44
  id: 'fabric.editor.replaceAll',
37
45
  defaultMessage: 'Replace all',
38
46
  description: 'Replace all instances of the word or phrase throughout the entire document'
47
+ },
48
+ replaceSuccess: {
49
+ id: 'fabric.editor.replaceSuccess',
50
+ defaultMessage: '{numberOfMatches} {matchPluralSingularNoun} replaced',
51
+ description: 'Text when replacement succesfully done'
52
+ },
53
+ matchSingularNoun: {
54
+ id: 'fabric.editor.match.singular',
55
+ defaultMessage: 'match',
56
+ description: 'Singular "Match" noun'
57
+ },
58
+ matchPluralNoun: {
59
+ id: 'fabric.editor.match.plural',
60
+ defaultMessage: 'matches',
61
+ description: 'Plural "Match" noun'
62
+ },
63
+ findNext: {
64
+ id: 'fabric.editor.findNext',
65
+ defaultMessage: 'Find next',
66
+ description: 'Locate the next occurrence of the word or phrase that was searched for'
67
+ },
68
+ findPrevious: {
69
+ id: 'fabric.editor.findPrevious',
70
+ defaultMessage: 'Find previous',
71
+ description: 'Locate the previous occurrence of the word or phrase that was searched for'
72
+ },
73
+ closeFindReplaceDialog: {
74
+ id: 'fabric.editor.closeFindReplaceDialog',
75
+ defaultMessage: 'Close',
76
+ description: 'Cancel search and close the "Find and Replace" dialog'
39
77
  }
40
78
  });
41
79
 
@@ -48,6 +86,8 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
48
86
  (0, _classCallCheck2.default)(this, Replace);
49
87
  _this = _super.call(this, props);
50
88
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "replaceTextfieldRef", /*#__PURE__*/_react.default.createRef());
89
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "successReplacementMessageRef", /*#__PURE__*/_react.default.createRef());
90
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isComposing", false);
51
91
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "skipWhileComposing", function (fn) {
52
92
  if (_this.state.isComposing) {
53
93
  return;
@@ -60,6 +100,14 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
60
100
  triggerMethod: _analytics.TRIGGER_METHOD.BUTTON,
61
101
  replaceText: _this.state.replaceText
62
102
  });
103
+ // for replace button replaceCount always 1;
104
+ var replaceCount = 1;
105
+ _this.triggerSuccessReplacementMessageUpdate(replaceCount);
106
+ _this.setState({
107
+ isHelperMessageVisible: true,
108
+ replaceCount: replaceCount
109
+ });
110
+ _this.props.setFindTyped(false);
63
111
  });
64
112
  });
65
113
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleReplaceChange", function (event) {
@@ -98,6 +146,14 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
98
146
  _this.props.onReplaceAll({
99
147
  replaceText: _this.state.replaceText
100
148
  });
149
+ _this.setState({
150
+ isHelperMessageVisible: true
151
+ });
152
+ _this.triggerSuccessReplacementMessageUpdate(_this.props.count.total);
153
+ _this.setState({
154
+ replaceCount: _this.props.count.total
155
+ });
156
+ _this.props.setFindTyped(false);
101
157
  });
102
158
  });
103
159
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleCompositionStart", function () {
@@ -112,15 +168,49 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
112
168
  // type for React.CompositionEvent doesn't set type for target correctly
113
169
  _this.updateReplaceValue(event.target.value);
114
170
  });
171
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "clearSearch", function () {
172
+ _this.props.onCancel({
173
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
174
+ });
175
+ _this.props.focusToolbarButton && _this.props.focusToolbarButton();
176
+ });
177
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFindNextClick", function () {
178
+ if (_this.isComposing) {
179
+ return;
180
+ }
181
+ _this.props.onFindNext({
182
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
183
+ });
184
+ });
185
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFindPrevClick", function () {
186
+ if (_this.isComposing) {
187
+ return;
188
+ }
189
+ _this.props.onFindPrev({
190
+ triggerMethod: _analytics.TRIGGER_METHOD.BUTTON
191
+ });
192
+ });
115
193
  var _replaceText = props.replaceText,
116
194
  formatMessage = props.intl.formatMessage;
117
195
  _this.state = {
118
196
  replaceText: _replaceText || '',
119
- isComposing: false
197
+ isComposing: false,
198
+ isHelperMessageVisible: false,
199
+ fakeSuccessReplacementMessageUpdate: false,
200
+ replaceCount: 0
120
201
  };
121
202
  _this.replaceWith = formatMessage(messages.replaceWith);
122
203
  _this.replace = formatMessage(messages.replace);
123
204
  _this.replaceAll = formatMessage(messages.replaceAll);
205
+ _this.findNext = formatMessage(messages.findNext);
206
+ _this.findPrevious = formatMessage(messages.findPrevious);
207
+ _this.findNextIcon = (0, _react2.jsx)(_chevronDown.default, {
208
+ label: _this.findNext
209
+ });
210
+ _this.findPrevIcon = (0, _react2.jsx)(_chevronUp.default, {
211
+ label: _this.findPrevious
212
+ });
213
+ _this.closeFindReplaceDialog = formatMessage(messages.closeFindReplaceDialog);
124
214
  return _this;
125
215
  }
126
216
  (0, _createClass2.default)(Replace, [{
@@ -139,13 +229,112 @@ var Replace = /*#__PURE__*/function (_React$PureComponent) {
139
229
  isComposing: false
140
230
  });
141
231
  }
232
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-find-replace')) {
233
+ var findTextField = document.getElementById('find-text-field');
234
+ var replaceButton = document.getElementById('replace-button');
235
+ var replaceAllButton = document.getElementById('replaceAll-button');
236
+ if (((replaceButton === null || replaceButton === void 0 ? void 0 : replaceButton.tabIndex) === -1 || (replaceAllButton === null || replaceAllButton === void 0 ? void 0 : replaceAllButton.tabIndex) === -1) && findTextField) {
237
+ findTextField.focus();
238
+ }
239
+ }
240
+ }
241
+ }, {
242
+ key: "triggerSuccessReplacementMessageUpdate",
243
+ value: function triggerSuccessReplacementMessageUpdate(currentReplaceCount) {
244
+ var _this$state;
245
+ if (((_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.replaceCount) === currentReplaceCount) {
246
+ this.setState({
247
+ fakeSuccessReplacementMessageUpdate: !this.state.fakeSuccessReplacementMessageUpdate
248
+ });
249
+ }
250
+ if (this.successReplacementMessageRef && this.successReplacementMessageRef.current) {
251
+ var ariaLiveRegion = this.successReplacementMessageRef.current.querySelector('[aria-live="polite"]');
252
+ ariaLiveRegion === null || ariaLiveRegion === void 0 || ariaLiveRegion.removeAttribute('aria-live');
253
+ ariaLiveRegion === null || ariaLiveRegion === void 0 || ariaLiveRegion.setAttribute('aria-live', 'polite');
254
+ }
142
255
  }
143
256
  }, {
144
257
  key: "render",
145
258
  value: function render() {
146
- var replaceText = this.state.replaceText;
147
- var canReplace = this.props.canReplace;
148
- return (0, _react2.jsx)("div", {
259
+ var _this$state2 = this.state,
260
+ replaceText = _this$state2.replaceText,
261
+ isHelperMessageVisible = _this$state2.isHelperMessageVisible,
262
+ replaceCount = _this$state2.replaceCount;
263
+ var _this$props = this.props,
264
+ canReplace = _this$props.canReplace,
265
+ count = _this$props.count,
266
+ formatMessage = _this$props.intl.formatMessage;
267
+ var resultsReplace = formatMessage(messages.replaceSuccess, {
268
+ numberOfMatches: replaceCount,
269
+ matchPluralSingularNoun: replaceCount > 1 ? formatMessage(messages.matchPluralNoun) : formatMessage(messages.matchSingularNoun)
270
+ });
271
+ return (0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-find-replace') ? (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)("div", {
272
+ css: [_styles.sectionWrapperStyles, _styles.sectionWrapperStylesAlternate]
273
+ }, (0, _react2.jsx)("div", {
274
+ css: _styles.textFieldWrapper
275
+ }, (0, _react2.jsx)(_form.Label, {
276
+ htmlFor: "replace-text-field"
277
+ }, "Replace with"), (0, _react2.jsx)(_textfield.default, {
278
+ name: "replace",
279
+ id: "replace-text-field",
280
+ appearance: "standard",
281
+ defaultValue: replaceText,
282
+ ref: this.replaceTextfieldRef,
283
+ autoComplete: "off",
284
+ onChange: this.handleReplaceChange,
285
+ onKeyDown: this.handleReplaceKeyDown,
286
+ onCompositionStart: this.handleCompositionStart,
287
+ onCompositionEnd: this.handleCompositionEnd
288
+ }), isHelperMessageVisible && this.props.findTyped === false && (0, _react2.jsx)("div", {
289
+ ref: this.successReplacementMessageRef
290
+ }, (0, _react2.jsx)(_form.ValidMessage, {
291
+ testId: "message-success-replacement"
292
+ },
293
+ /*
294
+ Replacement needed to trigger the SR announcement if message hasn't changed. e.g Replace button clicked twice.
295
+ '\u00a0' is value for &nbsp
296
+ */
297
+ this.state.fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(/ /, "\xA0") : resultsReplace)))), (0, _react2.jsx)("div", {
298
+ css: [_styles.sectionWrapperStyles, _styles.sectionWrapperStylesAlternate, _styles.sectionWrapperJustified]
299
+ }, (0, _react2.jsx)("div", {
300
+ css: _styles.orderOneStyles
301
+ }, (0, _react2.jsx)("div", {
302
+ css: _styles.NextPreviousItem
303
+ }, (0, _react2.jsx)(_FindReplaceTooltipButton.FindReplaceTooltipButton, {
304
+ title: this.findNext,
305
+ icon: this.findNextIcon,
306
+ keymapDescription: 'Enter',
307
+ onClick: this.handleFindNextClick,
308
+ disabled: count.total <= 1
309
+ })), (0, _react2.jsx)("div", {
310
+ css: _styles.NextPreviousItem
311
+ }, (0, _react2.jsx)(_FindReplaceTooltipButton.FindReplaceTooltipButton, {
312
+ title: this.findPrevious,
313
+ icon: this.findPrevIcon,
314
+ keymapDescription: 'Shift Enter',
315
+ onClick: this.handleFindPrevClick,
316
+ disabled: count.total <= 1
317
+ })), (0, _react2.jsx)(_standardButton.default, {
318
+ css: _styles.replaceSectionButtonStyles,
319
+ testId: this.replace,
320
+ id: "replace-button",
321
+ onClick: this.handleReplaceClick,
322
+ isDisabled: !canReplace
323
+ }, this.replace), (0, _react2.jsx)(_standardButton.default, {
324
+ css: _styles.replaceSectionButtonStyles,
325
+ appearance: "primary",
326
+ testId: this.replaceAll,
327
+ id: "replaceAll-button",
328
+ onClick: this.handleReplaceAllClick,
329
+ isDisabled: !canReplace
330
+ }, this.replaceAll)), (0, _react2.jsx)("div", {
331
+ css: _styles.orderZeroStyles
332
+ }, (0, _react2.jsx)(_standardButton.default, {
333
+ css: _styles.replaceSectionButtonStyles,
334
+ appearance: "subtle",
335
+ testId: this.closeFindReplaceDialog,
336
+ onClick: this.clearSearch
337
+ }, this.closeFindReplaceDialog)))) : (0, _react2.jsx)("div", {
149
338
  css: _styles.sectionWrapperStyles
150
339
  }, (0, _react2.jsx)(_textfield.default, {
151
340
  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
+ });
@@ -7,6 +7,7 @@ import debounce from 'lodash/debounce';
7
7
  import rafSchd from 'raf-schd';
8
8
  import { defineMessages, injectIntl } from 'react-intl-next';
9
9
  import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
10
+ import { Label } from '@atlaskit/form';
10
11
  import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
11
12
  import MatchCaseIcon from '@atlaskit/icon/glyph/emoji/keyboard';
12
13
  import ChevronDownIcon from '@atlaskit/icon/glyph/hipchat/chevron-down';
@@ -14,7 +15,7 @@ import ChevronUpIcon from '@atlaskit/icon/glyph/hipchat/chevron-up';
14
15
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
15
16
  import Textfield from '@atlaskit/textfield';
16
17
  import { FindReplaceTooltipButton } from './FindReplaceTooltipButton';
17
- import { countStyles, countWrapperStyles, sectionWrapperStyles } from './styles';
18
+ import { afterInputSection, countStyles, countStylesAlternateStyles, countWrapperStyles, matchCaseSection, sectionWrapperStyles, sectionWrapperStylesAlternate, textFieldWrapper } from './styles';
18
19
  export const FIND_DEBOUNCE_MS = 100;
19
20
  const messages = defineMessages({
20
21
  find: {
@@ -93,6 +94,7 @@ class Find extends React.Component {
93
94
  onSynced && onSynced();
94
95
  this.debouncedFind(value);
95
96
  });
97
+ this.props.setFindTyped(true);
96
98
  });
97
99
  // throtlle between animation frames gives better experience on Enter compared to arbitrary value
98
100
  // it adjusts based on performance (and document size)
@@ -169,7 +171,8 @@ class Find extends React.Component {
169
171
  this.findPrevious = formatMessage(messages.findPrevious);
170
172
  this.matchCase = formatMessage(messages.matchCase);
171
173
  this.matchCaseIcon = jsx(MatchCaseIcon, {
172
- label: this.matchCase
174
+ label: this.matchCase,
175
+ size: getBooleanFF('platform.editor.a11y-find-replace') ? 'small' : 'medium'
173
176
  });
174
177
  this.findNextIcon = jsx(ChevronDownIcon, {
175
178
  label: this.findNext
@@ -203,20 +206,18 @@ class Find extends React.Component {
203
206
  });
204
207
  }
205
208
  componentDidUpdate(prevProps) {
209
+ var _this$state2;
206
210
  // 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
- }
211
+ if (this.props.findText === ((_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.localFindText)) {
212
+ this.focusFindTextfield();
213
+ }
214
+ if (this.props.findText !== prevProps.findText) {
215
+ this.syncFindText(() => {
216
+ // focus after input is synced if find text provided
217
+ if (this.props.findText) {
218
+ this.focusFindTextfield();
219
+ }
220
+ });
220
221
  }
221
222
  }
222
223
  componentWillUnmount() {
@@ -237,50 +238,90 @@ class Find extends React.Component {
237
238
  selectedMatchPosition: count.index + 1,
238
239
  totalResultsCount: count.total
239
240
  });
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
- }));
241
+ if (getBooleanFF('platform.editor.a11y-find-replace')) {
242
+ const elemAfterInput = jsx("div", {
243
+ css: afterInputSection
244
+ }, jsx("div", {
245
+ "aria-live": "polite"
246
+ }, findText && jsx("span", {
247
+ "data-testid": "textfield-count",
248
+ css: [countStyles, countStylesAlternateStyles]
249
+ }, count.total === 0 ? this.noResultsFound : resultsCount)), allowMatchCase && jsx("div", {
250
+ css: matchCaseSection
251
+ }, jsx(FindReplaceTooltipButton, {
252
+ title: this.matchCase,
253
+ appearance: "default",
254
+ icon: this.matchCaseIcon,
255
+ onClick: this.handleMatchCaseClick,
256
+ isPressed: shouldMatchCase
257
+ })));
258
+ return jsx("div", {
259
+ css: [sectionWrapperStyles, sectionWrapperStylesAlternate]
260
+ }, jsx("div", {
261
+ css: textFieldWrapper
262
+ }, jsx(Label, {
263
+ htmlFor: "find-text-field"
264
+ }, this.find), jsx(Textfield, {
265
+ name: "find",
266
+ id: "find-text-field",
267
+ appearance: "standard",
268
+ value: this.state.localFindText,
269
+ ref: this.findTextfieldRef,
270
+ autoComplete: "off",
271
+ onChange: this.handleFindChange,
272
+ onKeyDown: this.handleFindKeyDown,
273
+ onKeyUp: this.handleFindKeyUp,
274
+ onBlur: this.props.onFindBlur,
275
+ onCompositionStart: this.handleCompositionStart,
276
+ onCompositionEnd: this.handleCompositionEnd,
277
+ elemAfterInput: elemAfterInput
278
+ })));
279
+ } else {
280
+ return jsx("div", {
281
+ css: sectionWrapperStyles
282
+ }, jsx(Textfield, {
283
+ name: "find",
284
+ appearance: "none",
285
+ placeholder: this.find,
286
+ value: this.state.localFindText,
287
+ ref: this.findTextfieldRef,
288
+ autoComplete: "off",
289
+ onChange: this.handleFindChange,
290
+ onKeyDown: this.handleFindKeyDown,
291
+ onKeyUp: this.handleFindKeyUp,
292
+ onBlur: this.props.onFindBlur,
293
+ onCompositionStart: this.handleCompositionStart,
294
+ onCompositionEnd: this.handleCompositionEnd
295
+ }), jsx("div", {
296
+ css: countWrapperStyles,
297
+ "aria-live": "polite"
298
+ }, findText && jsx("span", {
299
+ "data-testid": "textfield-count",
300
+ css: countStyles
301
+ }, count.total === 0 ? this.noResultsFound : resultsCount)), allowMatchCase && jsx(FindReplaceTooltipButton, {
302
+ title: this.matchCase,
303
+ icon: this.matchCaseIcon,
304
+ onClick: this.handleMatchCaseClick,
305
+ isPressed: shouldMatchCase
306
+ }), jsx(FindReplaceTooltipButton, {
307
+ title: this.findNext,
308
+ icon: this.findNextIcon,
309
+ keymapDescription: 'Enter',
310
+ onClick: this.handleFindNextClick,
311
+ disabled: count.total <= 1
312
+ }), jsx(FindReplaceTooltipButton, {
313
+ title: this.findPrevious,
314
+ icon: this.findPrevIcon,
315
+ keymapDescription: 'Shift Enter',
316
+ onClick: this.handleFindPrevClick,
317
+ disabled: count.total <= 1
318
+ }), jsx(FindReplaceTooltipButton, {
319
+ title: this.closeFindReplaceDialog,
320
+ icon: this.closeIcon,
321
+ keymapDescription: 'Escape',
322
+ onClick: this.clearSearch
323
+ }));
324
+ }
284
325
  }
285
326
  }
286
327
  export default injectIntl(Find);