@patternfly/chatbot 6.5.0-prerelease.7 → 6.5.0-prerelease.8
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/dist/cjs/AttachMenu/AttachMenu.d.ts +1 -1
- package/dist/cjs/AttachMenu/AttachMenu.js +1 -1
- package/dist/cjs/MessageBar/AttachButton.d.ts +2 -0
- package/dist/cjs/MessageBar/AttachButton.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.test.js +4 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +3 -5
- package/dist/cjs/MessageBar/MessageBar.js +2 -2
- package/dist/cjs/MessageBar/MessageBar.test.js +17 -0
- package/dist/esm/AttachMenu/AttachMenu.d.ts +1 -1
- package/dist/esm/AttachMenu/AttachMenu.js +1 -1
- package/dist/esm/MessageBar/AttachButton.d.ts +2 -0
- package/dist/esm/MessageBar/AttachButton.js +2 -2
- package/dist/esm/MessageBar/AttachButton.test.js +4 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +3 -5
- package/dist/esm/MessageBar/MessageBar.js +2 -2
- package/dist/esm/MessageBar/MessageBar.test.js +17 -0
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +3 -1
- package/src/AttachMenu/AttachMenu.tsx +13 -11
- package/src/MessageBar/AttachButton.test.tsx +4 -0
- package/src/MessageBar/AttachButton.tsx +4 -1
- package/src/MessageBar/MessageBar.test.tsx +28 -0
- package/src/MessageBar/MessageBar.tsx +5 -9
|
@@ -4,7 +4,7 @@ export interface AttachMenuProps extends DropdownProps {
|
|
|
4
4
|
/** Items in menu */
|
|
5
5
|
filteredItems: React.ReactNode;
|
|
6
6
|
/** A callback for when the input value changes. */
|
|
7
|
-
handleTextInputChange
|
|
7
|
+
handleTextInputChange?: (value: string) => void;
|
|
8
8
|
/** Flag to indicate if menu is opened. */
|
|
9
9
|
isOpen: boolean;
|
|
10
10
|
/** Additional properties to pass to the Popper */
|
|
@@ -17,7 +17,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
17
17
|
const react_core_1 = require("@patternfly/react-core");
|
|
18
18
|
const AttachMenu = (_a) => {
|
|
19
19
|
var { className, filteredItems, handleTextInputChange, isOpen, popperProps = undefined, onOpenChange, onOpenChangeKeys, onSelect, searchInputPlaceholder, searchInputAriaLabel = 'Filter menu items', toggle, menuSearchProps, menuSearchInputProps, searchInputProps } = _a, props = __rest(_a, ["className", "filteredItems", "handleTextInputChange", "isOpen", "popperProps", "onOpenChange", "onOpenChangeKeys", "onSelect", "searchInputPlaceholder", "searchInputAriaLabel", "toggle", "menuSearchProps", "menuSearchInputProps", "searchInputProps"]);
|
|
20
|
-
return ((0, jsx_runtime_1.jsxs)(react_core_1.Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.MenuSearch, Object.assign({}, menuSearchProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.MenuSearchInput, Object.assign({}, menuSearchInputProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)) })) })), filteredItems] })));
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)(react_core_1.Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [handleTextInputChange && ((0, jsx_runtime_1.jsx)(react_core_1.MenuSearch, Object.assign({}, menuSearchProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.MenuSearchInput, Object.assign({}, menuSearchInputProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)) })) }))), filteredItems] })));
|
|
21
21
|
};
|
|
22
22
|
exports.AttachMenu = AttachMenu;
|
|
23
23
|
exports.default = exports.AttachMenu;
|
|
@@ -41,5 +41,7 @@ export interface AttachButtonProps extends ButtonProps {
|
|
|
41
41
|
validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
|
|
42
42
|
/** Additional props passed to react-dropzone */
|
|
43
43
|
dropzoneProps?: DropzoneOptions;
|
|
44
|
+
/** Icon displayed in attach button */
|
|
45
|
+
icon?: React.ReactNode;
|
|
44
46
|
}
|
|
45
47
|
export declare const AttachButton: import("react").ForwardRefExoticComponent<AttachButtonProps & import("react").RefAttributes<any>>;
|
|
@@ -19,12 +19,12 @@ const react_core_1 = require("@patternfly/react-core");
|
|
|
19
19
|
const react_dropzone_1 = require("react-dropzone");
|
|
20
20
|
const paperclip_icon_1 = require("@patternfly/react-icons/dist/esm/icons/paperclip-icon");
|
|
21
21
|
const AttachButtonBase = (_a) => {
|
|
22
|
-
var { onAttachAccepted, onClick, isDisabled, className, tooltipProps, innerRef, tooltipContent = 'Attach', inputTestId, isCompact, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps } = _a, props = __rest(_a, ["onAttachAccepted", "onClick", "isDisabled", "className", "tooltipProps", "innerRef", "tooltipContent", "inputTestId", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps"]);
|
|
22
|
+
var { onAttachAccepted, onClick, isDisabled, className, tooltipProps, innerRef, tooltipContent = 'Attach', inputTestId, isCompact, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, icon = (0, jsx_runtime_1.jsx)(paperclip_icon_1.PaperclipIcon, {}) } = _a, props = __rest(_a, ["onAttachAccepted", "onClick", "isDisabled", "className", "tooltipProps", "innerRef", "tooltipContent", "inputTestId", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "icon"]);
|
|
23
23
|
const { open, getInputProps } = (0, react_dropzone_1.useDropzone)(Object.assign({ multiple: true, onDropAccepted: onAttachAccepted, accept: allowedFileTypes, minSize,
|
|
24
24
|
maxSize,
|
|
25
25
|
maxFiles, disabled: isAttachmentDisabled, onDrop: onAttach, onDropRejected: onAttachRejected, validator }, dropzoneProps));
|
|
26
26
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", Object.assign({ "data-testid": inputTestId }, getInputProps(), { hidden: true })), (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ id: "pf-chatbot__tooltip--attach", content: tooltipContent, position: "top", entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0,
|
|
27
27
|
// prevents VO announcements of both aria label and tooltip
|
|
28
|
-
aria: "none" }, tooltipProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ variant: "plain", ref: innerRef, className: `pf-chatbot__button--attach ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Attach', isDisabled: isDisabled, onClick: onClick !== null && onClick !== void 0 ? onClick : open, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true, children:
|
|
28
|
+
aria: "none" }, tooltipProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ variant: "plain", ref: innerRef, className: `pf-chatbot__button--attach ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Attach', isDisabled: isDisabled, onClick: onClick !== null && onClick !== void 0 ? onClick : open, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true, children: icon }), size: isCompact ? 'sm' : undefined }, props)) }))] }));
|
|
29
29
|
};
|
|
30
30
|
exports.AttachButton = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(AttachButtonBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -145,4 +145,8 @@ describe('Attach button', () => {
|
|
|
145
145
|
expect(validator).toHaveBeenCalledWith(file);
|
|
146
146
|
expect(onAttachRejected).toHaveBeenCalled();
|
|
147
147
|
}));
|
|
148
|
+
it('should handle icon prop', () => {
|
|
149
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, { icon: (0, jsx_runtime_1.jsx)("img", { alt: "", src: "" }) }));
|
|
150
|
+
expect(react_1.screen.getByRole('img')).toBeVisible();
|
|
151
|
+
});
|
|
148
152
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'react';
|
|
2
2
|
import { Accept, DropEvent, DropzoneOptions, FileError, FileRejection } from 'react-dropzone';
|
|
3
3
|
import { ButtonProps, MenuSearchInputProps, MenuSearchProps, SearchInputProps, TextAreaProps, TooltipProps } from '@patternfly/react-core';
|
|
4
|
+
import { AttachButtonProps } from './AttachButton';
|
|
4
5
|
import { ChatbotDisplayMode } from '../Chatbot';
|
|
5
6
|
export interface MessageBarWithAttachMenuProps {
|
|
6
7
|
/** Flag to enable whether attach menu is open */
|
|
@@ -12,7 +13,7 @@ export interface MessageBarWithAttachMenuProps {
|
|
|
12
13
|
/** A callback for when the attachment menu toggle is clicked */
|
|
13
14
|
onAttachMenuToggleClick: () => void;
|
|
14
15
|
/** A callback for when the input value in the menu changes. */
|
|
15
|
-
onAttachMenuInputChange
|
|
16
|
+
onAttachMenuInputChange?: (value: string) => void;
|
|
16
17
|
/** Function callback called when user selects item in menu. */
|
|
17
18
|
onAttachMenuSelect?: (event?: React.MouseEvent<Element, MouseEvent>, value?: string | number) => void;
|
|
18
19
|
/** Placeholder for search input */
|
|
@@ -77,11 +78,8 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
|
|
|
77
78
|
isSendButtonDisabled?: boolean;
|
|
78
79
|
/** Prop to allow passage of additional props to buttons */
|
|
79
80
|
buttonProps?: {
|
|
80
|
-
attach?: {
|
|
81
|
-
tooltipContent?: string;
|
|
81
|
+
attach?: AttachButtonProps & {
|
|
82
82
|
props?: ButtonProps;
|
|
83
|
-
inputTestId?: string;
|
|
84
|
-
tooltipProps?: Omit<TooltipProps, 'content'>;
|
|
85
83
|
};
|
|
86
84
|
stop?: {
|
|
87
85
|
tooltipContent?: string;
|
|
@@ -193,11 +193,11 @@ const MessageBarBase = (_a) => {
|
|
|
193
193
|
onChange && onChange({}, message);
|
|
194
194
|
};
|
|
195
195
|
const renderButtons = () => {
|
|
196
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r
|
|
196
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
197
197
|
if (hasStopButton && handleStopButton) {
|
|
198
198
|
return ((0, jsx_runtime_1.jsx)(StopButton_1.default, Object.assign({ onClick: handleStopButton, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _a === void 0 ? void 0 : _a.tooltipContent, isCompact: isCompact, tooltipProps: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _b === void 0 ? void 0 : _b.tooltipProps }, (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _c === void 0 ? void 0 : _c.props)));
|
|
199
199
|
}
|
|
200
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [attachMenuProps && ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps },
|
|
200
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [attachMenuProps && ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach))), !attachMenuProps && hasAttachButton && ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipContent, inputTestId: (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _g === void 0 ? void 0 : _g.inputTestId, isCompact: isCompact, tooltipProps: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _h === void 0 ? void 0 : _h.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _j === void 0 ? void 0 : _j.props))), hasMicrophoneButton && ((0, jsx_runtime_1.jsx)(MicrophoneButton_1.default, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.tooltipContent, language: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _l === void 0 ? void 0 : _l.language, isCompact: isCompact, tooltipProps: (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _m === void 0 ? void 0 : _m.tooltipProps }, (_o = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _o === void 0 ? void 0 : _o.props))), (alwayShowSendButton || message) && ((0, jsx_runtime_1.jsx)(SendButton_1.default, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_p = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _p === void 0 ? void 0 : _p.tooltipContent, isCompact: isCompact, tooltipProps: (_q = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _q === void 0 ? void 0 : _q.tooltipProps }, (_r = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _r === void 0 ? void 0 : _r.props)))] }));
|
|
201
201
|
};
|
|
202
202
|
const messageBarContents = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
|
|
203
203
|
if (attachMenuProps) {
|
|
@@ -192,6 +192,15 @@ describe('Message bar', () => {
|
|
|
192
192
|
} }));
|
|
193
193
|
expect(react_1.screen.getByTestId('menu-search-input')).toBeTruthy();
|
|
194
194
|
});
|
|
195
|
+
it('can remove input from attach menu', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
196
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn, attachMenuProps: {
|
|
197
|
+
isAttachMenuOpen: true,
|
|
198
|
+
setIsAttachMenuOpen: jest.fn(),
|
|
199
|
+
onAttachMenuToggleClick: jest.fn(),
|
|
200
|
+
attachMenuItems: ATTACH_MENU_ITEMS
|
|
201
|
+
} }));
|
|
202
|
+
expect(react_1.screen.queryByRole('textbox', { name: /Filter menu items/i })).not.toBeInTheDocument();
|
|
203
|
+
}));
|
|
195
204
|
it('can hide attach button', () => {
|
|
196
205
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: false }));
|
|
197
206
|
expect(react_1.screen.queryByRole('button', { name: 'Attach' })).toBeFalsy();
|
|
@@ -223,6 +232,14 @@ describe('Message bar', () => {
|
|
|
223
232
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: { attach: { props: { 'aria-label': 'Test' } } } }));
|
|
224
233
|
yield user_event_1.default.click(react_1.screen.getByRole('button', { name: 'Test' }));
|
|
225
234
|
}));
|
|
235
|
+
it('can change attach button icon', () => {
|
|
236
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: {
|
|
237
|
+
attach: {
|
|
238
|
+
icon: (0, jsx_runtime_1.jsx)("img", { alt: "", src: "" })
|
|
239
|
+
}
|
|
240
|
+
} }));
|
|
241
|
+
expect(react_1.screen.getByRole('img')).toBeVisible();
|
|
242
|
+
});
|
|
226
243
|
// Stop button
|
|
227
244
|
// --------------------------------------------------------------------------
|
|
228
245
|
it('can show stop button', () => {
|
|
@@ -4,7 +4,7 @@ export interface AttachMenuProps extends DropdownProps {
|
|
|
4
4
|
/** Items in menu */
|
|
5
5
|
filteredItems: React.ReactNode;
|
|
6
6
|
/** A callback for when the input value changes. */
|
|
7
|
-
handleTextInputChange
|
|
7
|
+
handleTextInputChange?: (value: string) => void;
|
|
8
8
|
/** Flag to indicate if menu is opened. */
|
|
9
9
|
isOpen: boolean;
|
|
10
10
|
/** Additional properties to pass to the Popper */
|
|
@@ -14,6 +14,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
import { MenuSearch, MenuSearchInput, SearchInput, Dropdown } from '@patternfly/react-core';
|
|
15
15
|
export const AttachMenu = (_a) => {
|
|
16
16
|
var { className, filteredItems, handleTextInputChange, isOpen, popperProps = undefined, onOpenChange, onOpenChangeKeys, onSelect, searchInputPlaceholder, searchInputAriaLabel = 'Filter menu items', toggle, menuSearchProps, menuSearchInputProps, searchInputProps } = _a, props = __rest(_a, ["className", "filteredItems", "handleTextInputChange", "isOpen", "popperProps", "onOpenChange", "onOpenChangeKeys", "onSelect", "searchInputPlaceholder", "searchInputAriaLabel", "toggle", "menuSearchProps", "menuSearchInputProps", "searchInputProps"]);
|
|
17
|
-
return (_jsxs(Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [_jsx(MenuSearch, Object.assign({}, menuSearchProps, { children: _jsx(MenuSearchInput, Object.assign({}, menuSearchInputProps, { children: _jsx(SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)) })) })), filteredItems] })));
|
|
17
|
+
return (_jsxs(Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [handleTextInputChange && (_jsx(MenuSearch, Object.assign({}, menuSearchProps, { children: _jsx(MenuSearchInput, Object.assign({}, menuSearchInputProps, { children: _jsx(SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)) })) }))), filteredItems] })));
|
|
18
18
|
};
|
|
19
19
|
export default AttachMenu;
|
|
@@ -41,5 +41,7 @@ export interface AttachButtonProps extends ButtonProps {
|
|
|
41
41
|
validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
|
|
42
42
|
/** Additional props passed to react-dropzone */
|
|
43
43
|
dropzoneProps?: DropzoneOptions;
|
|
44
|
+
/** Icon displayed in attach button */
|
|
45
|
+
icon?: React.ReactNode;
|
|
44
46
|
}
|
|
45
47
|
export declare const AttachButton: import("react").ForwardRefExoticComponent<AttachButtonProps & import("react").RefAttributes<any>>;
|
|
@@ -16,12 +16,12 @@ import { Button, Icon, Tooltip } from '@patternfly/react-core';
|
|
|
16
16
|
import { useDropzone } from 'react-dropzone';
|
|
17
17
|
import { PaperclipIcon } from '@patternfly/react-icons/dist/esm/icons/paperclip-icon';
|
|
18
18
|
const AttachButtonBase = (_a) => {
|
|
19
|
-
var { onAttachAccepted, onClick, isDisabled, className, tooltipProps, innerRef, tooltipContent = 'Attach', inputTestId, isCompact, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps } = _a, props = __rest(_a, ["onAttachAccepted", "onClick", "isDisabled", "className", "tooltipProps", "innerRef", "tooltipContent", "inputTestId", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps"]);
|
|
19
|
+
var { onAttachAccepted, onClick, isDisabled, className, tooltipProps, innerRef, tooltipContent = 'Attach', inputTestId, isCompact, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, icon = _jsx(PaperclipIcon, {}) } = _a, props = __rest(_a, ["onAttachAccepted", "onClick", "isDisabled", "className", "tooltipProps", "innerRef", "tooltipContent", "inputTestId", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "icon"]);
|
|
20
20
|
const { open, getInputProps } = useDropzone(Object.assign({ multiple: true, onDropAccepted: onAttachAccepted, accept: allowedFileTypes, minSize,
|
|
21
21
|
maxSize,
|
|
22
22
|
maxFiles, disabled: isAttachmentDisabled, onDrop: onAttach, onDropRejected: onAttachRejected, validator }, dropzoneProps));
|
|
23
23
|
return (_jsxs(_Fragment, { children: [_jsx("input", Object.assign({ "data-testid": inputTestId }, getInputProps(), { hidden: true })), _jsx(Tooltip, Object.assign({ id: "pf-chatbot__tooltip--attach", content: tooltipContent, position: "top", entryDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.entryDelay) || 0, exitDelay: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.exitDelay) || 0, distance: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.distance) || 8, animationDuration: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.animationDuration) || 0,
|
|
24
24
|
// prevents VO announcements of both aria label and tooltip
|
|
25
|
-
aria: "none" }, tooltipProps, { children: _jsx(Button, Object.assign({ variant: "plain", ref: innerRef, className: `pf-chatbot__button--attach ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Attach', isDisabled: isDisabled, onClick: onClick !== null && onClick !== void 0 ? onClick : open, icon: _jsx(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true, children:
|
|
25
|
+
aria: "none" }, tooltipProps, { children: _jsx(Button, Object.assign({ variant: "plain", ref: innerRef, className: `pf-chatbot__button--attach ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Attach', isDisabled: isDisabled, onClick: onClick !== null && onClick !== void 0 ? onClick : open, icon: _jsx(Icon, { iconSize: isCompact ? 'lg' : 'xl', isInline: true, children: icon }), size: isCompact ? 'sm' : undefined }, props)) }))] }));
|
|
26
26
|
};
|
|
27
27
|
export const AttachButton = forwardRef((props, ref) => (_jsx(AttachButtonBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -140,4 +140,8 @@ describe('Attach button', () => {
|
|
|
140
140
|
expect(validator).toHaveBeenCalledWith(file);
|
|
141
141
|
expect(onAttachRejected).toHaveBeenCalled();
|
|
142
142
|
}));
|
|
143
|
+
it('should handle icon prop', () => {
|
|
144
|
+
render(_jsx(AttachButton, { icon: _jsx("img", { alt: "", src: "" }) }));
|
|
145
|
+
expect(screen.getByRole('img')).toBeVisible();
|
|
146
|
+
});
|
|
143
147
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'react';
|
|
2
2
|
import { Accept, DropEvent, DropzoneOptions, FileError, FileRejection } from 'react-dropzone';
|
|
3
3
|
import { ButtonProps, MenuSearchInputProps, MenuSearchProps, SearchInputProps, TextAreaProps, TooltipProps } from '@patternfly/react-core';
|
|
4
|
+
import { AttachButtonProps } from './AttachButton';
|
|
4
5
|
import { ChatbotDisplayMode } from '../Chatbot';
|
|
5
6
|
export interface MessageBarWithAttachMenuProps {
|
|
6
7
|
/** Flag to enable whether attach menu is open */
|
|
@@ -12,7 +13,7 @@ export interface MessageBarWithAttachMenuProps {
|
|
|
12
13
|
/** A callback for when the attachment menu toggle is clicked */
|
|
13
14
|
onAttachMenuToggleClick: () => void;
|
|
14
15
|
/** A callback for when the input value in the menu changes. */
|
|
15
|
-
onAttachMenuInputChange
|
|
16
|
+
onAttachMenuInputChange?: (value: string) => void;
|
|
16
17
|
/** Function callback called when user selects item in menu. */
|
|
17
18
|
onAttachMenuSelect?: (event?: React.MouseEvent<Element, MouseEvent>, value?: string | number) => void;
|
|
18
19
|
/** Placeholder for search input */
|
|
@@ -77,11 +78,8 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
|
|
|
77
78
|
isSendButtonDisabled?: boolean;
|
|
78
79
|
/** Prop to allow passage of additional props to buttons */
|
|
79
80
|
buttonProps?: {
|
|
80
|
-
attach?: {
|
|
81
|
-
tooltipContent?: string;
|
|
81
|
+
attach?: AttachButtonProps & {
|
|
82
82
|
props?: ButtonProps;
|
|
83
|
-
inputTestId?: string;
|
|
84
|
-
tooltipProps?: Omit<TooltipProps, 'content'>;
|
|
85
83
|
};
|
|
86
84
|
stop?: {
|
|
87
85
|
tooltipContent?: string;
|
|
@@ -187,11 +187,11 @@ export const MessageBarBase = (_a) => {
|
|
|
187
187
|
onChange && onChange({}, message);
|
|
188
188
|
};
|
|
189
189
|
const renderButtons = () => {
|
|
190
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r
|
|
190
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
191
191
|
if (hasStopButton && handleStopButton) {
|
|
192
192
|
return (_jsx(StopButton, Object.assign({ onClick: handleStopButton, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _a === void 0 ? void 0 : _a.tooltipContent, isCompact: isCompact, tooltipProps: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _b === void 0 ? void 0 : _b.tooltipProps }, (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _c === void 0 ? void 0 : _c.props)));
|
|
193
193
|
}
|
|
194
|
-
return (_jsxs(_Fragment, { children: [attachMenuProps && (_jsx(AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps },
|
|
194
|
+
return (_jsxs(_Fragment, { children: [attachMenuProps && (_jsx(AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach))), !attachMenuProps && hasAttachButton && (_jsx(AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipContent, inputTestId: (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _g === void 0 ? void 0 : _g.inputTestId, isCompact: isCompact, tooltipProps: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _h === void 0 ? void 0 : _h.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _j === void 0 ? void 0 : _j.props))), hasMicrophoneButton && (_jsx(MicrophoneButton, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.tooltipContent, language: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _l === void 0 ? void 0 : _l.language, isCompact: isCompact, tooltipProps: (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _m === void 0 ? void 0 : _m.tooltipProps }, (_o = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _o === void 0 ? void 0 : _o.props))), (alwayShowSendButton || message) && (_jsx(SendButton, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_p = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _p === void 0 ? void 0 : _p.tooltipContent, isCompact: isCompact, tooltipProps: (_q = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _q === void 0 ? void 0 : _q.tooltipProps }, (_r = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _r === void 0 ? void 0 : _r.props)))] }));
|
|
195
195
|
};
|
|
196
196
|
const messageBarContents = (_jsxs(_Fragment, { children: [_jsx("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: _jsx(TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), _jsx("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
|
|
197
197
|
if (attachMenuProps) {
|
|
@@ -187,6 +187,15 @@ describe('Message bar', () => {
|
|
|
187
187
|
} }));
|
|
188
188
|
expect(screen.getByTestId('menu-search-input')).toBeTruthy();
|
|
189
189
|
});
|
|
190
|
+
it('can remove input from attach menu', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
191
|
+
render(_jsx(MessageBar, { onSendMessage: jest.fn, attachMenuProps: {
|
|
192
|
+
isAttachMenuOpen: true,
|
|
193
|
+
setIsAttachMenuOpen: jest.fn(),
|
|
194
|
+
onAttachMenuToggleClick: jest.fn(),
|
|
195
|
+
attachMenuItems: ATTACH_MENU_ITEMS
|
|
196
|
+
} }));
|
|
197
|
+
expect(screen.queryByRole('textbox', { name: /Filter menu items/i })).not.toBeInTheDocument();
|
|
198
|
+
}));
|
|
190
199
|
it('can hide attach button', () => {
|
|
191
200
|
render(_jsx(MessageBar, { onSendMessage: jest.fn, hasAttachButton: false }));
|
|
192
201
|
expect(screen.queryByRole('button', { name: 'Attach' })).toBeFalsy();
|
|
@@ -218,6 +227,14 @@ describe('Message bar', () => {
|
|
|
218
227
|
render(_jsx(MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: { attach: { props: { 'aria-label': 'Test' } } } }));
|
|
219
228
|
yield userEvent.click(screen.getByRole('button', { name: 'Test' }));
|
|
220
229
|
}));
|
|
230
|
+
it('can change attach button icon', () => {
|
|
231
|
+
render(_jsx(MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: {
|
|
232
|
+
attach: {
|
|
233
|
+
icon: _jsx("img", { alt: "", src: "" })
|
|
234
|
+
}
|
|
235
|
+
} }));
|
|
236
|
+
expect(screen.getByRole('img')).toBeVisible();
|
|
237
|
+
});
|
|
221
238
|
// Stop button
|
|
222
239
|
// --------------------------------------------------------------------------
|
|
223
240
|
it('can show stop button', () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/chatbot",
|
|
3
|
-
"version": "6.5.0-prerelease.
|
|
3
|
+
"version": "6.5.0-prerelease.8",
|
|
4
4
|
"description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx
CHANGED
|
@@ -366,7 +366,9 @@ Setting up cluster console...`;
|
|
|
366
366
|
<FlexItem>{stage.name}</FlexItem>
|
|
367
367
|
</Flex>
|
|
368
368
|
</AccordionToggle>
|
|
369
|
-
<AccordionContent id={stage.id.replace('-toggle', '')}
|
|
369
|
+
<AccordionContent id={stage.id.replace('-toggle', '')} style={{ border: '0px' }}>
|
|
370
|
+
{renderCodeBlock(stage)}
|
|
371
|
+
</AccordionContent>
|
|
370
372
|
</AccordionItem>
|
|
371
373
|
))}
|
|
372
374
|
</Accordion>
|
|
@@ -21,7 +21,7 @@ export interface AttachMenuProps extends DropdownProps {
|
|
|
21
21
|
/** Items in menu */
|
|
22
22
|
filteredItems: React.ReactNode;
|
|
23
23
|
/** A callback for when the input value changes. */
|
|
24
|
-
handleTextInputChange
|
|
24
|
+
handleTextInputChange?: (value: string) => void;
|
|
25
25
|
/** Flag to indicate if menu is opened. */
|
|
26
26
|
isOpen: boolean;
|
|
27
27
|
/** Additional properties to pass to the Popper */
|
|
@@ -73,16 +73,18 @@ export const AttachMenu: FunctionComponent<AttachMenuProps> = ({
|
|
|
73
73
|
onSelect={onSelect}
|
|
74
74
|
{...props}
|
|
75
75
|
>
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
{handleTextInputChange && (
|
|
77
|
+
<MenuSearch {...menuSearchProps}>
|
|
78
|
+
<MenuSearchInput {...menuSearchInputProps}>
|
|
79
|
+
<SearchInput
|
|
80
|
+
aria-label={searchInputAriaLabel}
|
|
81
|
+
onChange={(_event, value) => handleTextInputChange(value)}
|
|
82
|
+
placeholder={searchInputPlaceholder}
|
|
83
|
+
{...searchInputProps}
|
|
84
|
+
/>
|
|
85
|
+
</MenuSearchInput>
|
|
86
|
+
</MenuSearch>
|
|
87
|
+
)}
|
|
86
88
|
{filteredItems}
|
|
87
89
|
</Dropdown>
|
|
88
90
|
);
|
|
@@ -173,4 +173,8 @@ describe('Attach button', () => {
|
|
|
173
173
|
expect(validator).toHaveBeenCalledWith(file);
|
|
174
174
|
expect(onAttachRejected).toHaveBeenCalled();
|
|
175
175
|
});
|
|
176
|
+
it('should handle icon prop', () => {
|
|
177
|
+
render(<AttachButton icon={<img alt="" src="" />} />);
|
|
178
|
+
expect(screen.getByRole('img')).toBeVisible();
|
|
179
|
+
});
|
|
176
180
|
});
|
|
@@ -51,6 +51,8 @@ export interface AttachButtonProps extends ButtonProps {
|
|
|
51
51
|
validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
|
|
52
52
|
/** Additional props passed to react-dropzone */
|
|
53
53
|
dropzoneProps?: DropzoneOptions;
|
|
54
|
+
/** Icon displayed in attach button */
|
|
55
|
+
icon?: React.ReactNode;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
const AttachButtonBase: FunctionComponent<AttachButtonProps> = ({
|
|
@@ -72,6 +74,7 @@ const AttachButtonBase: FunctionComponent<AttachButtonProps> = ({
|
|
|
72
74
|
onAttachRejected,
|
|
73
75
|
validator,
|
|
74
76
|
dropzoneProps,
|
|
77
|
+
icon = <PaperclipIcon />,
|
|
75
78
|
...props
|
|
76
79
|
}: AttachButtonProps) => {
|
|
77
80
|
const { open, getInputProps } = useDropzone({
|
|
@@ -113,7 +116,7 @@ const AttachButtonBase: FunctionComponent<AttachButtonProps> = ({
|
|
|
113
116
|
onClick={onClick ?? open}
|
|
114
117
|
icon={
|
|
115
118
|
<Icon iconSize={isCompact ? 'lg' : 'xl'} isInline>
|
|
116
|
-
|
|
119
|
+
{icon}
|
|
117
120
|
</Icon>
|
|
118
121
|
}
|
|
119
122
|
size={isCompact ? 'sm' : undefined}
|
|
@@ -275,6 +275,20 @@ describe('Message bar', () => {
|
|
|
275
275
|
);
|
|
276
276
|
expect(screen.getByTestId('menu-search-input')).toBeTruthy();
|
|
277
277
|
});
|
|
278
|
+
it('can remove input from attach menu', async () => {
|
|
279
|
+
render(
|
|
280
|
+
<MessageBar
|
|
281
|
+
onSendMessage={jest.fn}
|
|
282
|
+
attachMenuProps={{
|
|
283
|
+
isAttachMenuOpen: true,
|
|
284
|
+
setIsAttachMenuOpen: jest.fn(),
|
|
285
|
+
onAttachMenuToggleClick: jest.fn(),
|
|
286
|
+
attachMenuItems: ATTACH_MENU_ITEMS
|
|
287
|
+
}}
|
|
288
|
+
/>
|
|
289
|
+
);
|
|
290
|
+
expect(screen.queryByRole('textbox', { name: /Filter menu items/i })).not.toBeInTheDocument();
|
|
291
|
+
});
|
|
278
292
|
it('can hide attach button', () => {
|
|
279
293
|
render(<MessageBar onSendMessage={jest.fn} hasAttachButton={false} />);
|
|
280
294
|
expect(screen.queryByRole('button', { name: 'Attach' })).toBeFalsy();
|
|
@@ -325,6 +339,20 @@ describe('Message bar', () => {
|
|
|
325
339
|
);
|
|
326
340
|
await userEvent.click(screen.getByRole('button', { name: 'Test' }));
|
|
327
341
|
});
|
|
342
|
+
it('can change attach button icon', () => {
|
|
343
|
+
render(
|
|
344
|
+
<MessageBar
|
|
345
|
+
onSendMessage={jest.fn}
|
|
346
|
+
hasAttachButton
|
|
347
|
+
buttonProps={{
|
|
348
|
+
attach: {
|
|
349
|
+
icon: <img alt="" src="" />
|
|
350
|
+
}
|
|
351
|
+
}}
|
|
352
|
+
/>
|
|
353
|
+
);
|
|
354
|
+
expect(screen.getByRole('img')).toBeVisible();
|
|
355
|
+
});
|
|
328
356
|
|
|
329
357
|
// Stop button
|
|
330
358
|
// --------------------------------------------------------------------------
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
// Import Chatbot components
|
|
15
15
|
import SendButton from './SendButton';
|
|
16
16
|
import MicrophoneButton from './MicrophoneButton';
|
|
17
|
-
import { AttachButton } from './AttachButton';
|
|
17
|
+
import { AttachButton, AttachButtonProps } from './AttachButton';
|
|
18
18
|
import AttachMenu from '../AttachMenu';
|
|
19
19
|
import StopButton from './StopButton';
|
|
20
20
|
import { ChatbotDisplayMode } from '../Chatbot';
|
|
@@ -29,7 +29,7 @@ export interface MessageBarWithAttachMenuProps {
|
|
|
29
29
|
/** A callback for when the attachment menu toggle is clicked */
|
|
30
30
|
onAttachMenuToggleClick: () => void;
|
|
31
31
|
/** A callback for when the input value in the menu changes. */
|
|
32
|
-
onAttachMenuInputChange
|
|
32
|
+
onAttachMenuInputChange?: (value: string) => void;
|
|
33
33
|
/** Function callback called when user selects item in menu. */
|
|
34
34
|
onAttachMenuSelect?: (event?: React.MouseEvent<Element, MouseEvent>, value?: string | number) => void;
|
|
35
35
|
/** Placeholder for search input */
|
|
@@ -95,12 +95,7 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
|
|
|
95
95
|
isSendButtonDisabled?: boolean;
|
|
96
96
|
/** Prop to allow passage of additional props to buttons */
|
|
97
97
|
buttonProps?: {
|
|
98
|
-
attach?: {
|
|
99
|
-
tooltipContent?: string;
|
|
100
|
-
props?: ButtonProps;
|
|
101
|
-
inputTestId?: string;
|
|
102
|
-
tooltipProps?: Omit<TooltipProps, 'content'>;
|
|
103
|
-
};
|
|
98
|
+
attach?: AttachButtonProps & { props?: ButtonProps };
|
|
104
99
|
stop?: { tooltipContent?: string; props?: ButtonProps; tooltipProps?: Omit<TooltipProps, 'content'> };
|
|
105
100
|
send?: { tooltipContent?: string; props?: ButtonProps; tooltipProps?: Omit<TooltipProps, 'content'> };
|
|
106
101
|
microphone?: {
|
|
@@ -376,7 +371,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
376
371
|
onAttachRejected={onAttachRejected}
|
|
377
372
|
validator={validator}
|
|
378
373
|
dropzoneProps={dropzoneProps}
|
|
379
|
-
{...buttonProps?.attach
|
|
374
|
+
{...buttonProps?.attach}
|
|
380
375
|
/>
|
|
381
376
|
)}
|
|
382
377
|
{!attachMenuProps && hasAttachButton && (
|
|
@@ -396,6 +391,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
396
391
|
onAttachRejected={onAttachRejected}
|
|
397
392
|
validator={validator}
|
|
398
393
|
dropzoneProps={dropzoneProps}
|
|
394
|
+
{...buttonProps?.attach}
|
|
399
395
|
{...buttonProps?.attach?.props}
|
|
400
396
|
/>
|
|
401
397
|
)}
|