@atlaskit/editor-plugin-find-replace 21.0.1 → 21.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/findReplacePlugin.js +12 -2
- package/dist/cjs/pm-plugins/commands-with-analytics.js +9 -2
- package/dist/cjs/pm-plugins/keymap.js +6 -6
- package/dist/cjs/pm-plugins/view-mode-shortcut.js +68 -0
- package/dist/cjs/ui/FindReplace.js +20 -4
- package/dist/cjs/ui/FindReplaceDropDownOrToolbarButtonWithState.js +18 -2
- package/dist/cjs/ui/Replace.js +13 -6
- package/dist/es2019/findReplacePlugin.js +10 -2
- package/dist/es2019/pm-plugins/commands-with-analytics.js +20 -10
- package/dist/es2019/pm-plugins/keymap.js +6 -6
- package/dist/es2019/pm-plugins/view-mode-shortcut.js +61 -0
- package/dist/es2019/ui/FindReplace.js +21 -5
- package/dist/es2019/ui/FindReplaceDropDownOrToolbarButtonWithState.js +12 -2
- package/dist/es2019/ui/Replace.js +12 -6
- package/dist/esm/findReplacePlugin.js +12 -2
- package/dist/esm/pm-plugins/commands-with-analytics.js +10 -2
- package/dist/esm/pm-plugins/keymap.js +6 -6
- package/dist/esm/pm-plugins/view-mode-shortcut.js +63 -0
- package/dist/esm/ui/FindReplace.js +22 -5
- package/dist/esm/ui/FindReplaceDropDownOrToolbarButtonWithState.js +18 -2
- package/dist/esm/ui/Replace.js +14 -7
- package/dist/types/findReplacePluginType.d.ts +2 -0
- package/dist/types/pm-plugins/commands-with-analytics.d.ts +8 -2
- package/dist/types/pm-plugins/keymap.d.ts +2 -1
- package/dist/types/pm-plugins/view-mode-shortcut.d.ts +10 -0
- package/dist/types/ui/FindReplace.d.ts +5 -0
- package/dist/types/ui/Replace.d.ts +6 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-find-replace
|
|
2
2
|
|
|
3
|
+
## 21.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`111eaadd44c1c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/111eaadd44c1c) -
|
|
8
|
+
EDITOR-8995: Make the editor find dialog usable in live view. The find dialog now accepts an
|
|
9
|
+
`allowReplace` prop, and hides the replace label, field, replacement count message, both replace
|
|
10
|
+
buttons and the horizontal rule when it is false. It also names the dialog "Find" instead of "Find
|
|
11
|
+
and Replace" in that state. The find plugin derives `allowReplace` from the `editorViewMode`
|
|
12
|
+
shared state, so view mode never offers replace. A new ProseMirror plugin opens the dialog on
|
|
13
|
+
`Mod-f` in view mode, where no keymap fires, behind the `platform_editor_collapsible_headings`
|
|
14
|
+
experiment. The `activated` analytics event gains an `editorViewMode` attribute.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
|
|
3
20
|
## 21.0.1
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -9,6 +9,7 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
10
10
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
11
|
var _types = require("@atlaskit/editor-common/types");
|
|
12
|
+
var _unsafeExpValNoExposure = require("@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure");
|
|
12
13
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
13
14
|
var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment");
|
|
14
15
|
var _commands = require("./pm-plugins/commands");
|
|
@@ -16,6 +17,7 @@ var _commandsWithAnalytics = require("./pm-plugins/commands-with-analytics");
|
|
|
16
17
|
var _keymap = _interopRequireDefault(require("./pm-plugins/keymap"));
|
|
17
18
|
var _main = require("./pm-plugins/main");
|
|
18
19
|
var _pluginKey = require("./pm-plugins/plugin-key");
|
|
20
|
+
var _viewModeShortcut = require("./pm-plugins/view-mode-shortcut");
|
|
19
21
|
var _FindReplaceDropDownOrToolbarButtonWithState = _interopRequireDefault(require("./ui/FindReplaceDropDownOrToolbarButtonWithState"));
|
|
20
22
|
var findReplacePlugin = exports.findReplacePlugin = function findReplacePlugin(_ref) {
|
|
21
23
|
var _api$primaryToolbar;
|
|
@@ -77,9 +79,17 @@ var findReplacePlugin = exports.findReplacePlugin = function findReplacePlugin(_
|
|
|
77
79
|
name: 'findReplaceKeymap',
|
|
78
80
|
plugin: function plugin() {
|
|
79
81
|
var _api$analytics;
|
|
80
|
-
return (0, _keymap.default)(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
82
|
+
return (0, _keymap.default)(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode);
|
|
81
83
|
}
|
|
82
84
|
}];
|
|
85
|
+
if (api !== null && api !== void 0 && api.editorViewMode && (0, _unsafeExpValNoExposure.UNSAFE_expValNoExposure)('platform_editor_collapsible_headings', 'isEnabled', false)) {
|
|
86
|
+
plugins.push({
|
|
87
|
+
name: 'findReplaceViewModeShortcut',
|
|
88
|
+
plugin: function plugin() {
|
|
89
|
+
return (0, _viewModeShortcut.viewModeShortcutPlugin)(api);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
83
93
|
if ((0, _editorExperiment.editorExperiment)('platform_editor_controls', 'variant1', {
|
|
84
94
|
exposure: false
|
|
85
95
|
})) {
|
|
@@ -138,7 +148,7 @@ var findReplacePlugin = exports.findReplacePlugin = function findReplacePlugin(_
|
|
|
138
148
|
dispatch = _editorViewRef$curren.dispatch;
|
|
139
149
|
if (api !== null && api !== void 0 && (_api$analytics2 = api.analytics) !== null && _api$analytics2 !== void 0 && _api$analytics2.actions) {
|
|
140
150
|
var _api$analytics3;
|
|
141
|
-
(0, _commandsWithAnalytics.activateWithAnalytics)(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions)({
|
|
151
|
+
(0, _commandsWithAnalytics.activateWithAnalytics)(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
142
152
|
triggerMethod: triggerMethod || _analytics.TRIGGER_METHOD.EXTERNAL
|
|
143
153
|
})(state, dispatch);
|
|
144
154
|
} else {
|
|
@@ -8,17 +8,24 @@ var _analytics = require("@atlaskit/editor-common/analytics");
|
|
|
8
8
|
var _editorAnalytics = require("@atlaskit/editor-common/editor-analytics");
|
|
9
9
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
10
10
|
var _commands = require("./commands");
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Hosts that do not install `editorViewMode` are always editing, so the attribute
|
|
13
|
+
* falls back to `edit` when the api is absent.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var activateWithAnalytics = exports.activateWithAnalytics = function activateWithAnalytics(editorAnalyticsAPI, editorViewModeAPI) {
|
|
12
17
|
return function (_ref) {
|
|
13
18
|
var triggerMethod = _ref.triggerMethod;
|
|
14
19
|
return (0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, function (state) {
|
|
20
|
+
var _editorViewModeAPI$sh, _editorViewModeAPI$sh2;
|
|
15
21
|
return {
|
|
16
22
|
eventType: _analytics.EVENT_TYPE.UI,
|
|
17
23
|
action: _analytics.ACTION.ACTIVATED,
|
|
18
24
|
actionSubject: _analytics.ACTION_SUBJECT.FIND_REPLACE_DIALOG,
|
|
19
25
|
attributes: {
|
|
20
26
|
inputMethod: state.selection instanceof _state.TextSelection && !state.selection.empty ? _analytics.INPUT_METHOD.PREFILL : _analytics.INPUT_METHOD.KEYBOARD,
|
|
21
|
-
triggerMethod: triggerMethod
|
|
27
|
+
triggerMethod: triggerMethod,
|
|
28
|
+
editorViewMode: (_editorViewModeAPI$sh = editorViewModeAPI === null || editorViewModeAPI === void 0 || (_editorViewModeAPI$sh2 = editorViewModeAPI.sharedState.currentState()) === null || _editorViewModeAPI$sh2 === void 0 ? void 0 : _editorViewModeAPI$sh2.mode) !== null && _editorViewModeAPI$sh !== void 0 ? _editorViewModeAPI$sh : 'edit'
|
|
22
29
|
}
|
|
23
30
|
};
|
|
24
31
|
})((0, _commands.activate)());
|
|
@@ -8,19 +8,19 @@ var _analytics = require("@atlaskit/editor-common/analytics");
|
|
|
8
8
|
var _keymaps = require("@atlaskit/editor-common/keymaps");
|
|
9
9
|
var _keymap = require("@atlaskit/editor-prosemirror/keymap");
|
|
10
10
|
var _commandsWithAnalytics = require("./commands-with-analytics");
|
|
11
|
-
var activateFindReplace = function activateFindReplace(editorAnalyticsAPI) {
|
|
11
|
+
var activateFindReplace = function activateFindReplace(editorAnalyticsAPI, editorViewModeAPI) {
|
|
12
12
|
return function (state, dispatch) {
|
|
13
|
-
(0, _commandsWithAnalytics.activateWithAnalytics)(editorAnalyticsAPI)({
|
|
13
|
+
(0, _commandsWithAnalytics.activateWithAnalytics)(editorAnalyticsAPI, editorViewModeAPI)({
|
|
14
14
|
triggerMethod: _analytics.TRIGGER_METHOD.SHORTCUT
|
|
15
15
|
})(state, dispatch);
|
|
16
16
|
return true;
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
-
var keymapPlugin = function keymapPlugin(editorAnalyticsAPI) {
|
|
19
|
+
var keymapPlugin = function keymapPlugin(editorAnalyticsAPI, editorViewModeAPI) {
|
|
20
20
|
var list = {};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (_keymaps.find.common) {
|
|
22
|
+
(0, _keymaps.bindKeymapWithCommand)(_keymaps.find.common, activateFindReplace(editorAnalyticsAPI, editorViewModeAPI), list);
|
|
23
|
+
}
|
|
24
24
|
return (0, _keymap.keymap)(list);
|
|
25
25
|
};
|
|
26
26
|
var _default = exports.default = keymapPlugin;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.viewModeShortcutPlugin = void 0;
|
|
7
|
+
var _bindEventListener = require("bind-event-listener");
|
|
8
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
9
|
+
var _keymaps = require("@atlaskit/editor-common/keymaps");
|
|
10
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
|
+
var _keymap = require("@atlaskit/editor-prosemirror/keymap");
|
|
12
|
+
var _commandsWithAnalytics = require("./commands-with-analytics");
|
|
13
|
+
/**
|
|
14
|
+
* Whether the event came from a field the user is typing into. `Mod-f` belongs to
|
|
15
|
+
* that field, not to us.
|
|
16
|
+
*/
|
|
17
|
+
var isFromTextEntry = function isFromTextEntry(event) {
|
|
18
|
+
var target = event.target;
|
|
19
|
+
return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
20
|
+
};
|
|
21
|
+
var activateInViewMode = function activateInViewMode(api) {
|
|
22
|
+
return function (state, dispatch) {
|
|
23
|
+
var _api$editorViewMode, _api$analytics;
|
|
24
|
+
// In edit mode `./keymap.ts` already handles `Mod-f`. Handling it here as well
|
|
25
|
+
// would activate the dialog twice from a single keypress.
|
|
26
|
+
if ((api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode) !== 'view') {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
(0, _commandsWithAnalytics.activateWithAnalytics)(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
30
|
+
triggerMethod: _analytics.TRIGGER_METHOD.SHORTCUT
|
|
31
|
+
})(state, dispatch);
|
|
32
|
+
return true;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Opens the find dialog on `Mod-f` while the editor is in view mode.
|
|
38
|
+
*
|
|
39
|
+
* The listener is bound on the document so that it still fires in view mode, where
|
|
40
|
+
* ProseMirror delivers the keydown to neither `keymap()` nor `handleDOMEvents`.
|
|
41
|
+
*/
|
|
42
|
+
var viewModeShortcutPlugin = exports.viewModeShortcutPlugin = function viewModeShortcutPlugin(api) {
|
|
43
|
+
var bindings = {};
|
|
44
|
+
if (_keymaps.find.common) {
|
|
45
|
+
(0, _keymaps.bindKeymapWithCommand)(_keymaps.find.common, activateInViewMode(api), bindings);
|
|
46
|
+
}
|
|
47
|
+
var handleKeydown = (0, _keymap.keydownHandler)(bindings);
|
|
48
|
+
return new _safePlugin.SafePlugin({
|
|
49
|
+
view: function view(_view) {
|
|
50
|
+
var unbind = (0, _bindEventListener.bind)(_view.root, {
|
|
51
|
+
type: 'keydown',
|
|
52
|
+
listener: function listener(event) {
|
|
53
|
+
// `view.root` is `Document | ShadowRoot`, so the binding widens the event.
|
|
54
|
+
if (!(event instanceof KeyboardEvent) || isFromTextEntry(event)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (handleKeydown(_view, event)) {
|
|
58
|
+
// Without this the browser find bar opens on top of our dialog.
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
destroy: unbind
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
@@ -22,6 +22,17 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
22
22
|
* @jsxRuntime classic
|
|
23
23
|
* @jsx jsx
|
|
24
24
|
*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
|
|
25
|
+
// Magic number taken from ./FindReplaceToolbarButton.tsx
|
|
26
|
+
var dropdownWidth = 382;
|
|
27
|
+
|
|
28
|
+
// Without replace the find row is the widest row, so the popup would size to it and
|
|
29
|
+
// change width as the match counter appears. Pin it to the width the dropdown reserves.
|
|
30
|
+
var findOnlyWidthStyles = (0, _react2.css)({
|
|
31
|
+
boxSizing: 'border-box',
|
|
32
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
33
|
+
width: "".concat(dropdownWidth, "px"),
|
|
34
|
+
maxWidth: '100%'
|
|
35
|
+
});
|
|
25
36
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
26
37
|
var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
27
38
|
function FindReplace(props) {
|
|
@@ -78,16 +89,18 @@ var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
78
89
|
allowMatchCase = _this$props.allowMatchCase,
|
|
79
90
|
shouldMatchCase = _this$props.shouldMatchCase,
|
|
80
91
|
onToggleMatchCase = _this$props.onToggleMatchCase,
|
|
81
|
-
intl = _this$props.intl
|
|
92
|
+
intl = _this$props.intl,
|
|
93
|
+
_this$props$allowRepl = _this$props.allowReplace,
|
|
94
|
+
allowReplace = _this$props$allowRepl === void 0 ? true : _this$props$allowRepl;
|
|
82
95
|
var focusToolbarButton = this.props.focusToolbarButton || function () {};
|
|
83
96
|
return (0, _react2.jsx)("div", {
|
|
84
97
|
role: 'dialog',
|
|
85
|
-
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(_messages.findReplaceMessages.findReplaceDialogAriaLabel),
|
|
98
|
+
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(allowReplace ? _messages.findReplaceMessages.findReplaceDialogAriaLabel : _messages.findReplaceMessages.findDialogAriaLabel),
|
|
86
99
|
"aria-modal": false,
|
|
87
100
|
ref: this.modalRef
|
|
88
101
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
89
102
|
,
|
|
90
|
-
css: [_uiStyles.wrapperStyles, _uiStyles.wrapperPaddingStyles]
|
|
103
|
+
css: [_uiStyles.wrapperStyles, _uiStyles.wrapperPaddingStyles, !allowReplace && findOnlyWidthStyles]
|
|
91
104
|
}, (0, _react2.jsx)(_Find.default, {
|
|
92
105
|
allowMatchCase: allowMatchCase,
|
|
93
106
|
shouldMatchCase: shouldMatchCase,
|
|
@@ -104,11 +117,14 @@ var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
104
117
|
onArrowDown: this.setFocusToReplace,
|
|
105
118
|
findTyped: this.state.findTyped,
|
|
106
119
|
setFindTyped: this.setFindTyped
|
|
107
|
-
}),
|
|
120
|
+
}), allowReplace &&
|
|
121
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
122
|
+
(0, _react2.jsx)("hr", {
|
|
108
123
|
role: "presentation",
|
|
109
124
|
css: _uiStyles.ruleStyles,
|
|
110
125
|
id: "replace-hr-element"
|
|
111
126
|
}), (0, _react2.jsx)(_Replace.default, {
|
|
127
|
+
allowReplace: allowReplace,
|
|
112
128
|
canReplace: !!isReplaceable,
|
|
113
129
|
replaceText: replaceText,
|
|
114
130
|
onReplace: onReplace,
|
|
@@ -9,6 +9,9 @@ exports.default = void 0;
|
|
|
9
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
11
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
12
|
+
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
13
|
+
var _unsafeExpValNoExposure = require("@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure");
|
|
14
|
+
var _conditionalHooksFactory = require("@atlaskit/platform-feature-flags-react/conditional-hooks-factory/conditional-hooks-factory");
|
|
12
15
|
var _commands = require("../pm-plugins/commands");
|
|
13
16
|
var _commandsWithAnalytics = require("../pm-plugins/commands-with-analytics");
|
|
14
17
|
var _FindReplaceDropdown = _interopRequireDefault(require("./FindReplaceDropdown"));
|
|
@@ -39,6 +42,16 @@ var useSharedPluginStateNoDebounce = function useSharedPluginStateNoDebounce(api
|
|
|
39
42
|
findReplaceState: state
|
|
40
43
|
};
|
|
41
44
|
};
|
|
45
|
+
var useEditorViewMode = (0, _conditionalHooksFactory.conditionalHooksFactory)(function () {
|
|
46
|
+
return (0, _unsafeExpValNoExposure.UNSAFE_expValNoExposure)('platform_editor_collapsible_headings', 'isEnabled', false);
|
|
47
|
+
}, function (api) {
|
|
48
|
+
return (0, _hooks.useSharedPluginStateWithSelector)(api, ['editorViewMode'], function (states) {
|
|
49
|
+
var _states$editorViewMod;
|
|
50
|
+
return (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode;
|
|
51
|
+
});
|
|
52
|
+
}, function () {
|
|
53
|
+
return undefined;
|
|
54
|
+
});
|
|
42
55
|
var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithState(_ref2) {
|
|
43
56
|
var _api$analytics, _matches$index;
|
|
44
57
|
var popupsBoundariesElement = _ref2.popupsBoundariesElement,
|
|
@@ -55,6 +68,8 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
55
68
|
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
56
69
|
var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
|
|
57
70
|
findReplaceState = _useSharedPluginState.findReplaceState;
|
|
71
|
+
var editorViewMode = useEditorViewMode(api);
|
|
72
|
+
var allowReplace = editorViewMode !== 'view';
|
|
58
73
|
var shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
|
|
59
74
|
var isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
|
|
60
75
|
var findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
|
|
@@ -82,7 +97,7 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
82
97
|
};
|
|
83
98
|
var handleActivate = function handleActivate() {
|
|
84
99
|
runWithEditorFocused(function () {
|
|
85
|
-
return dispatchCommand((0, _commandsWithAnalytics.activateWithAnalytics)(editorAnalyticsAPI)({
|
|
100
|
+
return dispatchCommand((0, _commandsWithAnalytics.activateWithAnalytics)(editorAnalyticsAPI, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
86
101
|
triggerMethod: _analytics.TRIGGER_METHOD.TOOLBAR
|
|
87
102
|
}));
|
|
88
103
|
});
|
|
@@ -176,7 +191,8 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
176
191
|
onReplace: handleReplace,
|
|
177
192
|
onReplaceAll: handleReplaceAll,
|
|
178
193
|
takeFullWidth: !!takeFullWidth,
|
|
179
|
-
isButtonHidden: isButtonHidden
|
|
194
|
+
isButtonHidden: isButtonHidden,
|
|
195
|
+
allowReplace: allowReplace
|
|
180
196
|
});
|
|
181
197
|
};
|
|
182
198
|
var _default_1 = /*#__PURE__*/_react.default.memo(FindReplaceToolbarButtonWithState);
|
package/dist/cjs/ui/Replace.js
CHANGED
|
@@ -31,6 +31,11 @@ var replaceWithLabelStyle = (0, _primitives.xcss)({
|
|
|
31
31
|
var actionButtonContainerStyles = (0, _primitives.xcss)({
|
|
32
32
|
paddingTop: 'space.200'
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
// Without the replace field above it, the button row needs no separating space.
|
|
36
|
+
var findOnlyActionButtonContainerStyles = (0, _primitives.xcss)({
|
|
37
|
+
paddingTop: 'space.0'
|
|
38
|
+
});
|
|
34
39
|
var actionButtonParentInlineStyles = (0, _primitives.xcss)({
|
|
35
40
|
justifyContent: 'space-between',
|
|
36
41
|
flexDirection: 'row-reverse',
|
|
@@ -44,7 +49,9 @@ var closeButtonInlineStyles = (0, _primitives.xcss)({
|
|
|
44
49
|
marginRight: 'auto'
|
|
45
50
|
});
|
|
46
51
|
var Replace = function Replace(_ref) {
|
|
47
|
-
var
|
|
52
|
+
var _ref$allowReplace = _ref.allowReplace,
|
|
53
|
+
allowReplace = _ref$allowReplace === void 0 ? true : _ref$allowReplace,
|
|
54
|
+
canReplace = _ref.canReplace,
|
|
48
55
|
initialReplaceText = _ref.replaceText,
|
|
49
56
|
onReplace = _ref.onReplace,
|
|
50
57
|
onReplaceAll = _ref.onReplaceAll,
|
|
@@ -194,7 +201,7 @@ var Replace = function Replace(_ref) {
|
|
|
194
201
|
});
|
|
195
202
|
return /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
196
203
|
xcss: replaceContainerStyles
|
|
197
|
-
}, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
204
|
+
}, allowReplace && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
198
205
|
xcss: replaceWithLabelStyle
|
|
199
206
|
}, /*#__PURE__*/_react.default.createElement(_primitives.Text, {
|
|
200
207
|
id: "replace-text-field-label",
|
|
@@ -217,8 +224,8 @@ var Replace = function Replace(_ref) {
|
|
|
217
224
|
ref: successReplacementMessageRef
|
|
218
225
|
}, /*#__PURE__*/_react.default.createElement(_validMessage.ValidMessage, {
|
|
219
226
|
testId: "message-success-replacement"
|
|
220
|
-
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, "\xA0") : resultsReplace)), /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
221
|
-
xcss: actionButtonContainerStyles
|
|
227
|
+
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, "\xA0") : resultsReplace))), /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
228
|
+
xcss: allowReplace ? actionButtonContainerStyles : findOnlyActionButtonContainerStyles
|
|
222
229
|
}, /*#__PURE__*/_react.default.createElement(_primitives.Inline, {
|
|
223
230
|
xcss: actionButtonParentInlineStyles
|
|
224
231
|
}, /*#__PURE__*/_react.default.createElement(_primitives.Inline, {
|
|
@@ -251,7 +258,7 @@ var Replace = function Replace(_ref) {
|
|
|
251
258
|
keymapDescription: 'Shift Enter',
|
|
252
259
|
onClick: handleFindPrevClick,
|
|
253
260
|
disabled: count.total <= 1
|
|
254
|
-
}), /*#__PURE__*/_react.default.createElement(_button.default, {
|
|
261
|
+
}), allowReplace && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_button.default, {
|
|
255
262
|
testId: 'Replace',
|
|
256
263
|
id: "replace-button",
|
|
257
264
|
onClick: handleReplaceClick,
|
|
@@ -262,7 +269,7 @@ var Replace = function Replace(_ref) {
|
|
|
262
269
|
id: "replaceAll-button",
|
|
263
270
|
onClick: handleReplaceAllClick,
|
|
264
271
|
isDisabled: count.totalReplaceable === 0
|
|
265
|
-
}, replaceAll)), /*#__PURE__*/_react.default.createElement(_primitives.Inline, {
|
|
272
|
+
}, replaceAll))), /*#__PURE__*/_react.default.createElement(_primitives.Inline, {
|
|
266
273
|
xcss: closeButtonInlineStyles
|
|
267
274
|
}, /*#__PURE__*/_react.default.createElement(_button.default, {
|
|
268
275
|
appearance: "subtle",
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
4
|
import { ToolbarSize } from '@atlaskit/editor-common/types';
|
|
5
|
+
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
5
6
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
6
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
7
8
|
import { activate } from './pm-plugins/commands';
|
|
@@ -9,6 +10,7 @@ import { activateWithAnalytics } from './pm-plugins/commands-with-analytics';
|
|
|
9
10
|
import keymapPlugin from './pm-plugins/keymap';
|
|
10
11
|
import { createPlugin } from './pm-plugins/main';
|
|
11
12
|
import { findReplacePluginKey } from './pm-plugins/plugin-key';
|
|
13
|
+
import { viewModeShortcutPlugin } from './pm-plugins/view-mode-shortcut';
|
|
12
14
|
import FindReplaceDropDownOrToolbarButtonWithState from './ui/FindReplaceDropDownOrToolbarButtonWithState';
|
|
13
15
|
export const findReplacePlugin = ({
|
|
14
16
|
config: props,
|
|
@@ -71,9 +73,15 @@ export const findReplacePlugin = ({
|
|
|
71
73
|
name: 'findReplaceKeymap',
|
|
72
74
|
plugin: () => {
|
|
73
75
|
var _api$analytics;
|
|
74
|
-
return keymapPlugin(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
76
|
+
return keymapPlugin(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode);
|
|
75
77
|
}
|
|
76
78
|
}];
|
|
79
|
+
if (api !== null && api !== void 0 && api.editorViewMode && UNSAFE_expValNoExposure('platform_editor_collapsible_headings', 'isEnabled', false)) {
|
|
80
|
+
plugins.push({
|
|
81
|
+
name: 'findReplaceViewModeShortcut',
|
|
82
|
+
plugin: () => viewModeShortcutPlugin(api)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
77
85
|
if (editorExperiment('platform_editor_controls', 'variant1', {
|
|
78
86
|
exposure: false
|
|
79
87
|
})) {
|
|
@@ -134,7 +142,7 @@ export const findReplacePlugin = ({
|
|
|
134
142
|
} = editorViewRef.current;
|
|
135
143
|
if (api !== null && api !== void 0 && (_api$analytics2 = api.analytics) !== null && _api$analytics2 !== void 0 && _api$analytics2.actions) {
|
|
136
144
|
var _api$analytics3;
|
|
137
|
-
activateWithAnalytics(api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions)({
|
|
145
|
+
activateWithAnalytics(api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
138
146
|
triggerMethod: triggerMethod || TRIGGER_METHOD.EXTERNAL
|
|
139
147
|
})(state, dispatch);
|
|
140
148
|
} else {
|
|
@@ -2,17 +2,27 @@ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/edit
|
|
|
2
2
|
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
|
3
3
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import { activate, cancelSearch, find, findNext, findPrevious, replace, replaceAll } from './commands';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hosts that do not install `editorViewMode` are always editing, so the attribute
|
|
8
|
+
* falls back to `edit` when the api is absent.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const activateWithAnalytics = (editorAnalyticsAPI, editorViewModeAPI) => ({
|
|
6
12
|
triggerMethod
|
|
7
|
-
}) => withAnalytics(editorAnalyticsAPI, state =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
}) => withAnalytics(editorAnalyticsAPI, state => {
|
|
14
|
+
var _editorViewModeAPI$sh, _editorViewModeAPI$sh2;
|
|
15
|
+
return {
|
|
16
|
+
eventType: EVENT_TYPE.UI,
|
|
17
|
+
action: ACTION.ACTIVATED,
|
|
18
|
+
actionSubject: ACTION_SUBJECT.FIND_REPLACE_DIALOG,
|
|
19
|
+
attributes: {
|
|
20
|
+
inputMethod: state.selection instanceof TextSelection && !state.selection.empty ? INPUT_METHOD.PREFILL : INPUT_METHOD.KEYBOARD,
|
|
21
|
+
triggerMethod,
|
|
22
|
+
editorViewMode: (_editorViewModeAPI$sh = editorViewModeAPI === null || editorViewModeAPI === void 0 ? void 0 : (_editorViewModeAPI$sh2 = editorViewModeAPI.sharedState.currentState()) === null || _editorViewModeAPI$sh2 === void 0 ? void 0 : _editorViewModeAPI$sh2.mode) !== null && _editorViewModeAPI$sh !== void 0 ? _editorViewModeAPI$sh : 'edit'
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
})(activate());
|
|
16
26
|
export const findWithAnalytics = editorAnalyticsAPI => ({
|
|
17
27
|
editorView,
|
|
18
28
|
containerElement,
|
|
@@ -2,17 +2,17 @@ import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
|
2
2
|
import { bindKeymapWithCommand, find as findKeymap } from '@atlaskit/editor-common/keymaps';
|
|
3
3
|
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
4
4
|
import { activateWithAnalytics } from './commands-with-analytics';
|
|
5
|
-
const activateFindReplace = editorAnalyticsAPI => (state, dispatch) => {
|
|
6
|
-
activateWithAnalytics(editorAnalyticsAPI)({
|
|
5
|
+
const activateFindReplace = (editorAnalyticsAPI, editorViewModeAPI) => (state, dispatch) => {
|
|
6
|
+
activateWithAnalytics(editorAnalyticsAPI, editorViewModeAPI)({
|
|
7
7
|
triggerMethod: TRIGGER_METHOD.SHORTCUT
|
|
8
8
|
})(state, dispatch);
|
|
9
9
|
return true;
|
|
10
10
|
};
|
|
11
|
-
const keymapPlugin = editorAnalyticsAPI => {
|
|
11
|
+
const keymapPlugin = (editorAnalyticsAPI, editorViewModeAPI) => {
|
|
12
12
|
const list = {};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if (findKeymap.common) {
|
|
14
|
+
bindKeymapWithCommand(findKeymap.common, activateFindReplace(editorAnalyticsAPI, editorViewModeAPI), list);
|
|
15
|
+
}
|
|
16
16
|
return keymap(list);
|
|
17
17
|
};
|
|
18
18
|
export default keymapPlugin;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { bindKeymapWithCommand, find as findKeymap } from '@atlaskit/editor-common/keymaps';
|
|
4
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
5
|
+
import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
|
|
6
|
+
import { activateWithAnalytics } from './commands-with-analytics';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Whether the event came from a field the user is typing into. `Mod-f` belongs to
|
|
10
|
+
* that field, not to us.
|
|
11
|
+
*/
|
|
12
|
+
const isFromTextEntry = event => {
|
|
13
|
+
const target = event.target;
|
|
14
|
+
return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
15
|
+
};
|
|
16
|
+
const activateInViewMode = api => (state, dispatch) => {
|
|
17
|
+
var _api$editorViewMode, _api$editorViewMode$s, _api$analytics;
|
|
18
|
+
// In edit mode `./keymap.ts` already handles `Mod-f`. Handling it here as well
|
|
19
|
+
// would activate the dialog twice from a single keypress.
|
|
20
|
+
if ((api === null || api === void 0 ? void 0 : (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : (_api$editorViewMode$s = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode$s === void 0 ? void 0 : _api$editorViewMode$s.mode) !== 'view') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
activateWithAnalytics(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
24
|
+
triggerMethod: TRIGGER_METHOD.SHORTCUT
|
|
25
|
+
})(state, dispatch);
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Opens the find dialog on `Mod-f` while the editor is in view mode.
|
|
31
|
+
*
|
|
32
|
+
* The listener is bound on the document so that it still fires in view mode, where
|
|
33
|
+
* ProseMirror delivers the keydown to neither `keymap()` nor `handleDOMEvents`.
|
|
34
|
+
*/
|
|
35
|
+
export const viewModeShortcutPlugin = api => {
|
|
36
|
+
const bindings = {};
|
|
37
|
+
if (findKeymap.common) {
|
|
38
|
+
bindKeymapWithCommand(findKeymap.common, activateInViewMode(api), bindings);
|
|
39
|
+
}
|
|
40
|
+
const handleKeydown = keydownHandler(bindings);
|
|
41
|
+
return new SafePlugin({
|
|
42
|
+
view: view => {
|
|
43
|
+
const unbind = bind(view.root, {
|
|
44
|
+
type: 'keydown',
|
|
45
|
+
listener: event => {
|
|
46
|
+
// `view.root` is `Document | ShadowRoot`, so the binding widens the event.
|
|
47
|
+
if (!(event instanceof KeyboardEvent) || isFromTextEntry(event)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (handleKeydown(view, event)) {
|
|
51
|
+
// Without this the browser find bar opens on top of our dialog.
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
destroy: unbind
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
@@ -9,11 +9,23 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
|
|
12
|
-
import { jsx } from '@emotion/react';
|
|
12
|
+
import { css, jsx } from '@emotion/react';
|
|
13
13
|
import { findReplaceMessages as messages } from '@atlaskit/editor-common/messages';
|
|
14
14
|
import Find from './Find';
|
|
15
15
|
import Replace from './Replace';
|
|
16
16
|
import { ruleStyles, wrapperPaddingStyles, wrapperStyles } from './ui-styles';
|
|
17
|
+
|
|
18
|
+
// Magic number taken from ./FindReplaceToolbarButton.tsx
|
|
19
|
+
const dropdownWidth = 382;
|
|
20
|
+
|
|
21
|
+
// Without replace the find row is the widest row, so the popup would size to it and
|
|
22
|
+
// change width as the match counter appears. Pin it to the width the dropdown reserves.
|
|
23
|
+
const findOnlyWidthStyles = css({
|
|
24
|
+
boxSizing: 'border-box',
|
|
25
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
26
|
+
width: `${dropdownWidth}px`,
|
|
27
|
+
maxWidth: '100%'
|
|
28
|
+
});
|
|
17
29
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
18
30
|
class FindReplace extends React.PureComponent {
|
|
19
31
|
constructor(props) {
|
|
@@ -64,17 +76,18 @@ class FindReplace extends React.PureComponent {
|
|
|
64
76
|
allowMatchCase,
|
|
65
77
|
shouldMatchCase,
|
|
66
78
|
onToggleMatchCase,
|
|
67
|
-
intl
|
|
79
|
+
intl,
|
|
80
|
+
allowReplace = true
|
|
68
81
|
} = this.props;
|
|
69
82
|
const focusToolbarButton = this.props.focusToolbarButton || (() => {});
|
|
70
83
|
return jsx("div", {
|
|
71
84
|
role: 'dialog',
|
|
72
|
-
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(messages.findReplaceDialogAriaLabel),
|
|
85
|
+
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(allowReplace ? messages.findReplaceDialogAriaLabel : messages.findDialogAriaLabel),
|
|
73
86
|
"aria-modal": false,
|
|
74
87
|
ref: this.modalRef
|
|
75
88
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
76
89
|
,
|
|
77
|
-
css: [wrapperStyles, wrapperPaddingStyles]
|
|
90
|
+
css: [wrapperStyles, wrapperPaddingStyles, !allowReplace && findOnlyWidthStyles]
|
|
78
91
|
}, jsx(Find, {
|
|
79
92
|
allowMatchCase: allowMatchCase,
|
|
80
93
|
shouldMatchCase: shouldMatchCase,
|
|
@@ -91,11 +104,14 @@ class FindReplace extends React.PureComponent {
|
|
|
91
104
|
onArrowDown: this.setFocusToReplace,
|
|
92
105
|
findTyped: this.state.findTyped,
|
|
93
106
|
setFindTyped: this.setFindTyped
|
|
94
|
-
}),
|
|
107
|
+
}), allowReplace &&
|
|
108
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
109
|
+
jsx("hr", {
|
|
95
110
|
role: "presentation",
|
|
96
111
|
css: ruleStyles,
|
|
97
112
|
id: "replace-hr-element"
|
|
98
113
|
}), jsx(Replace, {
|
|
114
|
+
allowReplace: allowReplace,
|
|
99
115
|
canReplace: !!isReplaceable,
|
|
100
116
|
replaceText: replaceText,
|
|
101
117
|
onReplace: onReplace,
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import React, { useLayoutEffect, useState } from 'react';
|
|
2
2
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
|
+
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
5
|
+
import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react/conditional-hooks-factory/conditional-hooks-factory';
|
|
3
6
|
import { blur, toggleMatchCase } from '../pm-plugins/commands';
|
|
4
7
|
import { activateWithAnalytics, cancelSearchWithAnalytics, findNextWithAnalytics, findPrevWithAnalytics, findWithAnalytics, replaceAllWithAnalytics, replaceWithAnalytics } from '../pm-plugins/commands-with-analytics';
|
|
5
8
|
import FindReplaceDropdown from './FindReplaceDropdown';
|
|
@@ -28,6 +31,10 @@ const useSharedPluginStateNoDebounce = api => {
|
|
|
28
31
|
findReplaceState: state
|
|
29
32
|
};
|
|
30
33
|
};
|
|
34
|
+
const useEditorViewMode = conditionalHooksFactory(() => UNSAFE_expValNoExposure('platform_editor_collapsible_headings', 'isEnabled', false), api => useSharedPluginStateWithSelector(api, ['editorViewMode'], states => {
|
|
35
|
+
var _states$editorViewMod;
|
|
36
|
+
return (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode;
|
|
37
|
+
}), () => undefined);
|
|
31
38
|
const FindReplaceToolbarButtonWithState = ({
|
|
32
39
|
popupsBoundariesElement,
|
|
33
40
|
popupsMountPoint,
|
|
@@ -46,6 +53,8 @@ const FindReplaceToolbarButtonWithState = ({
|
|
|
46
53
|
const {
|
|
47
54
|
findReplaceState
|
|
48
55
|
} = useSharedPluginStateNoDebounce(api);
|
|
56
|
+
const editorViewMode = useEditorViewMode(api);
|
|
57
|
+
const allowReplace = editorViewMode !== 'view';
|
|
49
58
|
const shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
|
|
50
59
|
const isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
|
|
51
60
|
const findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
|
|
@@ -74,7 +83,7 @@ const FindReplaceToolbarButtonWithState = ({
|
|
|
74
83
|
cmd(state, dispatch, editorView);
|
|
75
84
|
};
|
|
76
85
|
const handleActivate = () => {
|
|
77
|
-
runWithEditorFocused(() => dispatchCommand(activateWithAnalytics(editorAnalyticsAPI)({
|
|
86
|
+
runWithEditorFocused(() => dispatchCommand(activateWithAnalytics(editorAnalyticsAPI, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
78
87
|
triggerMethod: TRIGGER_METHOD.TOOLBAR
|
|
79
88
|
})));
|
|
80
89
|
};
|
|
@@ -160,7 +169,8 @@ const FindReplaceToolbarButtonWithState = ({
|
|
|
160
169
|
onReplace: handleReplace,
|
|
161
170
|
onReplaceAll: handleReplaceAll,
|
|
162
171
|
takeFullWidth: !!takeFullWidth,
|
|
163
|
-
isButtonHidden: isButtonHidden
|
|
172
|
+
isButtonHidden: isButtonHidden,
|
|
173
|
+
allowReplace: allowReplace
|
|
164
174
|
});
|
|
165
175
|
};
|
|
166
176
|
const _default_1 = /*#__PURE__*/React.memo(FindReplaceToolbarButtonWithState);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
1
|
+
import React, { Fragment, useState, useRef, useEffect } from 'react';
|
|
2
2
|
import { injectIntl } from 'react-intl';
|
|
3
3
|
import Button from '@atlaskit/button/default/button';
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
@@ -20,6 +20,11 @@ const replaceWithLabelStyle = xcss({
|
|
|
20
20
|
const actionButtonContainerStyles = xcss({
|
|
21
21
|
paddingTop: 'space.200'
|
|
22
22
|
});
|
|
23
|
+
|
|
24
|
+
// Without the replace field above it, the button row needs no separating space.
|
|
25
|
+
const findOnlyActionButtonContainerStyles = xcss({
|
|
26
|
+
paddingTop: 'space.0'
|
|
27
|
+
});
|
|
23
28
|
const actionButtonParentInlineStyles = xcss({
|
|
24
29
|
justifyContent: 'space-between',
|
|
25
30
|
flexDirection: 'row-reverse',
|
|
@@ -33,6 +38,7 @@ const closeButtonInlineStyles = xcss({
|
|
|
33
38
|
marginRight: 'auto'
|
|
34
39
|
});
|
|
35
40
|
const Replace = ({
|
|
41
|
+
allowReplace = true,
|
|
36
42
|
canReplace,
|
|
37
43
|
replaceText: initialReplaceText,
|
|
38
44
|
onReplace,
|
|
@@ -163,7 +169,7 @@ const Replace = ({
|
|
|
163
169
|
});
|
|
164
170
|
return /*#__PURE__*/React.createElement(Box, {
|
|
165
171
|
xcss: replaceContainerStyles
|
|
166
|
-
}, /*#__PURE__*/React.createElement(Box, {
|
|
172
|
+
}, allowReplace && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Box, {
|
|
167
173
|
xcss: replaceWithLabelStyle
|
|
168
174
|
}, /*#__PURE__*/React.createElement(Text, {
|
|
169
175
|
id: "replace-text-field-label",
|
|
@@ -186,8 +192,8 @@ const Replace = ({
|
|
|
186
192
|
ref: successReplacementMessageRef
|
|
187
193
|
}, /*#__PURE__*/React.createElement(ValidMessage, {
|
|
188
194
|
testId: "message-success-replacement"
|
|
189
|
-
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, '\u00a0') : resultsReplace)), /*#__PURE__*/React.createElement(Box, {
|
|
190
|
-
xcss: actionButtonContainerStyles
|
|
195
|
+
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, '\u00a0') : resultsReplace))), /*#__PURE__*/React.createElement(Box, {
|
|
196
|
+
xcss: allowReplace ? actionButtonContainerStyles : findOnlyActionButtonContainerStyles
|
|
191
197
|
}, /*#__PURE__*/React.createElement(Inline, {
|
|
192
198
|
xcss: actionButtonParentInlineStyles
|
|
193
199
|
}, /*#__PURE__*/React.createElement(Inline, {
|
|
@@ -216,7 +222,7 @@ const Replace = ({
|
|
|
216
222
|
keymapDescription: 'Shift Enter',
|
|
217
223
|
onClick: handleFindPrevClick,
|
|
218
224
|
disabled: count.total <= 1
|
|
219
|
-
}), /*#__PURE__*/React.createElement(Button, {
|
|
225
|
+
}), allowReplace && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
220
226
|
testId: 'Replace',
|
|
221
227
|
id: "replace-button",
|
|
222
228
|
onClick: handleReplaceClick,
|
|
@@ -227,7 +233,7 @@ const Replace = ({
|
|
|
227
233
|
id: "replaceAll-button",
|
|
228
234
|
onClick: handleReplaceAllClick,
|
|
229
235
|
isDisabled: count.totalReplaceable === 0
|
|
230
|
-
}, replaceAll)), /*#__PURE__*/React.createElement(Inline, {
|
|
236
|
+
}, replaceAll))), /*#__PURE__*/React.createElement(Inline, {
|
|
231
237
|
xcss: closeButtonInlineStyles
|
|
232
238
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
233
239
|
appearance: "subtle",
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
4
|
import { ToolbarSize } from '@atlaskit/editor-common/types';
|
|
5
|
+
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
5
6
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
6
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
7
8
|
import { activate } from './pm-plugins/commands';
|
|
@@ -9,6 +10,7 @@ import { activateWithAnalytics } from './pm-plugins/commands-with-analytics';
|
|
|
9
10
|
import keymapPlugin from './pm-plugins/keymap';
|
|
10
11
|
import { createPlugin } from './pm-plugins/main';
|
|
11
12
|
import { findReplacePluginKey } from './pm-plugins/plugin-key';
|
|
13
|
+
import { viewModeShortcutPlugin } from './pm-plugins/view-mode-shortcut';
|
|
12
14
|
import FindReplaceDropDownOrToolbarButtonWithState from './ui/FindReplaceDropDownOrToolbarButtonWithState';
|
|
13
15
|
export var findReplacePlugin = function findReplacePlugin(_ref) {
|
|
14
16
|
var _api$primaryToolbar;
|
|
@@ -70,9 +72,17 @@ export var findReplacePlugin = function findReplacePlugin(_ref) {
|
|
|
70
72
|
name: 'findReplaceKeymap',
|
|
71
73
|
plugin: function plugin() {
|
|
72
74
|
var _api$analytics;
|
|
73
|
-
return keymapPlugin(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
75
|
+
return keymapPlugin(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode);
|
|
74
76
|
}
|
|
75
77
|
}];
|
|
78
|
+
if (api !== null && api !== void 0 && api.editorViewMode && UNSAFE_expValNoExposure('platform_editor_collapsible_headings', 'isEnabled', false)) {
|
|
79
|
+
plugins.push({
|
|
80
|
+
name: 'findReplaceViewModeShortcut',
|
|
81
|
+
plugin: function plugin() {
|
|
82
|
+
return viewModeShortcutPlugin(api);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
76
86
|
if (editorExperiment('platform_editor_controls', 'variant1', {
|
|
77
87
|
exposure: false
|
|
78
88
|
})) {
|
|
@@ -131,7 +141,7 @@ export var findReplacePlugin = function findReplacePlugin(_ref) {
|
|
|
131
141
|
dispatch = _editorViewRef$curren.dispatch;
|
|
132
142
|
if (api !== null && api !== void 0 && (_api$analytics2 = api.analytics) !== null && _api$analytics2 !== void 0 && _api$analytics2.actions) {
|
|
133
143
|
var _api$analytics3;
|
|
134
|
-
activateWithAnalytics(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions)({
|
|
144
|
+
activateWithAnalytics(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
135
145
|
triggerMethod: triggerMethod || TRIGGER_METHOD.EXTERNAL
|
|
136
146
|
})(state, dispatch);
|
|
137
147
|
} else {
|
|
@@ -2,17 +2,25 @@ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/edit
|
|
|
2
2
|
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
|
3
3
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import { activate, cancelSearch, find, findNext, findPrevious, replace, replaceAll } from './commands';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hosts that do not install `editorViewMode` are always editing, so the attribute
|
|
8
|
+
* falls back to `edit` when the api is absent.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export var activateWithAnalytics = function activateWithAnalytics(editorAnalyticsAPI, editorViewModeAPI) {
|
|
6
12
|
return function (_ref) {
|
|
7
13
|
var triggerMethod = _ref.triggerMethod;
|
|
8
14
|
return withAnalytics(editorAnalyticsAPI, function (state) {
|
|
15
|
+
var _editorViewModeAPI$sh, _editorViewModeAPI$sh2;
|
|
9
16
|
return {
|
|
10
17
|
eventType: EVENT_TYPE.UI,
|
|
11
18
|
action: ACTION.ACTIVATED,
|
|
12
19
|
actionSubject: ACTION_SUBJECT.FIND_REPLACE_DIALOG,
|
|
13
20
|
attributes: {
|
|
14
21
|
inputMethod: state.selection instanceof TextSelection && !state.selection.empty ? INPUT_METHOD.PREFILL : INPUT_METHOD.KEYBOARD,
|
|
15
|
-
triggerMethod: triggerMethod
|
|
22
|
+
triggerMethod: triggerMethod,
|
|
23
|
+
editorViewMode: (_editorViewModeAPI$sh = editorViewModeAPI === null || editorViewModeAPI === void 0 || (_editorViewModeAPI$sh2 = editorViewModeAPI.sharedState.currentState()) === null || _editorViewModeAPI$sh2 === void 0 ? void 0 : _editorViewModeAPI$sh2.mode) !== null && _editorViewModeAPI$sh !== void 0 ? _editorViewModeAPI$sh : 'edit'
|
|
16
24
|
}
|
|
17
25
|
};
|
|
18
26
|
})(activate());
|
|
@@ -2,19 +2,19 @@ import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
|
2
2
|
import { bindKeymapWithCommand, find as findKeymap } from '@atlaskit/editor-common/keymaps';
|
|
3
3
|
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
4
4
|
import { activateWithAnalytics } from './commands-with-analytics';
|
|
5
|
-
var activateFindReplace = function activateFindReplace(editorAnalyticsAPI) {
|
|
5
|
+
var activateFindReplace = function activateFindReplace(editorAnalyticsAPI, editorViewModeAPI) {
|
|
6
6
|
return function (state, dispatch) {
|
|
7
|
-
activateWithAnalytics(editorAnalyticsAPI)({
|
|
7
|
+
activateWithAnalytics(editorAnalyticsAPI, editorViewModeAPI)({
|
|
8
8
|
triggerMethod: TRIGGER_METHOD.SHORTCUT
|
|
9
9
|
})(state, dispatch);
|
|
10
10
|
return true;
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
|
-
var keymapPlugin = function keymapPlugin(editorAnalyticsAPI) {
|
|
13
|
+
var keymapPlugin = function keymapPlugin(editorAnalyticsAPI, editorViewModeAPI) {
|
|
14
14
|
var list = {};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if (findKeymap.common) {
|
|
16
|
+
bindKeymapWithCommand(findKeymap.common, activateFindReplace(editorAnalyticsAPI, editorViewModeAPI), list);
|
|
17
|
+
}
|
|
18
18
|
return keymap(list);
|
|
19
19
|
};
|
|
20
20
|
export default keymapPlugin;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { bindKeymapWithCommand, find as findKeymap } from '@atlaskit/editor-common/keymaps';
|
|
4
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
5
|
+
import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
|
|
6
|
+
import { activateWithAnalytics } from './commands-with-analytics';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Whether the event came from a field the user is typing into. `Mod-f` belongs to
|
|
10
|
+
* that field, not to us.
|
|
11
|
+
*/
|
|
12
|
+
var isFromTextEntry = function isFromTextEntry(event) {
|
|
13
|
+
var target = event.target;
|
|
14
|
+
return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
15
|
+
};
|
|
16
|
+
var activateInViewMode = function activateInViewMode(api) {
|
|
17
|
+
return function (state, dispatch) {
|
|
18
|
+
var _api$editorViewMode, _api$analytics;
|
|
19
|
+
// In edit mode `./keymap.ts` already handles `Mod-f`. Handling it here as well
|
|
20
|
+
// would activate the dialog twice from a single keypress.
|
|
21
|
+
if ((api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode) !== 'view') {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
activateWithAnalytics(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
25
|
+
triggerMethod: TRIGGER_METHOD.SHORTCUT
|
|
26
|
+
})(state, dispatch);
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Opens the find dialog on `Mod-f` while the editor is in view mode.
|
|
33
|
+
*
|
|
34
|
+
* The listener is bound on the document so that it still fires in view mode, where
|
|
35
|
+
* ProseMirror delivers the keydown to neither `keymap()` nor `handleDOMEvents`.
|
|
36
|
+
*/
|
|
37
|
+
export var viewModeShortcutPlugin = function viewModeShortcutPlugin(api) {
|
|
38
|
+
var bindings = {};
|
|
39
|
+
if (findKeymap.common) {
|
|
40
|
+
bindKeymapWithCommand(findKeymap.common, activateInViewMode(api), bindings);
|
|
41
|
+
}
|
|
42
|
+
var handleKeydown = keydownHandler(bindings);
|
|
43
|
+
return new SafePlugin({
|
|
44
|
+
view: function view(_view) {
|
|
45
|
+
var unbind = bind(_view.root, {
|
|
46
|
+
type: 'keydown',
|
|
47
|
+
listener: function listener(event) {
|
|
48
|
+
// `view.root` is `Document | ShadowRoot`, so the binding widens the event.
|
|
49
|
+
if (!(event instanceof KeyboardEvent) || isFromTextEntry(event)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (handleKeydown(_view, event)) {
|
|
53
|
+
// Without this the browser find bar opens on top of our dialog.
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
destroy: unbind
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
};
|
|
@@ -16,11 +16,23 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
16
16
|
import React from 'react';
|
|
17
17
|
|
|
18
18
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
|
|
19
|
-
import { jsx } from '@emotion/react';
|
|
19
|
+
import { css, jsx } from '@emotion/react';
|
|
20
20
|
import { findReplaceMessages as messages } from '@atlaskit/editor-common/messages';
|
|
21
21
|
import Find from './Find';
|
|
22
22
|
import Replace from './Replace';
|
|
23
23
|
import { ruleStyles, wrapperPaddingStyles, wrapperStyles } from './ui-styles';
|
|
24
|
+
|
|
25
|
+
// Magic number taken from ./FindReplaceToolbarButton.tsx
|
|
26
|
+
var dropdownWidth = 382;
|
|
27
|
+
|
|
28
|
+
// Without replace the find row is the widest row, so the popup would size to it and
|
|
29
|
+
// change width as the match counter appears. Pin it to the width the dropdown reserves.
|
|
30
|
+
var findOnlyWidthStyles = css({
|
|
31
|
+
boxSizing: 'border-box',
|
|
32
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
33
|
+
width: "".concat(dropdownWidth, "px"),
|
|
34
|
+
maxWidth: '100%'
|
|
35
|
+
});
|
|
24
36
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
25
37
|
var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
26
38
|
function FindReplace(props) {
|
|
@@ -77,16 +89,18 @@ var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
77
89
|
allowMatchCase = _this$props.allowMatchCase,
|
|
78
90
|
shouldMatchCase = _this$props.shouldMatchCase,
|
|
79
91
|
onToggleMatchCase = _this$props.onToggleMatchCase,
|
|
80
|
-
intl = _this$props.intl
|
|
92
|
+
intl = _this$props.intl,
|
|
93
|
+
_this$props$allowRepl = _this$props.allowReplace,
|
|
94
|
+
allowReplace = _this$props$allowRepl === void 0 ? true : _this$props$allowRepl;
|
|
81
95
|
var focusToolbarButton = this.props.focusToolbarButton || function () {};
|
|
82
96
|
return jsx("div", {
|
|
83
97
|
role: 'dialog',
|
|
84
|
-
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(messages.findReplaceDialogAriaLabel),
|
|
98
|
+
"aria-label": intl === null || intl === void 0 ? void 0 : intl.formatMessage(allowReplace ? messages.findReplaceDialogAriaLabel : messages.findDialogAriaLabel),
|
|
85
99
|
"aria-modal": false,
|
|
86
100
|
ref: this.modalRef
|
|
87
101
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
88
102
|
,
|
|
89
|
-
css: [wrapperStyles, wrapperPaddingStyles]
|
|
103
|
+
css: [wrapperStyles, wrapperPaddingStyles, !allowReplace && findOnlyWidthStyles]
|
|
90
104
|
}, jsx(Find, {
|
|
91
105
|
allowMatchCase: allowMatchCase,
|
|
92
106
|
shouldMatchCase: shouldMatchCase,
|
|
@@ -103,11 +117,14 @@ var FindReplace = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
103
117
|
onArrowDown: this.setFocusToReplace,
|
|
104
118
|
findTyped: this.state.findTyped,
|
|
105
119
|
setFindTyped: this.setFindTyped
|
|
106
|
-
}),
|
|
120
|
+
}), allowReplace &&
|
|
121
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
122
|
+
jsx("hr", {
|
|
107
123
|
role: "presentation",
|
|
108
124
|
css: ruleStyles,
|
|
109
125
|
id: "replace-hr-element"
|
|
110
126
|
}), jsx(Replace, {
|
|
127
|
+
allowReplace: allowReplace,
|
|
111
128
|
canReplace: !!isReplaceable,
|
|
112
129
|
replaceText: replaceText,
|
|
113
130
|
onReplace: onReplace,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
2
|
import React, { useLayoutEffect, useState } from 'react';
|
|
3
3
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
5
|
+
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
6
|
+
import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react/conditional-hooks-factory/conditional-hooks-factory';
|
|
4
7
|
import { blur, toggleMatchCase } from '../pm-plugins/commands';
|
|
5
8
|
import { activateWithAnalytics, cancelSearchWithAnalytics, findNextWithAnalytics, findPrevWithAnalytics, findWithAnalytics, replaceAllWithAnalytics, replaceWithAnalytics } from '../pm-plugins/commands-with-analytics';
|
|
6
9
|
import FindReplaceDropdown from './FindReplaceDropdown';
|
|
@@ -31,6 +34,16 @@ var useSharedPluginStateNoDebounce = function useSharedPluginStateNoDebounce(api
|
|
|
31
34
|
findReplaceState: state
|
|
32
35
|
};
|
|
33
36
|
};
|
|
37
|
+
var useEditorViewMode = conditionalHooksFactory(function () {
|
|
38
|
+
return UNSAFE_expValNoExposure('platform_editor_collapsible_headings', 'isEnabled', false);
|
|
39
|
+
}, function (api) {
|
|
40
|
+
return useSharedPluginStateWithSelector(api, ['editorViewMode'], function (states) {
|
|
41
|
+
var _states$editorViewMod;
|
|
42
|
+
return (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode;
|
|
43
|
+
});
|
|
44
|
+
}, function () {
|
|
45
|
+
return undefined;
|
|
46
|
+
});
|
|
34
47
|
var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithState(_ref2) {
|
|
35
48
|
var _api$analytics, _matches$index;
|
|
36
49
|
var popupsBoundariesElement = _ref2.popupsBoundariesElement,
|
|
@@ -47,6 +60,8 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
47
60
|
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
48
61
|
var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
|
|
49
62
|
findReplaceState = _useSharedPluginState.findReplaceState;
|
|
63
|
+
var editorViewMode = useEditorViewMode(api);
|
|
64
|
+
var allowReplace = editorViewMode !== 'view';
|
|
50
65
|
var shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
|
|
51
66
|
var isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
|
|
52
67
|
var findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
|
|
@@ -74,7 +89,7 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
74
89
|
};
|
|
75
90
|
var handleActivate = function handleActivate() {
|
|
76
91
|
runWithEditorFocused(function () {
|
|
77
|
-
return dispatchCommand(activateWithAnalytics(editorAnalyticsAPI)({
|
|
92
|
+
return dispatchCommand(activateWithAnalytics(editorAnalyticsAPI, api === null || api === void 0 ? void 0 : api.editorViewMode)({
|
|
78
93
|
triggerMethod: TRIGGER_METHOD.TOOLBAR
|
|
79
94
|
}));
|
|
80
95
|
});
|
|
@@ -168,7 +183,8 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
|
|
|
168
183
|
onReplace: handleReplace,
|
|
169
184
|
onReplaceAll: handleReplaceAll,
|
|
170
185
|
takeFullWidth: !!takeFullWidth,
|
|
171
|
-
isButtonHidden: isButtonHidden
|
|
186
|
+
isButtonHidden: isButtonHidden,
|
|
187
|
+
allowReplace: allowReplace
|
|
172
188
|
});
|
|
173
189
|
};
|
|
174
190
|
var _default_1 = /*#__PURE__*/React.memo(FindReplaceToolbarButtonWithState);
|
package/dist/esm/ui/Replace.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import React, { Fragment, useState, useRef, useEffect } from 'react';
|
|
3
3
|
import { injectIntl } from 'react-intl';
|
|
4
4
|
import Button from '@atlaskit/button/default/button';
|
|
5
5
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
@@ -21,6 +21,11 @@ var replaceWithLabelStyle = xcss({
|
|
|
21
21
|
var actionButtonContainerStyles = xcss({
|
|
22
22
|
paddingTop: 'space.200'
|
|
23
23
|
});
|
|
24
|
+
|
|
25
|
+
// Without the replace field above it, the button row needs no separating space.
|
|
26
|
+
var findOnlyActionButtonContainerStyles = xcss({
|
|
27
|
+
paddingTop: 'space.0'
|
|
28
|
+
});
|
|
24
29
|
var actionButtonParentInlineStyles = xcss({
|
|
25
30
|
justifyContent: 'space-between',
|
|
26
31
|
flexDirection: 'row-reverse',
|
|
@@ -34,7 +39,9 @@ var closeButtonInlineStyles = xcss({
|
|
|
34
39
|
marginRight: 'auto'
|
|
35
40
|
});
|
|
36
41
|
var Replace = function Replace(_ref) {
|
|
37
|
-
var
|
|
42
|
+
var _ref$allowReplace = _ref.allowReplace,
|
|
43
|
+
allowReplace = _ref$allowReplace === void 0 ? true : _ref$allowReplace,
|
|
44
|
+
canReplace = _ref.canReplace,
|
|
38
45
|
initialReplaceText = _ref.replaceText,
|
|
39
46
|
onReplace = _ref.onReplace,
|
|
40
47
|
onReplaceAll = _ref.onReplaceAll,
|
|
@@ -184,7 +191,7 @@ var Replace = function Replace(_ref) {
|
|
|
184
191
|
});
|
|
185
192
|
return /*#__PURE__*/React.createElement(Box, {
|
|
186
193
|
xcss: replaceContainerStyles
|
|
187
|
-
}, /*#__PURE__*/React.createElement(Box, {
|
|
194
|
+
}, allowReplace && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Box, {
|
|
188
195
|
xcss: replaceWithLabelStyle
|
|
189
196
|
}, /*#__PURE__*/React.createElement(Text, {
|
|
190
197
|
id: "replace-text-field-label",
|
|
@@ -207,8 +214,8 @@ var Replace = function Replace(_ref) {
|
|
|
207
214
|
ref: successReplacementMessageRef
|
|
208
215
|
}, /*#__PURE__*/React.createElement(ValidMessage, {
|
|
209
216
|
testId: "message-success-replacement"
|
|
210
|
-
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, "\xA0") : resultsReplace)), /*#__PURE__*/React.createElement(Box, {
|
|
211
|
-
xcss: actionButtonContainerStyles
|
|
217
|
+
}, fakeSuccessReplacementMessageUpdate ? resultsReplace.replace(SPACE_REGEX, "\xA0") : resultsReplace))), /*#__PURE__*/React.createElement(Box, {
|
|
218
|
+
xcss: allowReplace ? actionButtonContainerStyles : findOnlyActionButtonContainerStyles
|
|
212
219
|
}, /*#__PURE__*/React.createElement(Inline, {
|
|
213
220
|
xcss: actionButtonParentInlineStyles
|
|
214
221
|
}, /*#__PURE__*/React.createElement(Inline, {
|
|
@@ -241,7 +248,7 @@ var Replace = function Replace(_ref) {
|
|
|
241
248
|
keymapDescription: 'Shift Enter',
|
|
242
249
|
onClick: handleFindPrevClick,
|
|
243
250
|
disabled: count.total <= 1
|
|
244
|
-
}), /*#__PURE__*/React.createElement(Button, {
|
|
251
|
+
}), allowReplace && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
245
252
|
testId: 'Replace',
|
|
246
253
|
id: "replace-button",
|
|
247
254
|
onClick: handleReplaceClick,
|
|
@@ -252,7 +259,7 @@ var Replace = function Replace(_ref) {
|
|
|
252
259
|
id: "replaceAll-button",
|
|
253
260
|
onClick: handleReplaceAllClick,
|
|
254
261
|
isDisabled: count.totalReplaceable === 0
|
|
255
|
-
}, replaceAll)), /*#__PURE__*/React.createElement(Inline, {
|
|
262
|
+
}, replaceAll))), /*#__PURE__*/React.createElement(Inline, {
|
|
256
263
|
xcss: closeButtonInlineStyles
|
|
257
264
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
258
265
|
appearance: "subtle",
|
|
@@ -3,6 +3,7 @@ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/t
|
|
|
3
3
|
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
4
4
|
import type { BlockCollapsePlugin } from '@atlaskit/editor-plugin-block-collapse/blockCollapsePluginType';
|
|
5
5
|
import type { CardPlugin } from '@atlaskit/editor-plugin-card';
|
|
6
|
+
import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode/editorViewmodePluginType';
|
|
6
7
|
import type { ExpandPlugin } from '@atlaskit/editor-plugin-expand';
|
|
7
8
|
import type { MentionsPlugin } from '@atlaskit/editor-plugin-mentions';
|
|
8
9
|
import type { PrimaryToolbarPlugin } from '@atlaskit/editor-plugin-primary-toolbar';
|
|
@@ -19,6 +20,7 @@ export type FindReplacePluginDependencies = [
|
|
|
19
20
|
OptionalPlugin<CardPlugin>,
|
|
20
21
|
OptionalPlugin<ExpandPlugin>,
|
|
21
22
|
OptionalPlugin<BlockCollapsePlugin>,
|
|
23
|
+
OptionalPlugin<EditorViewModePlugin>,
|
|
22
24
|
OptionalPlugin<SyncedBlockPlugin>
|
|
23
25
|
];
|
|
24
26
|
export type FindReplacePlugin = NextEditorPlugin<'findReplace', {
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { EditorAnalyticsAPI, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
-
import type { Command } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
3
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
-
|
|
4
|
+
import type { FindReplacePlugin } from '../findReplacePluginType';
|
|
5
|
+
/**
|
|
6
|
+
* Hosts that do not install `editorViewMode` are always editing, so the attribute
|
|
7
|
+
* falls back to `edit` when the api is absent.
|
|
8
|
+
*/
|
|
9
|
+
export type EditorViewModeAPI = ExtractInjectionAPI<FindReplacePlugin>['editorViewMode'];
|
|
10
|
+
export declare const activateWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined, editorViewModeAPI?: EditorViewModeAPI) => ({ triggerMethod, }: {
|
|
5
11
|
triggerMethod: TRIGGER_METHOD.SHORTCUT | TRIGGER_METHOD.TOOLBAR | TRIGGER_METHOD.EXTERNAL;
|
|
6
12
|
}) => Command;
|
|
7
13
|
export declare const findWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ editorView, containerElement, keyword, }: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
-
|
|
3
|
+
import type { EditorViewModeAPI } from './commands-with-analytics';
|
|
4
|
+
declare const keymapPlugin: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined, editorViewModeAPI: EditorViewModeAPI) => SafePlugin;
|
|
4
5
|
export default keymapPlugin;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { FindReplacePlugin } from '../findReplacePluginType';
|
|
4
|
+
/**
|
|
5
|
+
* Opens the find dialog on `Mod-f` while the editor is in view mode.
|
|
6
|
+
*
|
|
7
|
+
* The listener is bound on the document so that it still fires in view mode, where
|
|
8
|
+
* ProseMirror delivers the keydown to neither `keymap()` nor `handleDOMEvents`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const viewModeShortcutPlugin: (api?: ExtractInjectionAPI<FindReplacePlugin>) => SafePlugin;
|
|
@@ -8,6 +8,11 @@ import type { IntlShape } from 'react-intl';
|
|
|
8
8
|
import type { DispatchAnalyticsEvent, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
9
9
|
import type { MatchCaseProps } from '../types';
|
|
10
10
|
export type FindReplaceProps = {
|
|
11
|
+
/**
|
|
12
|
+
* When `false`, the dialog offers find only: the replace label, field, replacement
|
|
13
|
+
* count message and both replace buttons are not rendered.
|
|
14
|
+
*/
|
|
15
|
+
allowReplace?: boolean;
|
|
11
16
|
count: {
|
|
12
17
|
index: number;
|
|
13
18
|
total: number;
|
|
@@ -3,6 +3,12 @@ import type { WithIntlProps, WrappedComponentProps } from 'react-intl';
|
|
|
3
3
|
import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
export type ReplaceProps = {
|
|
6
|
+
/**
|
|
7
|
+
* When `false`, the replace label, field, replacement count message and both
|
|
8
|
+
* replace buttons are not rendered. Both chevrons and the Close button stay.
|
|
9
|
+
* Defaults to `true`.
|
|
10
|
+
*/
|
|
11
|
+
allowReplace?: boolean;
|
|
6
12
|
canReplace: boolean;
|
|
7
13
|
count: {
|
|
8
14
|
index: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-find-replace",
|
|
3
|
-
"version": "21.0
|
|
3
|
+
"version": "21.1.0",
|
|
4
4
|
"description": "find replace plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"@atlaskit/editor-plugin-analytics": "^21.0.0",
|
|
25
25
|
"@atlaskit/editor-plugin-block-collapse": "^7.0.0",
|
|
26
26
|
"@atlaskit/editor-plugin-card": "^27.0.0",
|
|
27
|
+
"@atlaskit/editor-plugin-editor-viewmode": "^23.0.0",
|
|
27
28
|
"@atlaskit/editor-plugin-expand": "^22.0.0",
|
|
28
29
|
"@atlaskit/editor-plugin-mentions": "^23.0.0",
|
|
29
30
|
"@atlaskit/editor-plugin-primary-toolbar": "^22.0.0",
|
|
@@ -36,13 +37,15 @@
|
|
|
36
37
|
"@atlaskit/mention": "^30.0.0",
|
|
37
38
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
38
39
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
40
|
+
"@atlaskit/platform-feature-flags-react": "^1.2.0",
|
|
39
41
|
"@atlaskit/primitives": "^22.5.0",
|
|
40
42
|
"@atlaskit/textfield": "^10.2.0",
|
|
41
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
43
|
+
"@atlaskit/tmp-editor-statsig": "^207.0.0",
|
|
42
44
|
"@atlaskit/tokens": "^20.0.0",
|
|
43
45
|
"@atlaskit/tooltip": "^24.3.0",
|
|
44
46
|
"@babel/runtime": "^7.0.0",
|
|
45
47
|
"@emotion/react": "^11.7.1",
|
|
48
|
+
"bind-event-listener": "^3.0.0",
|
|
46
49
|
"classnames": "^2.2.5",
|
|
47
50
|
"lodash": "^4.17.21",
|
|
48
51
|
"raf-schd": "^4.0.3"
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
"react-intl": "^7.0.0"
|
|
58
61
|
},
|
|
59
62
|
"peerDependencies": {
|
|
60
|
-
"@atlaskit/editor-common": "^125.
|
|
63
|
+
"@atlaskit/editor-common": "^125.2.0",
|
|
61
64
|
"react": "^18.2.0 || ^19.2.0",
|
|
62
65
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
63
66
|
},
|