@atlaskit/jql-editor 4.10.7 → 4.11.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/jql-editor
2
2
 
3
+ ## 4.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#169739](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/169739)
8
+ [`0eafd620f45b3`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0eafd620f45b3) -
9
+ Implement mechanism to override JQL Editor components [GRAVITYAI-1949]
10
+
3
11
  ## 4.10.7
4
12
 
5
13
  ### Patch Changes
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useJqlEditorAnalytics = void 0;
7
7
  var _jqlEditorCommon = require("@atlaskit/jql-editor-common");
8
8
  var useJqlEditorAnalytics = exports.useJqlEditorAnalytics = function useJqlEditorAnalytics(analyticsSource) {
9
- return (0, _jqlEditorCommon.useJqlPackageAnalytics)(analyticsSource, "@atlaskit/jql-editor", "4.10.7", _jqlEditorCommon.ANALYTICS_CHANNEL);
9
+ return (0, _jqlEditorCommon.useJqlPackageAnalytics)(analyticsSource, "@atlaskit/jql-editor", "4.11.0", _jqlEditorCommon.ANALYTICS_CHANNEL);
10
10
  };
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useStoreActions = exports.useScopedId = exports.useRichInlineNodesEnabled = exports.useOnSyntaxHelp = exports.useLineNumbersVisible = exports.useJqlError = exports.useIsSearching = exports.useIntl = exports.useIdPrefix = exports.useHydratedValue = exports.useHydratedUser = exports.useHydratedDeprecations = exports.useExternalMessages = exports.useEditorViewHasFocus = exports.useEditorView = exports.useEditorStateHasJqlError = exports.useEditorState = exports.useAutocompleteProvider = exports.useAutocompletePosition = exports.useAutocompleteOptions = exports.useAutocompleteLoading = exports.useAutocompleteIsOpen = exports.useAutocomplete = exports.initialState = exports.actions = exports.EditorStateContainer = void 0;
7
+ exports.useStoreActions = exports.useScopedId = exports.useRichInlineNodesEnabled = exports.useOnSyntaxHelp = exports.useLineNumbersVisible = exports.useJqlError = exports.useIsSearching = exports.useIntl = exports.useIdPrefix = exports.useHydratedValue = exports.useHydratedUser = exports.useHydratedDeprecations = exports.useExternalMessages = exports.useEditorViewHasFocus = exports.useEditorView = exports.useEditorStateHasJqlError = exports.useEditorState = exports.useCustomErrorComponent = exports.useAutocompleteProvider = exports.useAutocompletePosition = exports.useAutocompleteOptions = exports.useAutocompleteLoading = exports.useAutocompleteIsOpen = exports.useAutocomplete = exports.initialState = exports.actions = exports.EditorStateContainer = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
@@ -18,6 +18,7 @@ var _uuid = require("uuid");
18
18
  var _view = require("@atlaskit/editor-prosemirror/view");
19
19
  var _jqlAst = require("@atlaskit/jql-ast");
20
20
  var _jqlAutocomplete = require("@atlaskit/jql-autocomplete");
21
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
21
22
  var _analytics = require("../analytics");
22
23
  var _selectErrorCommand = require("../commands/select-error-command");
23
24
  var _constants = require("../common/constants");
@@ -783,6 +784,12 @@ var useExternalMessages = exports.useExternalMessages = (0, _reactSweetState.cre
783
784
  };
784
785
  }
785
786
  });
787
+ var useCustomErrorComponent = exports.useCustomErrorComponent = (0, _reactSweetState.createHook)(Store, {
788
+ selector: function selector(state) {
789
+ var _state$customComponen;
790
+ return (_state$customComponen = state.customComponents) === null || _state$customComponen === void 0 ? void 0 : _state$customComponen.ErrorMessage;
791
+ }
792
+ });
786
793
  var memoizedAutocompleteOptionsSelector = (0, _reactSweetState.createSelector)(function (state) {
787
794
  return state.autocomplete.options.tokens;
788
795
  }, function (state) {
@@ -928,7 +935,8 @@ var EditorStateContainer = exports.EditorStateContainer = (0, _reactSweetState.c
928
935
  externalMessages = _ref45.externalMessages,
929
936
  enableRichInlineNodes = _ref45.enableRichInlineNodes,
930
937
  onDebugUnsafeMessage = _ref45.onDebugUnsafeMessage,
931
- onSyntaxHelp = _ref45.onSyntaxHelp;
938
+ onSyntaxHelp = _ref45.onSyntaxHelp,
939
+ customComponents = _ref45.customComponents;
932
940
  setState({
933
941
  controlledQuery: query,
934
942
  query: query,
@@ -949,7 +957,8 @@ var EditorStateContainer = exports.EditorStateContainer = (0, _reactSweetState.c
949
957
  });
950
958
  }) : undefined,
951
959
  onDebugUnsafeMessage: onDebugUnsafeMessage,
952
- onSyntaxHelp: onSyntaxHelp
960
+ onSyntaxHelp: onSyntaxHelp,
961
+ customComponents: (0, _platformFeatureFlags.fg)('custom_components_for_jql_editor') ? customComponents : undefined
953
962
  });
954
963
  dispatch(actions.initialiseEditorState());
955
964
  };
@@ -965,7 +974,8 @@ var EditorStateContainer = exports.EditorStateContainer = (0, _reactSweetState.c
965
974
  externalMessages = _ref47.externalMessages,
966
975
  enableRichInlineNodes = _ref47.enableRichInlineNodes,
967
976
  onDebugUnsafeMessage = _ref47.onDebugUnsafeMessage,
968
- onSyntaxHelp = _ref47.onSyntaxHelp;
977
+ onSyntaxHelp = _ref47.onSyntaxHelp,
978
+ customComponents = _ref47.customComponents;
969
979
  var _getState14 = getState(),
970
980
  controlledQuery = _getState14.controlledQuery,
971
981
  query = _getState14.query;
@@ -988,7 +998,8 @@ var EditorStateContainer = exports.EditorStateContainer = (0, _reactSweetState.c
988
998
  autocompleteProvider: autocompleteProvider,
989
999
  enableRichInlineNodes: enableRichInlineNodes,
990
1000
  onDebugUnsafeMessage: onDebugUnsafeMessage,
991
- onSyntaxHelp: onSyntaxHelp
1001
+ onSyntaxHelp: onSyntaxHelp,
1002
+ customComponents: (0, _platformFeatureFlags.fg)('custom_components_for_jql_editor') ? customComponents : undefined
992
1003
  });
993
1004
  };
994
1005
  }
@@ -9,6 +9,7 @@ exports.default = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactIntlNext = require("react-intl-next");
11
11
  var _reactMagneticDi = require("react-magnetic-di");
