@rh-support/components 2.0.7 → 2.0.9
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/lib/cjs/AlertMessage/AlertMessage.js +4 -4
- package/lib/cjs/ConfirmationModal/ConfirmationContext.js +13 -41
- package/lib/cjs/ConfirmationModal/ConfirmationDialog.js +5 -5
- package/lib/cjs/CoverSpinner/CoverSpinner.js +1 -1
- package/lib/cjs/CustomContentLoader/CustomContentLoader.js +4 -4
- package/lib/cjs/CustomTextInput/CustomTextInput.js +8 -19
- package/lib/cjs/DropDownList/AsyncDropDownList.js +5 -5
- package/lib/cjs/DropDownList/DropDownList.js +45 -75
- package/lib/cjs/DropDownList/DropdownWrapper.js +7 -18
- package/lib/cjs/DropDownList/MultiSelectDropdownList.js +3 -3
- package/lib/cjs/DropDownList/SearchableList.js +41 -55
- package/lib/cjs/DropDownList/SelectList.js +15 -26
- package/lib/cjs/DropDownList/async.js +28 -38
- package/lib/cjs/DropDownList/dropdownUtils.js +9 -20
- package/lib/cjs/DropDownList/withMulti.js +15 -26
- package/lib/cjs/ErrorBoundary/ErrorBoundary.js +18 -47
- package/lib/cjs/ErrorBoundary/ErrorBoundaryFallbackComponent.js +10 -10
- package/lib/cjs/ErrorPages/Generic403.js +2 -2
- package/lib/cjs/FeedbackForm/FeedbackForm.js +24 -52
- package/lib/cjs/Functional/CaseContactsSelectorExternal.js +81 -154
- package/lib/cjs/InlineEdit/InlineEdit.js +56 -142
- package/lib/cjs/InlineEdit/NewInlineEdit.js +60 -145
- package/lib/cjs/LanguageSelector/LanguageSelector.js +10 -26
- package/lib/cjs/LoadingDots/LoadingDots.js +3 -3
- package/lib/cjs/LoadingIndicator/LoadingIndicator.js +3 -3
- package/lib/cjs/LoginModal/LoginModal.js +3 -3
- package/lib/cjs/MarkdownEditor/MarkdownEditor.js +113 -165
- package/lib/cjs/MoreOrLess/MoreOrLess.js +20 -40
- package/lib/cjs/PaginatedList/PaginatedList.js +15 -31
- package/lib/cjs/PaginationCompact/PaginationCompact.js +14 -31
- package/lib/cjs/ProgressBar/CircularProgressBar/CircularProgressBar.js +14 -14
- package/lib/cjs/ProgressBar/CircularProgressBar/Path.js +20 -18
- package/lib/cjs/ProgressBar/ProgressBar.js +8 -19
- package/lib/cjs/PromisifyModal/PromisifyModal.js +19 -36
- package/lib/cjs/SubscriptionAbuse/SubscriptionAbuseModal.js +5 -5
- package/lib/cjs/SubscriptionAbuse/const.js +3 -3
- package/lib/cjs/SupportFeedbackForm/SupportFeedbackForm.js +8 -24
- package/lib/cjs/SupportFeedbackForm/SupportFeedbackModal.js +50 -120
- package/lib/cjs/Table/PFTable.js +52 -89
- package/lib/cjs/Table/Table.js +12 -29
- package/lib/cjs/Table/TableColumnSelector.js +14 -15
- package/lib/cjs/Table/TablePagination.js +8 -8
- package/lib/cjs/Table/TableProvider.js +6 -6
- package/lib/cjs/TermsAndConditions/AcceptTermsModal.js +46 -100
- package/lib/cjs/TextAreaAutosize/TextAreaAutosize.js +35 -62
- package/lib/cjs/TextAreaResizable/TextAreaResizable.js +9 -25
- package/lib/cjs/ToastNotification/ToastNotification.js +35 -70
- package/lib/cjs/TopContentSearch/TopContentSearch.js +48 -113
- package/lib/cjs/ValueChangedIcon/ValueChangedIcon.js +13 -29
- package/lib/cjs/helperFunctions/errorMessage.js +13 -13
- package/lib/cjs/hooks/useBreakpoint.js +26 -43
- package/lib/cjs/hooks/useCopyToClipboard.js +8 -24
- package/lib/cjs/hooks/useDebounce.js +13 -38
- package/lib/cjs/hooks/useFetch.js +47 -123
- package/lib/cjs/hooks/useForceUpdate.js +2 -18
- package/lib/cjs/hooks/useForkRef.js +3 -3
- package/lib/cjs/hooks/useIsMounted.js +4 -4
- package/lib/cjs/hooks/useLRUCache.js +11 -11
- package/lib/cjs/hooks/useLocalStorage.js +7 -23
- package/lib/cjs/hooks/useOnScreen.js +5 -24
- package/lib/cjs/hooks/usePolling.js +8 -30
- package/lib/cjs/hooks/usePrevious.js +3 -3
- package/lib/cjs/hooks/useTitle.js +4 -4
- package/lib/cjs/hooks/useUndo.js +49 -72
- package/package.json +6 -7
|
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.LoginModal = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const react_core_1 = require("@patternfly/react-core");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const defaultProps = {
|
|
10
10
|
title: 'Welcome back',
|
|
11
11
|
buttonText: 'Log back in',
|
|
12
12
|
content: 'Log back in to view this content.',
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
3
|
if (k2 === undefined) k2 = k;
|
|
15
4
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
@@ -40,66 +29,34 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
40
29
|
}
|
|
41
30
|
return t;
|
|
42
31
|
};
|
|
43
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
44
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
45
|
-
if (!m) return o;
|
|
46
|
-
var i = m.call(o), r, ar = [], e;
|
|
47
|
-
try {
|
|
48
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
49
|
-
}
|
|
50
|
-
catch (error) { e = { error: error }; }
|
|
51
|
-
finally {
|
|
52
|
-
try {
|
|
53
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
54
|
-
}
|
|
55
|
-
finally { if (e) throw e.error; }
|
|
56
|
-
}
|
|
57
|
-
return ar;
|
|
58
|
-
};
|
|
59
|
-
var __values = (this && this.__values) || function(o) {
|
|
60
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
61
|
-
if (m) return m.call(o);
|
|
62
|
-
if (o && typeof o.length === "number") return {
|
|
63
|
-
next: function () {
|
|
64
|
-
if (o && i >= o.length) o = void 0;
|
|
65
|
-
return { value: o && o[i++], done: !o };
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
69
|
-
};
|
|
70
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
71
|
-
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
72
|
-
to[j] = from[i];
|
|
73
|
-
return to;
|
|
74
|
-
};
|
|
75
32
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
76
33
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
77
34
|
};
|
|
78
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
79
36
|
exports.MarkdownEditor = exports.EditorMode = void 0;
|
|
80
37
|
require("./markdownEditor.css");
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
38
|
+
const ui_toolkit_1 = require("@cee-eng/ui-toolkit");
|
|
39
|
+
const react_core_1 = require("@patternfly/react-core");
|
|
40
|
+
const code_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/code-icon"));
|
|
41
|
+
const image_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/image-icon"));
|
|
42
|
+
const link_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/link-icon"));
|
|
43
|
+
const list_ul_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/list-ul-icon"));
|
|
44
|
+
const quote_right_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/quote-right-icon"));
|
|
45
|
+
const trash_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/trash-icon"));
|
|
46
|
+
const utils_1 = require("@rh-support/utils");
|
|
47
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
48
|
+
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
|
|
49
|
+
const react_1 = __importStar(require("react"));
|
|
50
|
+
const react_i18next_1 = require("react-i18next");
|
|
51
|
+
const hooks_1 = require("../hooks");
|
|
95
52
|
var EditorMode;
|
|
96
53
|
(function (EditorMode) {
|
|
97
54
|
EditorMode["PLAIN"] = "plaintext";
|
|
98
55
|
EditorMode["MARKDOWN"] = "markdown";
|
|
99
56
|
})(EditorMode = exports.EditorMode || (exports.EditorMode = {}));
|
|
100
|
-
|
|
57
|
+
const defaultProps = {
|
|
101
58
|
value: '',
|
|
102
|
-
onChange:
|
|
59
|
+
onChange: () => { },
|
|
103
60
|
id: '',
|
|
104
61
|
className: '',
|
|
105
62
|
hidePreviewText: 'Hide preview',
|
|
@@ -118,161 +75,152 @@ var defaultProps = {
|
|
|
118
75
|
},
|
|
119
76
|
};
|
|
120
77
|
function MarkdownEditor(props) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
78
|
+
const { t } = react_i18next_1.useTranslation();
|
|
79
|
+
const { hidePreviewText, showPreviewText, mdPlaceholder, plainTextPlaceholder, textAreaClassName, bindTextArea, markedownOptions, allowEmoji, hideHeadingOptions, rows, showMarkdownPlainTextToggle, editorMode, className, charLimit, minCharsForCounter, id, onCommentExceedCharsLimit, fileSelectorProps: { onClipboardPaste, onFileDelete, onFileSelect, isSupportedFile, showFileSelectorInToolbar = false, isUploadingFile = false, filesList = [], attachFileBtn, } } = props, textAreaProps = __rest(props, ["hidePreviewText", "showPreviewText", "mdPlaceholder", "plainTextPlaceholder", "textAreaClassName", "bindTextArea", "markedownOptions", "allowEmoji", "hideHeadingOptions", "rows", "showMarkdownPlainTextToggle", "editorMode", "className", "charLimit", "minCharsForCounter", "id", "onCommentExceedCharsLimit", "fileSelectorProps"]);
|
|
80
|
+
const [isPreview, setIsPreview] = react_1.useState(false);
|
|
81
|
+
const [mdValue, setMdValue] = react_1.useState(props.value);
|
|
82
|
+
const previousFileList = hooks_1.usePrevious(filesList);
|
|
83
|
+
const [isPlainModeEnabled, setIsPlainModeEnabled] = react_1.useState(showMarkdownPlainTextToggle && props.editorMode === EditorMode.PLAIN ? true : false);
|
|
84
|
+
const textareaRef = react_1.useRef(null);
|
|
85
|
+
const { state, setURValue, undo, redo, resetURValue } = hooks_1.useUndo(props.value);
|
|
129
86
|
// for access inside event handlers
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
setIsFileSelectorOpen(
|
|
87
|
+
const isPlainModeEnabledRef = react_1.useRef(isPlainModeEnabled);
|
|
88
|
+
const [isFileSelectorOpen, setIsFileSelectorOpen] = react_1.useState(false);
|
|
89
|
+
const onFileSelectLocal = () => {
|
|
90
|
+
setIsFileSelectorOpen((open) => !open);
|
|
134
91
|
};
|
|
135
|
-
|
|
92
|
+
const onFileSelectToggle = (isOpen) => {
|
|
136
93
|
setIsFileSelectorOpen(isOpen);
|
|
137
94
|
};
|
|
138
|
-
react_1.useEffect(
|
|
95
|
+
react_1.useEffect(() => {
|
|
139
96
|
if ((previousFileList || []).length < (filesList || []).length && isUploadingFile) {
|
|
140
97
|
onFileInsert(filesList[0]);
|
|
141
98
|
}
|
|
142
99
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
143
100
|
}, [filesList]);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
?
|
|
147
|
-
:
|
|
101
|
+
const onFileInsert = (file) => {
|
|
102
|
+
const template = utils_1.isImageFile(file.fileType)
|
|
103
|
+
? ``
|
|
104
|
+
: `[${file.fileName}](${file.link})`;
|
|
148
105
|
insert(template, 0, 0);
|
|
149
|
-
|
|
106
|
+
const currentStart = textareaRef.current.selectionStart;
|
|
150
107
|
textareaRef.current.setSelectionRange(currentStart + template.length, currentStart + template.length);
|
|
151
108
|
onFileSelect && onFileSelect(file);
|
|
152
109
|
};
|
|
153
110
|
function pastedFile(items) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
var item = items_1_1.value;
|
|
158
|
-
if (isSupportedFile && isSupportedFile(item.type)) {
|
|
159
|
-
return item.getAsFile();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
164
|
-
finally {
|
|
165
|
-
try {
|
|
166
|
-
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
|
|
111
|
+
for (const item of items) {
|
|
112
|
+
if (isSupportedFile && isSupportedFile(item.type)) {
|
|
113
|
+
return item.getAsFile();
|
|
167
114
|
}
|
|
168
|
-
finally { if (e_1) throw e_1.error; }
|
|
169
115
|
}
|
|
170
116
|
return null;
|
|
171
117
|
}
|
|
172
|
-
|
|
118
|
+
const onPaste = (event) => {
|
|
173
119
|
if (!event.clipboardData || isPlainModeEnabledRef.current)
|
|
174
120
|
return;
|
|
175
121
|
if (!event.clipboardData.items)
|
|
176
122
|
return;
|
|
177
|
-
|
|
123
|
+
const file = pastedFile(event.clipboardData.items);
|
|
178
124
|
if (!file)
|
|
179
125
|
return;
|
|
180
|
-
|
|
126
|
+
const files = [file];
|
|
181
127
|
event.preventDefault();
|
|
182
128
|
onClipboardPaste(files);
|
|
183
129
|
};
|
|
184
130
|
// To handle dropped images
|
|
185
|
-
|
|
131
|
+
const onDrop = (event) => {
|
|
186
132
|
if (!event.dataTransfer.files)
|
|
187
133
|
return;
|
|
188
|
-
|
|
134
|
+
const file = event.dataTransfer.files[0];
|
|
189
135
|
if (!file)
|
|
190
136
|
return;
|
|
191
|
-
|
|
137
|
+
const files = [file];
|
|
192
138
|
event.preventDefault();
|
|
193
139
|
onClipboardPaste(files);
|
|
194
140
|
};
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return (react_1.default.createElement(react_core_1.DropdownItem, { key: file.id, onClick:
|
|
141
|
+
const getFileSelectorList = () => {
|
|
142
|
+
const filesAsDropdownItems = filesList.map((file) => {
|
|
143
|
+
return (react_1.default.createElement(react_core_1.DropdownItem, { key: file.id, onClick: () => {
|
|
198
144
|
onFileInsert(file);
|
|
199
145
|
} },
|
|
200
146
|
react_1.default.createElement(react_core_1.Flex, { flexWrap: { default: 'nowrap' } },
|
|
201
147
|
react_1.default.createElement(react_core_1.FlexItem, null,
|
|
202
148
|
react_1.default.createElement(react_core_1.Text, { component: react_core_1.TextVariants.small }, file.fileName)),
|
|
203
149
|
onFileDelete && (react_1.default.createElement(react_core_1.FlexItem, { className: "pf-u-ml-auto" },
|
|
204
|
-
react_1.default.createElement(react_core_1.Button, { variant: react_core_1.ButtonVariant.plain, onClick:
|
|
150
|
+
react_1.default.createElement(react_core_1.Button, { variant: react_core_1.ButtonVariant.plain, onClick: (event) => {
|
|
205
151
|
onFileSelectToggle(false);
|
|
206
152
|
onFileDelete(file);
|
|
207
153
|
event.stopPropagation();
|
|
208
154
|
} },
|
|
209
155
|
react_1.default.createElement(trash_icon_1.default, { color: "#c9190b" })))))));
|
|
210
156
|
});
|
|
211
|
-
return
|
|
157
|
+
return [
|
|
158
|
+
...filesAsDropdownItems,
|
|
159
|
+
...(filesAsDropdownItems.length > 0 ? [react_1.default.createElement(react_core_1.DropdownSeparator, { key: "separator" })] : []),
|
|
212
160
|
react_1.default.createElement(react_core_1.DropdownItem, { key: "separated link", component: attachFileBtn }),
|
|
213
|
-
]
|
|
161
|
+
];
|
|
214
162
|
};
|
|
215
|
-
|
|
163
|
+
const bindTextAreaRef = (ref) => {
|
|
216
164
|
textareaRef.current = ref;
|
|
217
165
|
if (props.bindTextArea)
|
|
218
166
|
props.bindTextArea(ref);
|
|
219
167
|
};
|
|
220
|
-
|
|
168
|
+
const onModeChange = (isPlainMode) => {
|
|
221
169
|
setIsPlainModeEnabled(isPlainMode);
|
|
222
170
|
isPlainModeEnabledRef.current = isPlainMode;
|
|
223
171
|
isPlainMode && isPreview && setIsPreview(false);
|
|
224
|
-
|
|
172
|
+
const mode = isPlainMode ? EditorMode.PLAIN : EditorMode.MARKDOWN;
|
|
225
173
|
props.onChange(mdValue, mode);
|
|
226
174
|
};
|
|
227
|
-
react_1.useEffect(
|
|
175
|
+
react_1.useEffect(() => {
|
|
228
176
|
if (mdValue !== props.value) {
|
|
229
177
|
setMdValue(props.value);
|
|
230
178
|
}
|
|
231
179
|
}, [mdValue, props.value]);
|
|
232
|
-
react_1.useEffect(
|
|
233
|
-
|
|
180
|
+
react_1.useEffect(() => {
|
|
181
|
+
const isPlainMode = props.editorMode === EditorMode.PLAIN ? true : false;
|
|
234
182
|
if (isPlainMode === isPlainModeEnabled)
|
|
235
183
|
return;
|
|
236
184
|
onModeChange(isPlainMode);
|
|
237
185
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
238
186
|
}, [props.editorMode]);
|
|
239
|
-
react_1.useEffect(
|
|
187
|
+
react_1.useEffect(() => {
|
|
240
188
|
// update state on undo redo
|
|
241
189
|
if (mdValue !== state.present) {
|
|
242
190
|
onValueChangeLocal(state.present);
|
|
243
191
|
}
|
|
244
192
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
245
193
|
}, [state.present]);
|
|
246
|
-
hooks_1.useDebounce(
|
|
194
|
+
hooks_1.useDebounce(() => {
|
|
247
195
|
if (isEmpty_1.default(mdValue))
|
|
248
196
|
return;
|
|
249
197
|
!isPlainModeEnabled && setURValue(mdValue);
|
|
250
198
|
}, [mdValue], 500);
|
|
251
|
-
|
|
252
|
-
|
|
199
|
+
const onValueChangeLocal = (text) => {
|
|
200
|
+
const mode = showMarkdownPlainTextToggle && isPlainModeEnabled ? EditorMode.PLAIN : EditorMode.MARKDOWN;
|
|
253
201
|
props.onChange(text, mode);
|
|
254
202
|
setMdValue(text);
|
|
255
203
|
};
|
|
256
|
-
|
|
257
|
-
|
|
204
|
+
const textChanged = (event) => {
|
|
205
|
+
let value = event.target.value;
|
|
258
206
|
if (!props.allowEmoji && utils_1.isEmojiPattern(value)) {
|
|
259
207
|
value = value.replace(utils_1.emojiPattern, '').trim();
|
|
260
208
|
}
|
|
261
209
|
onValueChangeLocal(value);
|
|
262
210
|
charLimit - value.length < 0 ? props.onCommentExceedCharsLimit(true) : props.onCommentExceedCharsLimit(false);
|
|
263
211
|
};
|
|
264
|
-
|
|
212
|
+
const hasSelection = () => {
|
|
265
213
|
return textareaRef.current.selectionStart !== textareaRef.current.selectionEnd;
|
|
266
214
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
215
|
+
const wrapSelection = (templateStart, templateEnd) => {
|
|
216
|
+
const currentText = textareaRef.current.value;
|
|
217
|
+
const posStart = textareaRef.current.selectionStart;
|
|
218
|
+
const posEnd = textareaRef.current.selectionEnd;
|
|
219
|
+
const selectedText = currentText.substring(posStart, posEnd);
|
|
220
|
+
const whitespaceEdges = selectedText.match(/^\s*|\s*$/g) || [];
|
|
221
|
+
const leadingWhitespace = whitespaceEdges[0] || '';
|
|
222
|
+
const trailingWhitespace = whitespaceEdges[1] || '';
|
|
223
|
+
const newText = currentText.substring(0, posStart) +
|
|
276
224
|
leadingWhitespace +
|
|
277
225
|
templateStart +
|
|
278
226
|
selectedText.trim() +
|
|
@@ -286,21 +234,21 @@ function MarkdownEditor(props) {
|
|
|
286
234
|
textareaRef.current.focus();
|
|
287
235
|
onValueChangeLocal(newText);
|
|
288
236
|
};
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
237
|
+
const wrapBasedOnNewLines = () => {
|
|
238
|
+
const currentText = textareaRef.current.value;
|
|
239
|
+
const posStart = textareaRef.current.selectionStart;
|
|
240
|
+
const posEnd = textareaRef.current.selectionEnd;
|
|
241
|
+
const selectedText = currentText.substring(posStart, posEnd);
|
|
242
|
+
const splitText = selectedText.split('\n');
|
|
243
|
+
const newText = currentText
|
|
296
244
|
.substring(0, posStart)
|
|
297
|
-
.concat(splitText.map(
|
|
245
|
+
.concat(splitText.map((v) => `- ${v}`).join('\n'), '\n', currentText.substring(posEnd));
|
|
298
246
|
onValueChangeLocal(newText);
|
|
299
247
|
};
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
248
|
+
const insert = (template, selectionStart, selectionEnd) => {
|
|
249
|
+
const currentText = textareaRef.current.value;
|
|
250
|
+
const pos = textareaRef.current.selectionStart;
|
|
251
|
+
const newText = currentText.substring(0, pos) + template + currentText.substring(pos);
|
|
304
252
|
onValueChangeLocal(newText);
|
|
305
253
|
textareaRef.current.value = newText;
|
|
306
254
|
textareaRef.current.selectionStart = pos + selectionStart;
|
|
@@ -308,7 +256,7 @@ function MarkdownEditor(props) {
|
|
|
308
256
|
textareaRef.current.focus();
|
|
309
257
|
onValueChangeLocal(newText);
|
|
310
258
|
};
|
|
311
|
-
|
|
259
|
+
const bold = () => {
|
|
312
260
|
if (hasSelection()) {
|
|
313
261
|
wrapSelection('**', '**');
|
|
314
262
|
}
|
|
@@ -316,7 +264,7 @@ function MarkdownEditor(props) {
|
|
|
316
264
|
insert('**TEXT**', 2, 6);
|
|
317
265
|
}
|
|
318
266
|
};
|
|
319
|
-
|
|
267
|
+
const italic = () => {
|
|
320
268
|
if (hasSelection()) {
|
|
321
269
|
wrapSelection('_', '_');
|
|
322
270
|
}
|
|
@@ -324,7 +272,7 @@ function MarkdownEditor(props) {
|
|
|
324
272
|
insert('_TEXT_', 1, 5);
|
|
325
273
|
}
|
|
326
274
|
};
|
|
327
|
-
|
|
275
|
+
const h1 = () => {
|
|
328
276
|
if (hasSelection()) {
|
|
329
277
|
wrapSelection('# ', '');
|
|
330
278
|
}
|
|
@@ -332,7 +280,7 @@ function MarkdownEditor(props) {
|
|
|
332
280
|
insert('# HEADING', 2, 9);
|
|
333
281
|
}
|
|
334
282
|
};
|
|
335
|
-
|
|
283
|
+
const h2 = () => {
|
|
336
284
|
if (hasSelection()) {
|
|
337
285
|
wrapSelection('## ', '');
|
|
338
286
|
}
|
|
@@ -340,7 +288,7 @@ function MarkdownEditor(props) {
|
|
|
340
288
|
insert('## HEADING', 3, 10);
|
|
341
289
|
}
|
|
342
290
|
};
|
|
343
|
-
|
|
291
|
+
const h3 = () => {
|
|
344
292
|
if (hasSelection()) {
|
|
345
293
|
wrapSelection('### ', '');
|
|
346
294
|
}
|
|
@@ -348,7 +296,7 @@ function MarkdownEditor(props) {
|
|
|
348
296
|
insert('### HEADING', 4, 11);
|
|
349
297
|
}
|
|
350
298
|
};
|
|
351
|
-
|
|
299
|
+
const list = () => {
|
|
352
300
|
if (hasSelection()) {
|
|
353
301
|
wrapBasedOnNewLines();
|
|
354
302
|
}
|
|
@@ -356,7 +304,7 @@ function MarkdownEditor(props) {
|
|
|
356
304
|
insert('- ITEM', 2, 6);
|
|
357
305
|
}
|
|
358
306
|
};
|
|
359
|
-
|
|
307
|
+
const link = () => {
|
|
360
308
|
if (hasSelection()) {
|
|
361
309
|
wrapSelection('[', '](URL "TITLE")');
|
|
362
310
|
}
|
|
@@ -364,7 +312,7 @@ function MarkdownEditor(props) {
|
|
|
364
312
|
insert('[LINK TEXT](URL "TITLE")', 1, 10);
|
|
365
313
|
}
|
|
366
314
|
};
|
|
367
|
-
|
|
315
|
+
const quote = () => {
|
|
368
316
|
if (hasSelection()) {
|
|
369
317
|
wrapSelection('> ', '\n');
|
|
370
318
|
}
|
|
@@ -372,7 +320,7 @@ function MarkdownEditor(props) {
|
|
|
372
320
|
insert('> QUOTE', 2, 7);
|
|
373
321
|
}
|
|
374
322
|
};
|
|
375
|
-
|
|
323
|
+
const code = () => {
|
|
376
324
|
if (hasSelection()) {
|
|
377
325
|
wrapSelection('~~~\n', '\n~~~\n');
|
|
378
326
|
}
|
|
@@ -380,15 +328,15 @@ function MarkdownEditor(props) {
|
|
|
380
328
|
insert('~~~\nCODE\n~~~\n', 4, 8);
|
|
381
329
|
}
|
|
382
330
|
};
|
|
383
|
-
|
|
384
|
-
setIsPreview(
|
|
331
|
+
const preview = () => {
|
|
332
|
+
setIsPreview((previewFlag) => !previewFlag);
|
|
385
333
|
};
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
334
|
+
const previewMDText = (mdText) => {
|
|
335
|
+
let text = mdText;
|
|
336
|
+
const markeddownOptions = Object.assign(Object.assign({}, props.markedownOptions), { openLinksInNewTab: true, gfm: true, breaks: true });
|
|
389
337
|
return ui_toolkit_1.parseCommentMarkdown(text, { openImagesInNewTab: false, lazyLoadImages: false }, markeddownOptions);
|
|
390
338
|
};
|
|
391
|
-
|
|
339
|
+
const keydown = (event) => {
|
|
392
340
|
if (event.ctrlKey) {
|
|
393
341
|
switch (event.key) {
|
|
394
342
|
case 'b':
|
|
@@ -422,20 +370,20 @@ function MarkdownEditor(props) {
|
|
|
422
370
|
}
|
|
423
371
|
}
|
|
424
372
|
};
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
return (react_1.default.createElement("span", { className:
|
|
373
|
+
const getCharCountText = (comment) => {
|
|
374
|
+
const charCountLeft = charLimit - comment.length;
|
|
375
|
+
return (react_1.default.createElement("span", { className: `character-count-wrapper ${charCountLeft <= 0 ? 'red' : ''}` },
|
|
428
376
|
"(",
|
|
429
|
-
t(
|
|
377
|
+
t(`{{charCountLeft}} characters left`, { charCountLeft }),
|
|
430
378
|
")"));
|
|
431
379
|
};
|
|
432
|
-
|
|
380
|
+
const contentRows = (props.value && props.value.split('\n').length + 1) || 4;
|
|
433
381
|
// reset undo redo value after post comment
|
|
434
382
|
props.disabled && !isEmpty_1.default(state.present) && resetURValue('');
|
|
435
383
|
// editor is disabled and preview is true -> set preview to false
|
|
436
384
|
props.disabled && isPreview && setIsPreview(false);
|
|
437
|
-
|
|
438
|
-
return (react_1.default.createElement("div", { className:
|
|
385
|
+
const disablePreviewButton = mdValue === '';
|
|
386
|
+
return (react_1.default.createElement("div", { className: `markdown-editor-container ${props.className}`, id: props.id, "data-tracking-id": "md-editor-container", onDrop: onDrop, onPaste: onPaste },
|
|
439
387
|
!isPlainModeEnabled && (react_1.default.createElement(react_core_1.Toolbar, { className: "pf-l-flex border-bottom" },
|
|
440
388
|
react_1.default.createElement(react_core_1.ToolbarGroup, { "data-tracking-id": "md-editor-toolbar", className: "markdown-toolbar-left-section pf-m-wrap" },
|
|
441
389
|
react_1.default.createElement(react_core_1.Button, { variant: react_core_1.ButtonVariant.plain, tabIndex: -1, isDisabled: props.disabled || isPreview, onClick: bold, "data-tracking-id": "md-editor-toolbar-b", title: "Bold" }, "B"),
|
|
@@ -460,13 +408,13 @@ function MarkdownEditor(props) {
|
|
|
460
408
|
react_1.default.createElement(react_core_1.ToolbarItem, null,
|
|
461
409
|
react_1.default.createElement("a", { className: "pf-c-button pf-m-link pf-m-inline markdown-guidance", rel: "noopener noreferrer", target: "_blank", href: "/articles/4729621", "data-tracking-id": "md-guidance" },
|
|
462
410
|
react_1.default.createElement(react_i18next_1.Trans, null, "Markdown guidance"))))),
|
|
463
|
-
react_1.default.createElement("div", { className: "markdown-content" }, !isPreview ? (react_1.default.createElement("textarea",
|
|
411
|
+
react_1.default.createElement("div", { className: "markdown-content" }, !isPreview ? (react_1.default.createElement("textarea", Object.assign({}, textAreaProps, { onKeyDown: keydown, placeholder: isPlainModeEnabled ? t(props.plainTextPlaceholder) : t(props.mdPlaceholder), ref: bindTextAreaRef, className: classnames_1.default('form-control', 'markdown-text-area', props.textAreaClassName, 'textArea'), value: mdValue, onChange: textChanged, rows: props.rows || contentRows }))) : (react_1.default.createElement("div", { className: "markdown-preview", style: { maxHeight: mdValue ? 310 : 100 } },
|
|
464
412
|
react_1.default.createElement("div", { dangerouslySetInnerHTML: {
|
|
465
413
|
__html: previewMDText(mdValue),
|
|
466
414
|
} })))),
|
|
467
|
-
react_1.default.createElement("div", null, props.showMarkdownPlainTextToggle && (react_1.default.createElement("div", { className:
|
|
415
|
+
react_1.default.createElement("div", null, props.showMarkdownPlainTextToggle && (react_1.default.createElement("div", { className: `markdown-toggle-toolbar pf-l-flex` },
|
|
468
416
|
react_1.default.createElement("span", { className: "markdown-toolbar-left-section" },
|
|
469
|
-
!isPlainModeEnabled && (react_1.default.createElement(react_core_1.Button, { className: "markdown-preview-btn", tabIndex: -1, variant: react_core_1.ButtonVariant.link, onClick: preview, title: "Show preview", "data-tracking-id":
|
|
417
|
+
!isPlainModeEnabled && (react_1.default.createElement(react_core_1.Button, { className: "markdown-preview-btn", tabIndex: -1, variant: react_core_1.ButtonVariant.link, onClick: preview, title: "Show preview", "data-tracking-id": `md-preview-${isPreview ? 'hide' : 'show'}`, isDisabled: disablePreviewButton }, isPreview ? (react_1.default.createElement("span", null,
|
|
470
418
|
" ",
|
|
471
419
|
t(hidePreviewText))) : (react_1.default.createElement("span", null,
|
|
472
420
|
" ",
|
|
@@ -478,9 +426,9 @@ function MarkdownEditor(props) {
|
|
|
478
426
|
react_1.default.createElement(react_core_1.Spinner, { className: "pf-u-ml-sm", size: "md" }))),
|
|
479
427
|
mdValue.length > props.minCharsForCounter && getCharCountText(mdValue)),
|
|
480
428
|
react_1.default.createElement("span", null,
|
|
481
|
-
react_1.default.createElement(react_core_1.Button, { variant: "plain", className: isPlainModeEnabled ? 'markdown-active-mode' : '', onClick:
|
|
429
|
+
react_1.default.createElement(react_core_1.Button, { variant: "plain", className: isPlainModeEnabled ? 'markdown-active-mode' : '', onClick: () => onModeChange(true), isDisabled: isPlainModeEnabled || isUploadingFile, "data-tracking-id": "md-editor-plaintext" },
|
|
482
430
|
react_1.default.createElement(react_i18next_1.Trans, null, "Plain text")),
|
|
483
|
-
react_1.default.createElement(react_core_1.Button, { variant: "plain", className: !isPlainModeEnabled ? 'markdown-active-mode' : '', onClick:
|
|
431
|
+
react_1.default.createElement(react_core_1.Button, { variant: "plain", className: !isPlainModeEnabled ? 'markdown-active-mode' : '', onClick: () => onModeChange(false), isDisabled: !isPlainModeEnabled, "data-tracking-id": "md-editor-md" },
|
|
484
432
|
react_1.default.createElement(react_i18next_1.Trans, null, "Markdown"))))))));
|
|
485
433
|
}
|
|
486
434
|
exports.MarkdownEditor = MarkdownEditor;
|
|
@@ -18,59 +18,39 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
22
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
23
|
-
if (!m) return o;
|
|
24
|
-
var i = m.call(o), r, ar = [], e;
|
|
25
|
-
try {
|
|
26
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
27
|
-
}
|
|
28
|
-
catch (error) { e = { error: error }; }
|
|
29
|
-
finally {
|
|
30
|
-
try {
|
|
31
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
32
|
-
}
|
|
33
|
-
finally { if (e) throw e.error; }
|
|
34
|
-
}
|
|
35
|
-
return ar;
|
|
36
|
-
};
|
|
37
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
38
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
39
23
|
};
|
|
40
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
25
|
exports.MoreOrLess = void 0;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
26
|
+
const utils_1 = require("@rh-support/utils");
|
|
27
|
+
const react_1 = __importStar(require("react"));
|
|
28
|
+
const react_i18next_1 = require("react-i18next");
|
|
29
|
+
const resize_observer_polyfill_1 = __importDefault(require("resize-observer-polyfill"));
|
|
30
|
+
const defaultProps = {
|
|
47
31
|
maxHeight: 500,
|
|
48
32
|
className: '',
|
|
49
33
|
};
|
|
50
34
|
function MoreOrLess(props) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
const { t } = react_i18next_1.useTranslation();
|
|
36
|
+
const [isVisible, setVisibility] = react_1.useState(false);
|
|
37
|
+
const [y, setY] = react_1.useState(undefined);
|
|
38
|
+
const [elem, setElem] = react_1.useState(null);
|
|
39
|
+
const sectionRef = react_1.useRef(null);
|
|
56
40
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
react_1.useEffect(function () {
|
|
61
|
-
return function () { return resizeObserver.disconnect(); };
|
|
41
|
+
const resizeObserver = new resize_observer_polyfill_1.default(() => elem.scrollHeight > props.maxHeight ? setVisibility(true) : setVisibility(false));
|
|
42
|
+
react_1.useEffect(() => {
|
|
43
|
+
return () => resizeObserver.disconnect();
|
|
62
44
|
}, [resizeObserver]);
|
|
63
|
-
|
|
45
|
+
const ref = react_1.useCallback((node) => {
|
|
64
46
|
if (node !== null) {
|
|
65
47
|
setElem(node);
|
|
66
48
|
resizeObserver.observe(node);
|
|
67
49
|
}
|
|
68
50
|
}, [resizeObserver]);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
73
|
-
var handleMoreOrLess = function (e) {
|
|
51
|
+
const [showLess, setShowLess] = react_1.useState(false);
|
|
52
|
+
const getClassAndText = () => showLess ? { text: t('Show less'), class: 'Show less' } : { text: t('Show more'), class: 'Show more' };
|
|
53
|
+
const handleMoreOrLess = (e) => {
|
|
74
54
|
e.preventDefault();
|
|
75
55
|
// save scroll y position after click on more and then
|
|
76
56
|
// scroll to the saved y position after clicking on less
|
|
@@ -81,11 +61,11 @@ function MoreOrLess(props) {
|
|
|
81
61
|
utils_1.scrollIntoView(sectionRef, { navBarRef: props.appStickyHeaderRef, timeout: 0, offset: 30 });
|
|
82
62
|
setY(undefined);
|
|
83
63
|
}
|
|
84
|
-
setShowLess(
|
|
64
|
+
setShowLess((prevState) => !prevState);
|
|
85
65
|
};
|
|
86
|
-
return (react_1.default.createElement("div", { className:
|
|
66
|
+
return (react_1.default.createElement("div", { className: `${props.className}`, ref: sectionRef },
|
|
87
67
|
react_1.default.createElement("div", { ref: ref, style: { maxHeight: props.maxHeight + 'px' }, className: 'more-less-wrapper ' + (showLess ? 'open' : '') }, props.children),
|
|
88
|
-
isVisible && (react_1.default.createElement("button", { onClick: handleMoreOrLess, className:
|
|
68
|
+
isVisible && (react_1.default.createElement("button", { onClick: handleMoreOrLess, className: `btn btn-app btn-link ${getClassAndText().class}`, type: "button" }, getClassAndText().text))));
|
|
89
69
|
}
|
|
90
70
|
exports.MoreOrLess = MoreOrLess;
|
|
91
71
|
MoreOrLess.defaultProps = defaultProps;
|