12
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
13
  var _analytics = require("../../analytics");
13
14
  var _useEditorTheme = require("../../hooks/use-editor-theme");
14
15
  var _state = require("../../state");
@@ -38,7 +39,8 @@ var JQLEditorInner = function JQLEditorInner(_ref) {
38
39
  enableRichInlineNodes = _ref$enableRichInline === void 0 ? false : _ref$enableRichInline,
39
40
  isCompact = _ref.isCompact,
40
41
  onSyntaxHelp = _ref.onSyntaxHelp,
41
- onFocus = _ref.onFocus;
42
+ onFocus = _ref.onFocus,
43
+ customComponents = _ref.customComponents;
42
44
  var editorTheme = (0, _useEditorTheme.useEditorTheme)({
43
45
  isSearch: !!onSearch,
44
46
  isCompact: isCompact
@@ -65,7 +67,8 @@ var JQLEditorInner = function JQLEditorInner(_ref) {
65
67
  autocompleteProvider: autocompleteProvider,
66
68
  enableRichInlineNodes: enableRichInlineNodes,
67
69
  onSyntaxHelp: onSyntaxHelp,
68
- onFocus: onFocus
70
+ onFocus: onFocus,
71
+ customComponents: (0, _platformFeatureFlags.fg)('custom_components_for_jql_editor') ? customComponents : undefined
69
72
  }, /*#__PURE__*/_react.default.createElement(_useEditorTheme.EditorThemeContext.Provider, {
70
73
  value: editorTheme
71
74
  }, /*#__PURE__*/_react.default.createElement(_jqlEditorPortalProvider.JQLEditorPortalRenderer, null, /*#__PURE__*/_react.default.createElement(_jqlEditorView.default, {
@@ -6,17 +6,22 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.ErrorMessages = void 0;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
9
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
12
  var _react = _interopRequireWildcard(require("react"));
11
13
  var _reactMagneticDi = require("react-magnetic-di");
12
14
  var _form = require("@atlaskit/form");
13
15
  var _jqlAst = require("@atlaskit/jql-ast");
16
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
17
  var _constants = require("../../../../common/constants");
15
18
  var _messages = require("../../../../common/messages");
19
+ var _useEditorTheme = require("../../../../hooks/use-editor-theme");
16
20
  var _useEditorViewIsInvalid = require("../../../../hooks/use-editor-view-is-invalid");
17
21
  var _state = require("../../../../state");
18
22
  var _format = require("../format");
19
23
  var _messages2 = require("./messages");
24
+ var _excluded = ["Component"];
20
25
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
21
26
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
22
27
  var useFormattedErrorMessage = function useFormattedErrorMessage() {
@@ -56,13 +61,54 @@ var useFormattedErrorMessage = function useFormattedErrorMessage() {
56
61
  }
57
62
  return null;
58
63
  };
64
+ /**
65
+ * This is a decorator component to include the editorTheme prop to the already passed list of props
66
+ */
67
+ var CustomComponentDecoratedWithEditorTheme = function CustomComponentDecoratedWithEditorTheme(props) {
68
+ var Component = props.Component,
69
+ rest = (0, _objectWithoutProperties2.default)(props, _excluded);
70
+ var editorThemeContext = (0, _useEditorTheme.useEditorThemeContext)();
71
+
72
+ // This is a slightly redundant condition.
73
+ // Technically, CustomErrorMessage component should never be called with an undefined Component
74
+ // This is enforced by the static types. Adding this condition as an extra layer of protection
75
+ if (!Component) {
76
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "props.children");
77
+ }
78
+ return /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({
79
+ editorTheme: editorThemeContext
80
+ }, rest));
81
+ };
59
82
  var ErrorMessages = exports.ErrorMessages = function ErrorMessages() {
60
83
  var _useScopedId = (0, _state.useScopedId)(_constants.JQL_EDITOR_INPUT_ID),
61
84
  _useScopedId2 = (0, _slicedToArray2.default)(_useScopedId, 1),
62
85
  editorId = _useScopedId2[0];
63
86
  var errorMessage = useFormattedErrorMessage();
87
+ var testId = 'jql-editor-validation';
88
+ if ((0, _platformFeatureFlags.fg)('custom_components_for_jql_editor')) {
89
+ // eslint-disable-next-line react-hooks/rules-of-hooks
90
+ var _useCustomErrorCompon = (0, _state.useCustomErrorComponent)(),
91
+ _useCustomErrorCompon2 = (0, _slicedToArray2.default)(_useCustomErrorCompon, 1),
92
+ CustomErrorComponent = _useCustomErrorCompon2[0];
93
+ var childrenToRender = errorMessage != null ? /*#__PURE__*/_react.default.createElement(_format.MessageContainer, null, /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, {
94
+ testId: testId
95
+ }, /*#__PURE__*/_react.default.createElement("span", {
96
+ role: "alert",
97
+ "aria-describedby": editorId
98
+ }, errorMessage))) : null;
99
+
100
+ // Only render CustomErrorComponent if there is an errorMessage
101
+ if (errorMessage != null && CustomErrorComponent) {
102
+ return /*#__PURE__*/_react.default.createElement(CustomComponentDecoratedWithEditorTheme, {
103
+ testId: testId,
104
+ editorId: editorId,
105
+ Component: CustomErrorComponent
106
+ }, childrenToRender);
107
+ }
108
+ return childrenToRender;
109
+ }
64
110
  return errorMessage != null ? /*#__PURE__*/_react.default.createElement(_format.MessageContainer, null, /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, {
65
- testId: "jql-editor-validation"
111
+ testId: testId
66
112
  }, /*#__PURE__*/_react.default.createElement("span", {
67
113
  role: "alert",
68
114
  "aria-describedby": editorId
@@ -1,4 +1,4 @@
1
1
  import { ANALYTICS_CHANNEL, useJqlPackageAnalytics } from '@atlaskit/jql-editor-common';
2
2
  export const useJqlEditorAnalytics = analyticsSource => {
3
- return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "4.10.7", ANALYTICS_CHANNEL);
3
+ return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "4.11.0", ANALYTICS_CHANNEL);
4
4
  };
@@ -8,6 +8,7 @@ import { v4 as uuidv4 } from 'uuid';
8
8
  import { EditorView } from '@atlaskit/editor-prosemirror/view';
9
9
  import { computeJqlInsights, isListOperator } from '@atlaskit/jql-ast';
10
10
  import { JQLAutocomplete } from '@atlaskit/jql-autocomplete';
11
+ import { fg } from '@atlaskit/platform-feature-flags';
11
12
  import { ActionSubject, ActionSubjectId, Action as AnalyticsAction, EventType } from '../analytics';
12
13
  import { selectErrorCommand } from '../commands/select-error-command';
13
14
  import { JQL_EDITOR_MAIN_ID } from '../common/constants';
@@ -772,6 +773,12 @@ export const useExternalMessages = createHook(Store, {
772
773
  };
773
774
  }
774
775
  });
776
+ export const useCustomErrorComponent = createHook(Store, {
777
+ selector: state => {
778
+ var _state$customComponen;
779
+ return (_state$customComponen = state.customComponents) === null || _state$customComponen === void 0 ? void 0 : _state$customComponen.ErrorMessage;
780
+ }
781
+ });
775
782
  const memoizedAutocompleteOptionsSelector = createSelector(state => state.autocomplete.options.tokens, state => state.autocomplete.options.functions, state => state.autocomplete.options.values, state => state.autocomplete.options.operators, state => state.autocomplete.options.fields, (tokens, functions, values, operators, fields) => [...tokens, ...functions, ...values, ...operators, ...fields]);
776
783
  export const useAutocompleteOptions = createHook(Store, {
777
784
  selector: memoizedAutocompleteOptionsSelector
@@ -897,7 +904,8 @@ export const EditorStateContainer = createContainer(Store, {
897
904
  externalMessages,
898
905
  enableRichInlineNodes,
899
906
  onDebugUnsafeMessage,
900
- onSyntaxHelp
907
+ onSyntaxHelp,
908
+ customComponents
901
909
  }) => {
902
910
  setState({
903
911
  controlledQuery: query,
@@ -919,7 +927,8 @@ export const EditorStateContainer = createContainer(Store, {
919
927
  });
920
928
  }) : undefined,
921
929
  onDebugUnsafeMessage,
922
- onSyntaxHelp
930
+ onSyntaxHelp,
931
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
923
932
  });
924
933
  dispatch(actions.initialiseEditorState());
925
934
  },
@@ -934,7 +943,8 @@ export const EditorStateContainer = createContainer(Store, {
934
943
  externalMessages,
935
944
  enableRichInlineNodes,
936
945
  onDebugUnsafeMessage,
937
- onSyntaxHelp
946
+ onSyntaxHelp,
947
+ customComponents
938
948
  }) => {
939
949
  const {
940
950
  controlledQuery,
@@ -959,7 +969,8 @@ export const EditorStateContainer = createContainer(Store, {
959
969
  autocompleteProvider,
960
970
  enableRichInlineNodes,
961
971
  onDebugUnsafeMessage,
962
- onSyntaxHelp
972
+ onSyntaxHelp,
973
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
963
974
  });
964
975
  }
965
976
  });
@@ -1,6 +1,7 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { injectIntl } from 'react-intl-next';
3
3
  import { di } from 'react-magnetic-di';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { useJqlEditorAnalytics } from '../../analytics';
5
6
  import { EditorThemeContext, useEditorTheme } from '../../hooks/use-editor-theme';
6
7
  import { EditorStateContainer } from '../../state';
@@ -24,7 +25,8 @@ const JQLEditorInner = ({
24
25
  enableRichInlineNodes = false,
25
26
  isCompact,
26
27
  onSyntaxHelp,
27
- onFocus
28
+ onFocus,
29
+ customComponents
28
30
  }) => {
29
31
  const editorTheme = useEditorTheme({
30
32
  isSearch: !!onSearch,
@@ -53,7 +55,8 @@ const JQLEditorInner = ({
53
55
  autocompleteProvider: autocompleteProvider,
54
56
  enableRichInlineNodes: enableRichInlineNodes,
55
57
  onSyntaxHelp: onSyntaxHelp,
56
- onFocus: onFocus
58
+ onFocus: onFocus,
59
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
57
60
  }, /*#__PURE__*/React.createElement(EditorThemeContext.Provider, {
58
61
  value: editorTheme
59
62
  }, /*#__PURE__*/React.createElement(JQLEditorPortalRenderer, null, /*#__PURE__*/React.createElement(JQLEditorView, {
@@ -1,11 +1,14 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
1
2
  import React, { useEffect } from 'react';
2
3
  import { di } from 'react-magnetic-di';
3
4
  import { ErrorMessage } from '@atlaskit/form';
4
5
  import { JQLSyntaxError } from '@atlaskit/jql-ast';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
5
7
  import { JQL_EDITOR_INPUT_ID } from '../../../../common/constants';
6
8
  import { commonMessages } from '../../../../common/messages';
9
+ import { useEditorThemeContext } from '../../../../hooks/use-editor-theme';
7
10
  import { useEditorViewIsInvalid } from '../../../../hooks/use-editor-view-is-invalid';
8
- import { useExternalMessages, useIntl, useJqlError, useScopedId, useStoreActions } from '../../../../state';
11
+ import { useCustomErrorComponent, useExternalMessages, useIntl, useJqlError, useScopedId, useStoreActions } from '../../../../state';
9
12
  import { FormatMessages, MessageContainer } from '../format';
10
13
  import { messages } from './messages';
11
14
  const useFormattedErrorMessage = () => {
@@ -43,11 +46,52 @@ const useFormattedErrorMessage = () => {
43
46
  }
44
47
  return null;
45
48
  };
49
+ /**
50
+ * This is a decorator component to include the editorTheme prop to the already passed list of props
51
+ */
52
+ const CustomComponentDecoratedWithEditorTheme = props => {
53
+ const {
54
+ Component,
55
+ ...rest
56
+ } = props;
57
+ const editorThemeContext = useEditorThemeContext();
58
+
59
+ // This is a slightly redundant condition.
60
+ // Technically, CustomErrorMessage component should never be called with an undefined Component
61
+ // This is enforced by the static types. Adding this condition as an extra layer of protection
62
+ if (!Component) {
63
+ return /*#__PURE__*/React.createElement(React.Fragment, null, "props.children");
64
+ }
65
+ return /*#__PURE__*/React.createElement(Component, _extends({
66
+ editorTheme: editorThemeContext
67
+ }, rest));
68
+ };
46
69
  export const ErrorMessages = () => {
47
70
  const [editorId] = useScopedId(JQL_EDITOR_INPUT_ID);
48
71
  const errorMessage = useFormattedErrorMessage();
72
+ const testId = 'jql-editor-validation';
73
+ if (fg('custom_components_for_jql_editor')) {
74
+ // eslint-disable-next-line react-hooks/rules-of-hooks
75
+ const [CustomErrorComponent] = useCustomErrorComponent();
76
+ const childrenToRender = errorMessage != null ? /*#__PURE__*/React.createElement(MessageContainer, null, /*#__PURE__*/React.createElement(ErrorMessage, {
77
+ testId: testId
78
+ }, /*#__PURE__*/React.createElement("span", {
79
+ role: "alert",
80
+ "aria-describedby": editorId
81
+ }, errorMessage))) : null;
82
+
83
+ // Only render CustomErrorComponent if there is an errorMessage
84
+ if (errorMessage != null && CustomErrorComponent) {
85
+ return /*#__PURE__*/React.createElement(CustomComponentDecoratedWithEditorTheme, {
86
+ testId: testId,
87
+ editorId: editorId,
88
+ Component: CustomErrorComponent
89
+ }, childrenToRender);
90
+ }
91
+ return childrenToRender;
92
+ }
49
93
  return errorMessage != null ? /*#__PURE__*/React.createElement(MessageContainer, null, /*#__PURE__*/React.createElement(ErrorMessage, {
50
- testId: "jql-editor-validation"
94
+ testId: testId
51
95
  }, /*#__PURE__*/React.createElement("span", {
52
96
  role: "alert",
53
97
  "aria-describedby": editorId
@@ -1,4 +1,4 @@
1
1
  import { ANALYTICS_CHANNEL, useJqlPackageAnalytics } from '@atlaskit/jql-editor-common';
2
2
  export var useJqlEditorAnalytics = function useJqlEditorAnalytics(analyticsSource) {
3
- return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "4.10.7", ANALYTICS_CHANNEL);
3
+ return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "4.11.0", ANALYTICS_CHANNEL);
4
4
  };
@@ -13,6 +13,7 @@ import { v4 as uuidv4 } from 'uuid';
13
13
  import { EditorView } from '@atlaskit/editor-prosemirror/view';
14
14
  import { computeJqlInsights, isListOperator } from '@atlaskit/jql-ast';
15
15
  import { JQLAutocomplete } from '@atlaskit/jql-autocomplete';
16
+ import { fg } from '@atlaskit/platform-feature-flags';
16
17
  import { ActionSubject, ActionSubjectId, Action as AnalyticsAction, EventType } from '../analytics';
17
18
  import { selectErrorCommand } from '../commands/select-error-command';
18
19
  import { JQL_EDITOR_MAIN_ID } from '../common/constants';
@@ -776,6 +777,12 @@ export var useExternalMessages = createHook(Store, {
776
777
  };
777
778
  }
778
779
  });
780
+ export var useCustomErrorComponent = createHook(Store, {
781
+ selector: function selector(state) {
782
+ var _state$customComponen;
783
+ return (_state$customComponen = state.customComponents) === null || _state$customComponen === void 0 ? void 0 : _state$customComponen.ErrorMessage;
784
+ }
785
+ });
779
786
  var memoizedAutocompleteOptionsSelector = createSelector(function (state) {
780
787
  return state.autocomplete.options.tokens;
781
788
  }, function (state) {
@@ -921,7 +928,8 @@ export var EditorStateContainer = createContainer(Store, {
921
928
  externalMessages = _ref45.externalMessages,
922
929
  enableRichInlineNodes = _ref45.enableRichInlineNodes,
923
930
  onDebugUnsafeMessage = _ref45.onDebugUnsafeMessage,
924
- onSyntaxHelp = _ref45.onSyntaxHelp;
931
+ onSyntaxHelp = _ref45.onSyntaxHelp,
932
+ customComponents = _ref45.customComponents;
925
933
  setState({
926
934
  controlledQuery: query,
927
935
  query: query,
@@ -942,7 +950,8 @@ export var EditorStateContainer = createContainer(Store, {
942
950
  });
943
951
  }) : undefined,
944
952
  onDebugUnsafeMessage: onDebugUnsafeMessage,
945
- onSyntaxHelp: onSyntaxHelp
953
+ onSyntaxHelp: onSyntaxHelp,
954
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
946
955
  });
947
956
  dispatch(actions.initialiseEditorState());
948
957
  };
@@ -958,7 +967,8 @@ export var EditorStateContainer = createContainer(Store, {
958
967
  externalMessages = _ref47.externalMessages,
959
968
  enableRichInlineNodes = _ref47.enableRichInlineNodes,
960
969
  onDebugUnsafeMessage = _ref47.onDebugUnsafeMessage,
961
- onSyntaxHelp = _ref47.onSyntaxHelp;
970
+ onSyntaxHelp = _ref47.onSyntaxHelp,
971
+ customComponents = _ref47.customComponents;
962
972
  var _getState14 = getState(),
963
973
  controlledQuery = _getState14.controlledQuery,
964
974
  query = _getState14.query;
@@ -981,7 +991,8 @@ export var EditorStateContainer = createContainer(Store, {
981
991
  autocompleteProvider: autocompleteProvider,
982
992
  enableRichInlineNodes: enableRichInlineNodes,
983
993
  onDebugUnsafeMessage: onDebugUnsafeMessage,
984
- onSyntaxHelp: onSyntaxHelp
994
+ onSyntaxHelp: onSyntaxHelp,
995
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
985
996
  });
986
997
  };
987
998
  }
@@ -1,6 +1,7 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { injectIntl } from 'react-intl-next';
3
3
  import { di } from 'react-magnetic-di';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { useJqlEditorAnalytics } from '../../analytics';
5
6
  import { EditorThemeContext, useEditorTheme } from '../../hooks/use-editor-theme';
6
7
  import { EditorStateContainer } from '../../state';
@@ -26,7 +27,8 @@ var JQLEditorInner = function JQLEditorInner(_ref) {
26
27
  enableRichInlineNodes = _ref$enableRichInline === void 0 ? false : _ref$enableRichInline,
27
28
  isCompact = _ref.isCompact,
28
29
  onSyntaxHelp = _ref.onSyntaxHelp,
29
- onFocus = _ref.onFocus;
30
+ onFocus = _ref.onFocus,
31
+ customComponents = _ref.customComponents;
30
32
  var editorTheme = useEditorTheme({
31
33
  isSearch: !!onSearch,
32
34
  isCompact: isCompact
@@ -53,7 +55,8 @@ var JQLEditorInner = function JQLEditorInner(_ref) {
53
55
  autocompleteProvider: autocompleteProvider,
54
56
  enableRichInlineNodes: enableRichInlineNodes,
55
57
  onSyntaxHelp: onSyntaxHelp,
56
- onFocus: onFocus
58
+ onFocus: onFocus,
59
+ customComponents: fg('custom_components_for_jql_editor') ? customComponents : undefined
57
60
  }, /*#__PURE__*/React.createElement(EditorThemeContext.Provider, {
58
61
  value: editorTheme
59
62
  }, /*#__PURE__*/React.createElement(JQLEditorPortalRenderer, null, /*#__PURE__*/React.createElement(JQLEditorView, {
@@ -1,12 +1,17 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
1
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ var _excluded = ["Component"];
2
5
  import React, { useEffect } from 'react';
3
6
  import { di } from 'react-magnetic-di';
4
7
  import { ErrorMessage } from '@atlaskit/form';
5
8
  import { JQLSyntaxError } from '@atlaskit/jql-ast';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
6
10
  import { JQL_EDITOR_INPUT_ID } from '../../../../common/constants';
7
11
  import { commonMessages } from '../../../../common/messages';
12
+ import { useEditorThemeContext } from '../../../../hooks/use-editor-theme';
8
13
  import { useEditorViewIsInvalid } from '../../../../hooks/use-editor-view-is-invalid';
9
- import { useExternalMessages, useIntl, useJqlError, useScopedId, useStoreActions } from '../../../../state';
14
+ import { useCustomErrorComponent, useExternalMessages, useIntl, useJqlError, useScopedId, useStoreActions } from '../../../../state';
10
15
  import { FormatMessages, MessageContainer } from '../format';
11
16
  import { messages } from './messages';
12
17
  var useFormattedErrorMessage = function useFormattedErrorMessage() {
@@ -46,13 +51,54 @@ var useFormattedErrorMessage = function useFormattedErrorMessage() {
46
51
  }
47
52
  return null;
48
53
  };
54
+ /**
55
+ * This is a decorator component to include the editorTheme prop to the already passed list of props
56
+ */
57
+ var CustomComponentDecoratedWithEditorTheme = function CustomComponentDecoratedWithEditorTheme(props) {
58
+ var Component = props.Component,
59
+ rest = _objectWithoutProperties(props, _excluded);
60
+ var editorThemeContext = useEditorThemeContext();
61
+
62
+ // This is a slightly redundant condition.
63
+ // Technically, CustomErrorMessage component should never be called with an undefined Component
64
+ // This is enforced by the static types. Adding this condition as an extra layer of protection
65
+ if (!Component) {
66
+ return /*#__PURE__*/React.createElement(React.Fragment, null, "props.children");
67
+ }
68
+ return /*#__PURE__*/React.createElement(Component, _extends({
69
+ editorTheme: editorThemeContext
70
+ }, rest));
71
+ };
49
72
  export var ErrorMessages = function ErrorMessages() {
50
73
  var _useScopedId = useScopedId(JQL_EDITOR_INPUT_ID),
51
74
  _useScopedId2 = _slicedToArray(_useScopedId, 1),
52
75
  editorId = _useScopedId2[0];
53
76
  var errorMessage = useFormattedErrorMessage();
77
+ var testId = 'jql-editor-validation';
78
+ if (fg('custom_components_for_jql_editor')) {
79
+ // eslint-disable-next-line react-hooks/rules-of-hooks
80
+ var _useCustomErrorCompon = useCustomErrorComponent(),
81
+ _useCustomErrorCompon2 = _slicedToArray(_useCustomErrorCompon, 1),
82
+ CustomErrorComponent = _useCustomErrorCompon2[0];
83
+ var childrenToRender = errorMessage != null ? /*#__PURE__*/React.createElement(MessageContainer, null, /*#__PURE__*/React.createElement(ErrorMessage, {
84
+ testId: testId
85
+ }, /*#__PURE__*/React.createElement("span", {
86
+ role: "alert",
87
+ "aria-describedby": editorId
88
+ }, errorMessage))) : null;
89
+
90
+ // Only render CustomErrorComponent if there is an errorMessage
91
+ if (errorMessage != null && CustomErrorComponent) {
92
+ return /*#__PURE__*/React.createElement(CustomComponentDecoratedWithEditorTheme, {
93
+ testId: testId,
94
+ editorId: editorId,
95
+ Component: CustomErrorComponent
96
+ }, childrenToRender);
97
+ }
98
+ return childrenToRender;
99
+ }
54
100
  return errorMessage != null ? /*#__PURE__*/React.createElement(MessageContainer, null, /*#__PURE__*/React.createElement(ErrorMessage, {
55
- testId: "jql-editor-validation"
101
+ testId: testId
56
102
  }, /*#__PURE__*/React.createElement("span", {
57
103
  role: "alert",
58
104
  "aria-describedby": editorId
@@ -2,4 +2,4 @@ export { default as JQLEditor } from './ui';
2
2
  export { JQLEditorAsync, preloadJQLEditor } from './async';
3
3
  export { JQLEditorReadOnly } from './ui/jql-editor-layout';
4
4
  export { JQLEditorAnalyticsListener, ANALYTICS_CHANNEL, useJqlPackageAnalytics, EventType, } from './analytics';
5
- export type { ListenerProps, JqlAnalyticsEvent, JQLEditorUIProps, JQLEditorProps, HydratedValue, HydratedValues, HydratedUser, AutocompleteOption, AutocompleteValueType, AutocompleteOptions, AutocompleteProvider, JQLClause, ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, } from './types';
5
+ export type { ListenerProps, JqlAnalyticsEvent, JQLEditorUIProps, JQLEditorProps, HydratedValue, HydratedValues, HydratedUser, AutocompleteOption, AutocompleteValueType, AutocompleteOptions, AutocompleteProvider, JQLClause, ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, CustomComponents, } from './types';
@@ -11,7 +11,7 @@ import { type AutocompleteOptionGroup, type AutocompleteOptions, type Autocomple
11
11
  import { type AutocompleteProvider } from '../plugins/types';
12
12
  import { type PortalActions } from '../ui/jql-editor-portal-provider/types';
13
13
  import { type HydratedDeprecatedField, type HydratedUser, type HydratedValue } from '../ui/jql-editor/types';
14
- import { type AutocompletePosition, type AutocompleteState, type ContextAwareJQLSuggestions, type ExternalMessagesNormalized, type OptionsKey, type Props, type State } from './types';
14
+ import { type AutocompletePosition, type AutocompleteState, type ContextAwareJQLSuggestions, type CustomErrorComponent, type ExternalMessagesNormalized, type OptionsKey, type Props, type State } from './types';
15
15
  export declare const initialState: State;
16
16
  export declare const actions: {
17
17
  onEditorViewBlur: () => Action<State>;
@@ -499,6 +499,38 @@ export declare const useExternalMessages: import("react-sweet-state").HookFuncti
499
499
  externalErrorMessageViewed: () => Action<State, Props>;
500
500
  createAndFireAnalyticsEvent: (payload: JqlEditorAnalyticsEvent) => Action<State, Props>;
501
501
  }>, void>;
502
+ export declare const useCustomErrorComponent: import("react-sweet-state").HookFunction<CustomErrorComponent | undefined, import("react-sweet-state").BoundActions<State, {
503
+ onEditorViewBlur: () => Action<State>;
504
+ onEditorViewFocus: (event: FocusEvent<HTMLElement>) => Action<State, Props>;
505
+ openAutocompleteOnNextUpdate: () => Action<State>;
506
+ closeAutocomplete: () => Action<State>;
507
+ setSelectedAutocompleteOptionId: (selectedOptionId: string | undefined) => Action<State>;
508
+ getAutocompleteSuggestions: (editorState: EditorState) => Action<State>;
509
+ getAutocompleteOptions: (suggestions: ContextAwareJQLSuggestions) => Action<State>;
510
+ appendOptionsForObservable: (key: OptionsKey, observable: Observable<AutocompleteOptions>, rule: JQLRuleSuggestion, type: AutocompleteOptionType) => Action<State, void, Observable<AutocompleteOptions>>;
511
+ cancelSubscription: () => Action<State>;
512
+ setLoading: (loading: boolean) => Action<State>;
513
+ setAutocompleteOptions: (options: AutocompleteOptionGroup) => Action<State>;
514
+ setAutocompleteContainer: (container: HTMLElement | null) => Action<State>;
515
+ callAutocompleteProviders: ({ rules, tokens }: ContextAwareJQLSuggestions) => Action<State>;
516
+ updateValidationState: () => Action<State>;
517
+ initialiseEditorState: () => Action<State, Props>;
518
+ configurePlugins: (portalActions: PortalActions | void) => Action<State, Props>;
519
+ onApplyEditorTransaction: (transaction: Transaction) => Action<State, Props>;
520
+ resetEditorState: (query: string, addToHistory?: boolean) => Action<State>;
521
+ initialiseEditorView: (editorViewNode: HTMLElement, attributes: {
522
+ [key: string]: string;
523
+ }, portalActions: PortalActions) => Action<State, Props>;
524
+ updateEditorView: (attributes: {
525
+ [key: string]: string;
526
+ }) => Action<State, Props>;
527
+ setEditorViewContainer: (editorViewContainer: HTMLElement) => Action<State>;
528
+ setEditorViewContainerScroll: (scroll: number) => Action<State>;
529
+ onSearch: () => Action<State>;
530
+ onSearchCommand: (pmState: EditorState, pmDispatch: ((tr: Transaction) => void) | undefined, pmView: EditorView | undefined, keyboardShortcut: boolean) => Action<State, Props, boolean>;
531
+ externalErrorMessageViewed: () => Action<State, Props>;
532
+ createAndFireAnalyticsEvent: (payload: JqlEditorAnalyticsEvent) => Action<State, Props>;
533
+ }>, void>;
502
534
  export declare const useAutocompleteOptions: import("react-sweet-state").HookFunction<SelectableAutocompleteOption[], import("react-sweet-state").BoundActions<State, {
503
535
  onEditorViewBlur: () => Action<State>;
504
536
  onEditorViewFocus: (event: FocusEvent<HTMLElement>) => Action<State, Props>;
@@ -1,4 +1,4 @@
1
- import { type FocusEvent, type MouseEvent, type MutableRefObject, type ReactNode } from 'react';
1
+ import { type FocusEvent, type MouseEvent, type MutableRefObject, type PropsWithChildren, type ReactNode } from 'react';
2
2
  import { type IntlShape } from 'react-intl-next';
3
3
  import { type Subscription } from 'rxjs/Subscription';
4
4
  import { type EditorState } from '@atlaskit/editor-prosemirror/state';
@@ -6,6 +6,7 @@ import { type EditorView } from '@atlaskit/editor-prosemirror/view';
6
6
  import { type Jast, type JQLParseError } from '@atlaskit/jql-ast';
7
7
  import { type JQLRuleContext, type JQLRuleSuggestions, type TokenSuggestions } from '@atlaskit/jql-autocomplete';
8
8
  import { type JqlEditorAnalyticsEvent } from '../analytics';
9
+ import { type EditorTheme } from '../hooks/use-editor-theme';
9
10
  import { type AutocompleteOptionGroup, type AutocompleteProvider } from '../plugins/autocomplete/types';
10
11
  import { type HydratedValue, type HydratedValues } from '../ui/jql-editor/types';
11
12
  export type ContextAwareTokenSuggestions = TokenSuggestions & {
@@ -64,6 +65,14 @@ export type ExternalInfo = {
64
65
  */
65
66
  message: ReactNode;
66
67
  };
68
+ export type CustomErrorComponent = React.ComponentType<PropsWithChildren<{
69
+ testId: string;
70
+ editorTheme: EditorTheme;
71
+ editorId: string;
72
+ }>>;
73
+ export type CustomComponents = {
74
+ ErrorMessage?: CustomErrorComponent;
75
+ };
67
76
  export type ExternalMessage = ExternalError | ExternalWarning | ExternalInfo;
68
77
  export type ExternalMessagesNormalized = {
69
78
  errors: ExternalError[];
@@ -220,6 +229,10 @@ export type State = {
220
229
  * handled which will prevent default behaviour of the help button, i.e. `e.preventDefault()`.
221
230
  */
222
231
  onSyntaxHelp?: (e: MouseEvent<HTMLElement>) => boolean;
232
+ /**
233
+ * Custom components to take over the rendering of certain parts of the jql editor
234
+ */
235
+ customComponents?: CustomComponents;
223
236
  };
224
237
  export type DebugMessageEventAttribute = string | number | boolean | void | null;
225
238
  export type Props = {
@@ -239,4 +252,5 @@ export type Props = {
239
252
  enableRichInlineNodes: boolean;
240
253
  onSyntaxHelp?: (e: MouseEvent<HTMLElement>) => boolean;
241
254
  onFocus?: (e: FocusEvent<HTMLElement>) => void;
255
+ customComponents?: CustomComponents;
242
256
  };
@@ -1,5 +1,5 @@
1
1
  export type { JQLClause } from '@atlaskit/jql-autocomplete';
2
2
  export type { JQLEditorUIProps, JQLEditorProps, HydratedValues, HydratedValue, HydratedUser, } from './ui/types';
3
- export type { ExternalMessage, ExternalError, ExternalWarning, ExternalInfo } from './state/types';
3
+ export type { ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, CustomComponents, } from './state/types';
4
4
  export type { AutocompleteProvider, AutocompleteOptions, AutocompleteOption, AutocompleteValueType, } from './plugins/types';
5
5
  export type { ListenerProps, JqlAnalyticsEvent } from './analytics';
@@ -1,7 +1,7 @@
1
1
  import { type FocusEvent, type MouseEvent, type Ref } from 'react';
2
2
  import { type Jast } from '@atlaskit/jql-ast';
3
3
  import { type AutocompleteProvider } from '../../plugins/autocomplete/types';
4
- import { type ExternalMessage } from '../../state/types';
4
+ import { type CustomComponents, type ExternalMessage } from '../../state/types';
5
5
  export type HydratedUser = {
6
6
  type: 'user';
7
7
  id: string;
@@ -98,4 +98,8 @@ export type JQLEditorUIProps = {
98
98
  inputRef?: Ref<{
99
99
  focus: () => void;
100
100
  }>;
101
+ /**
102
+ * Custom components to take over the rendering of certain parts of JQL editor
103
+ */
104
+ customComponents?: CustomComponents;
101
105
  };
@@ -2,4 +2,4 @@ export { default as JQLEditor } from './ui';
2
2
  export { JQLEditorAsync, preloadJQLEditor } from './async';
3
3
  export { JQLEditorReadOnly } from './ui/jql-editor-layout';
4
4
  export { JQLEditorAnalyticsListener, ANALYTICS_CHANNEL, useJqlPackageAnalytics, EventType, } from './analytics';
5
- export type { ListenerProps, JqlAnalyticsEvent, JQLEditorUIProps, JQLEditorProps, HydratedValue, HydratedValues, HydratedUser, AutocompleteOption, AutocompleteValueType, AutocompleteOptions, AutocompleteProvider, JQLClause, ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, } from './types';
5
+ export type { ListenerProps, JqlAnalyticsEvent, JQLEditorUIProps, JQLEditorProps, HydratedValue, HydratedValues, HydratedUser, AutocompleteOption, AutocompleteValueType, AutocompleteOptions, AutocompleteProvider, JQLClause, ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, CustomComponents, } from './types';
@@ -11,7 +11,7 @@ import { type AutocompleteOptionGroup, type AutocompleteOptions, type Autocomple
11
11
  import { type AutocompleteProvider } from '../plugins/types';
12
12
  import { type PortalActions } from '../ui/jql-editor-portal-provider/types';
13
13
  import { type HydratedDeprecatedField, type HydratedUser, type HydratedValue } from '../ui/jql-editor/types';
14
- import { type AutocompletePosition, type AutocompleteState, type ContextAwareJQLSuggestions, type ExternalMessagesNormalized, type OptionsKey, type Props, type State } from './types';
14
+ import { type AutocompletePosition, type AutocompleteState, type ContextAwareJQLSuggestions, type CustomErrorComponent, type ExternalMessagesNormalized, type OptionsKey, type Props, type State } from './types';
15
15
  export declare const initialState: State;
16
16
  export declare const actions: {
17
17
  onEditorViewBlur: () => Action<State>;
@@ -499,6 +499,38 @@ export declare const useExternalMessages: import("react-sweet-state").HookFuncti
499
499
  externalErrorMessageViewed: () => Action<State, Props>;
500
500
  createAndFireAnalyticsEvent: (payload: JqlEditorAnalyticsEvent) => Action<State, Props>;
501
501
  }>, void>;
502
+ export declare const useCustomErrorComponent: import("react-sweet-state").HookFunction<CustomErrorComponent | undefined, import("react-sweet-state").BoundActions<State, {
503
+ onEditorViewBlur: () => Action<State>;
504
+ onEditorViewFocus: (event: FocusEvent<HTMLElement>) => Action<State, Props>;
505
+ openAutocompleteOnNextUpdate: () => Action<State>;
506
+ closeAutocomplete: () => Action<State>;
507
+ setSelectedAutocompleteOptionId: (selectedOptionId: string | undefined) => Action<State>;
508
+ getAutocompleteSuggestions: (editorState: EditorState) => Action<State>;
509
+ getAutocompleteOptions: (suggestions: ContextAwareJQLSuggestions) => Action<State>;
510
+ appendOptionsForObservable: (key: OptionsKey, observable: Observable<AutocompleteOptions>, rule: JQLRuleSuggestion, type: AutocompleteOptionType) => Action<State, void, Observable<AutocompleteOptions>>;
511
+ cancelSubscription: () => Action<State>;
512
+ setLoading: (loading: boolean) => Action<State>;
513
+ setAutocompleteOptions: (options: AutocompleteOptionGroup) => Action<State>;
514
+ setAutocompleteContainer: (container: HTMLElement | null) => Action<State>;
515
+ callAutocompleteProviders: ({ rules, tokens }: ContextAwareJQLSuggestions) => Action<State>;
516
+ updateValidationState: () => Action<State>;
517
+ initialiseEditorState: () => Action<State, Props>;
518
+ configurePlugins: (portalActions: PortalActions | void) => Action<State, Props>;
519
+ onApplyEditorTransaction: (transaction: Transaction) => Action<State, Props>;
520
+ resetEditorState: (query: string, addToHistory?: boolean) => Action<State>;
521
+ initialiseEditorView: (editorViewNode: HTMLElement, attributes: {
522
+ [key: string]: string;
523
+ }, portalActions: PortalActions) => Action<State, Props>;
524
+ updateEditorView: (attributes: {
525
+ [key: string]: string;
526
+ }) => Action<State, Props>;
527
+ setEditorViewContainer: (editorViewContainer: HTMLElement) => Action<State>;
528
+ setEditorViewContainerScroll: (scroll: number) => Action<State>;
529
+ onSearch: () => Action<State>;
530
+ onSearchCommand: (pmState: EditorState, pmDispatch: ((tr: Transaction) => void) | undefined, pmView: EditorView | undefined, keyboardShortcut: boolean) => Action<State, Props, boolean>;
531
+ externalErrorMessageViewed: () => Action<State, Props>;
532
+ createAndFireAnalyticsEvent: (payload: JqlEditorAnalyticsEvent) => Action<State, Props>;
533
+ }>, void>;
502
534
  export declare const useAutocompleteOptions: import("react-sweet-state").HookFunction<SelectableAutocompleteOption[], import("react-sweet-state").BoundActions<State, {
503
535
  onEditorViewBlur: () => Action<State>;
504
536
  onEditorViewFocus: (event: FocusEvent<HTMLElement>) => Action<State, Props>;
@@ -1,4 +1,4 @@
1
- import { type FocusEvent, type MouseEvent, type MutableRefObject, type ReactNode } from 'react';
1
+ import { type FocusEvent, type MouseEvent, type MutableRefObject, type PropsWithChildren, type ReactNode } from 'react';
2
2
  import { type IntlShape } from 'react-intl-next';
3
3
  import { type Subscription } from 'rxjs/Subscription';
4
4
  import { type EditorState } from '@atlaskit/editor-prosemirror/state';
@@ -6,6 +6,7 @@ import { type EditorView } from '@atlaskit/editor-prosemirror/view';
6
6
  import { type Jast, type JQLParseError } from '@atlaskit/jql-ast';
7
7
  import { type JQLRuleContext, type JQLRuleSuggestions, type TokenSuggestions } from '@atlaskit/jql-autocomplete';
8
8
  import { type JqlEditorAnalyticsEvent } from '../analytics';
9
+ import { type EditorTheme } from '../hooks/use-editor-theme';
9
10
  import { type AutocompleteOptionGroup, type AutocompleteProvider } from '../plugins/autocomplete/types';
10
11
  import { type HydratedValue, type HydratedValues } from '../ui/jql-editor/types';
11
12
  export type ContextAwareTokenSuggestions = TokenSuggestions & {
@@ -64,6 +65,14 @@ export type ExternalInfo = {
64
65
  */
65
66
  message: ReactNode;
66
67
  };
68
+ export type CustomErrorComponent = React.ComponentType<PropsWithChildren<{
69
+ testId: string;
70
+ editorTheme: EditorTheme;
71
+ editorId: string;
72
+ }>>;
73
+ export type CustomComponents = {
74
+ ErrorMessage?: CustomErrorComponent;
75
+ };
67
76
  export type ExternalMessage = ExternalError | ExternalWarning | ExternalInfo;
68
77
  export type ExternalMessagesNormalized = {
69
78
  errors: ExternalError[];
@@ -220,6 +229,10 @@ export type State = {
220
229
  * handled which will prevent default behaviour of the help button, i.e. `e.preventDefault()`.
221
230
  */
222
231
  onSyntaxHelp?: (e: MouseEvent<HTMLElement>) => boolean;
232
+ /**
233
+ * Custom components to take over the rendering of certain parts of the jql editor
234
+ */
235
+ customComponents?: CustomComponents;
223
236
  };
224
237
  export type DebugMessageEventAttribute = string | number | boolean | void | null;
225
238
  export type Props = {
@@ -239,4 +252,5 @@ export type Props = {
239
252
  enableRichInlineNodes: boolean;
240
253
  onSyntaxHelp?: (e: MouseEvent<HTMLElement>) => boolean;
241
254
  onFocus?: (e: FocusEvent<HTMLElement>) => void;
255
+ customComponents?: CustomComponents;
242
256
  };
@@ -1,5 +1,5 @@
1
1
  export type { JQLClause } from '@atlaskit/jql-autocomplete';
2
2
  export type { JQLEditorUIProps, JQLEditorProps, HydratedValues, HydratedValue, HydratedUser, } from './ui/types';
3
- export type { ExternalMessage, ExternalError, ExternalWarning, ExternalInfo } from './state/types';
3
+ export type { ExternalMessage, ExternalError, ExternalWarning, ExternalInfo, CustomComponents, } from './state/types';
4
4
  export type { AutocompleteProvider, AutocompleteOptions, AutocompleteOption, AutocompleteValueType, } from './plugins/types';
5
5
  export type { ListenerProps, JqlAnalyticsEvent } from './analytics';
@@ -1,7 +1,7 @@
1
1
  import { type FocusEvent, type MouseEvent, type Ref } from 'react';
2
2
  import { type Jast } from '@atlaskit/jql-ast';
3
3
  import { type AutocompleteProvider } from '../../plugins/autocomplete/types';
4
- import { type ExternalMessage } from '../../state/types';
4
+ import { type CustomComponents, type ExternalMessage } from '../../state/types';
5
5
  export type HydratedUser = {
6
6
  type: 'user';
7
7
  id: string;
@@ -98,4 +98,8 @@ export type JQLEditorUIProps = {
98
98
  inputRef?: Ref<{
99
99
  focus: () => void;
100
100
  }>;
101
+ /**
102
+ * Custom components to take over the rendering of certain parts of JQL editor
103
+ */
104
+ customComponents?: CustomComponents;
101
105
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/jql-editor",
3
- "version": "4.10.7",
3
+ "version": "4.11.0",
4
4
  "description": "This package allows consumers to render an advanced JQL editor component to enable autocomplete-assisted authoring and validation of JQL queries.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -40,18 +40,18 @@
40
40
  "@atlaskit/avatar": "^21.17.0",
41
41
  "@atlaskit/button": "^20.3.0",
42
42
  "@atlaskit/editor-prosemirror": "6.0.0",
43
- "@atlaskit/form": "^10.5.0",
44
- "@atlaskit/icon": "^22.26.0",
43
+ "@atlaskit/form": "^10.6.0",
44
+ "@atlaskit/icon": "^22.27.0",
45
45
  "@atlaskit/jql-ast": "^3.3.0",
46
46
  "@atlaskit/jql-autocomplete": "^2.0.0",
47
47
  "@atlaskit/jql-editor-common": "^2.1.0",
48
48
  "@atlaskit/jql-parser": "^2.0.0",
49
49
  "@atlaskit/legacy-custom-icons": "^0.20.0",
50
50
  "@atlaskit/platform-feature-flags": "^0.3.0",
51
- "@atlaskit/primitives": "^13.2.0",
51
+ "@atlaskit/primitives": "^13.3.0",
52
52
  "@atlaskit/spinner": "^16.3.0",
53
53
  "@atlaskit/theme": "^14.0.0",
54
- "@atlaskit/tokens": "^2.3.0",
54
+ "@atlaskit/tokens": "^2.4.0",
55
55
  "@atlaskit/tooltip": "^18.9.0",
56
56
  "@babel/runtime": "^7.0.0",
57
57
  "@emotion/react": "^11.7.1",
@@ -77,6 +77,7 @@
77
77
  "@atlaskit/docs": "*",
78
78
  "@atlaskit/jql-editor-autocomplete-rest": "^2.1.0",
79
79
  "@atlaskit/visual-regression": "*",
80
+ "@atlassian/feature-flags-test-utils": "0.2.3",
80
81
  "@storybook/addon-actions": "^6.4.0",
81
82
  "@storybook/addon-knobs": "^6.4.0",
82
83
  "@testing-library/jest-dom": "^6.4.5",
@@ -127,6 +128,9 @@
127
128
  "platform-feature-flags": {
128
129
  "platform-component-visual-refresh": {
129
130
  "type": "boolean"
131
+ },
132
+ "custom_components_for_jql_editor": {
133
+ "type": "boolean"
130
134
  }
131
135
  }
132
136
  }