@patternfly/chatbot 6.3.0-prerelease.11 → 6.3.0-prerelease.12
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/ResponseActions/ResponseActionButton.d.ts +2 -2
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -1
- package/dist/cjs/ResponseActions/ResponseActions.js +6 -6
- package/dist/cjs/ResponseActions/ResponseActions.test.js +16 -1
- package/dist/esm/ResponseActions/ResponseActionButton.d.ts +2 -2
- package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -1
- package/dist/esm/ResponseActions/ResponseActions.js +6 -6
- package/dist/esm/ResponseActions/ResponseActions.test.js +16 -1
- package/package.json +1 -1
- package/src/ResponseActions/ResponseActionButton.tsx +2 -2
- package/src/ResponseActions/ResponseActions.test.tsx +18 -1
- package/src/ResponseActions/ResponseActions.tsx +10 -1
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { TooltipProps } from '@patternfly/react-core';
|
3
|
-
export interface ResponseActionButtonProps {
|
2
|
+
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
3
|
+
export interface ResponseActionButtonProps extends ButtonProps {
|
4
4
|
/** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
|
5
5
|
ariaLabel?: string;
|
6
6
|
/** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
|
@@ -26,9 +26,12 @@ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
26
26
|
/** Id for content controlled by the button, such as the feedback form */
|
27
27
|
'aria-controls'?: string;
|
28
28
|
}
|
29
|
+
type ExtendedActionProps = ActionProps & {
|
30
|
+
[key: string]: any;
|
31
|
+
};
|
29
32
|
export interface ResponseActionProps {
|
30
33
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
31
|
-
actions: Record<string,
|
34
|
+
actions: Record<string, ExtendedActionProps | undefined> & {
|
32
35
|
positive?: ActionProps;
|
33
36
|
negative?: ActionProps;
|
34
37
|
copy?: ActionProps;
|
@@ -39,14 +39,14 @@ const ResponseActions = ({ actions }) => {
|
|
39
39
|
onClick && onClick(e);
|
40
40
|
};
|
41
41
|
return (react_1.default.createElement("div", { ref: responseActions, className: "pf-chatbot__response-actions" },
|
42
|
-
positive && (react_1.default.createElement(ResponseActionButton_1.default, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] })),
|
43
|
-
negative && (react_1.default.createElement(ResponseActionButton_1.default, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] })),
|
44
|
-
copy && (react_1.default.createElement(ResponseActionButton_1.default, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] })),
|
45
|
-
share && (react_1.default.createElement(ResponseActionButton_1.default, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: react_1.default.createElement(react_icons_1.ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] })),
|
46
|
-
listen && (react_1.default.createElement(ResponseActionButton_1.default, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: react_1.default.createElement(react_icons_1.VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] })),
|
42
|
+
positive && (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, positive, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))),
|
43
|
+
negative && (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, negative, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))),
|
44
|
+
copy && (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, copy, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: react_1.default.createElement(react_icons_1.OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))),
|
45
|
+
share && (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, share, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: react_1.default.createElement(react_icons_1.ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))),
|
46
|
+
listen && (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, listen, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: react_1.default.createElement(react_icons_1.VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))),
|
47
47
|
Object.keys(additionalActions).map((action) => {
|
48
48
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
49
|
-
return (react_1.default.createElement(ResponseActionButton_1.default, { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] }));
|
49
|
+
return (react_1.default.createElement(ResponseActionButton_1.default, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] })));
|
50
50
|
})));
|
51
51
|
};
|
52
52
|
exports.ResponseActions = ResponseActions;
|
@@ -52,6 +52,13 @@ const CUSTOM_ACTIONS = [
|
|
52
52
|
}
|
53
53
|
}
|
54
54
|
];
|
55
|
+
const ALL_ACTIONS_DATA_TEST = [
|
56
|
+
{ type: 'positive', label: 'Good response', dataTestId: 'positive' },
|
57
|
+
{ type: 'negative', label: 'Bad response', dataTestId: 'negative' },
|
58
|
+
{ type: 'copy', label: 'Copy', dataTestId: 'copy' },
|
59
|
+
{ type: 'share', label: 'Share', dataTestId: 'share' },
|
60
|
+
{ type: 'listen', label: 'Listen', dataTestId: 'listen' }
|
61
|
+
];
|
55
62
|
describe('ResponseActions', () => {
|
56
63
|
afterEach(() => {
|
57
64
|
jest.clearAllMocks();
|
@@ -161,6 +168,12 @@ describe('ResponseActions', () => {
|
|
161
168
|
expect(react_2.screen.getByRole('button', { name: label })).toHaveClass('test');
|
162
169
|
});
|
163
170
|
});
|
171
|
+
it('should be able to add custom attributes to buttons', () => {
|
172
|
+
ALL_ACTIONS_DATA_TEST.forEach(({ type, dataTestId }) => {
|
173
|
+
(0, react_2.render)(react_1.default.createElement(ResponseActions_1.default, { actions: { [type]: { onClick: jest.fn(), 'data-testid': dataTestId } } }));
|
174
|
+
expect(react_2.screen.getByTestId(dataTestId)).toBeTruthy();
|
175
|
+
});
|
176
|
+
});
|
164
177
|
it('should be able to add custom actions', () => {
|
165
178
|
CUSTOM_ACTIONS.forEach((action) => {
|
166
179
|
const key = Object.keys(action)[0];
|
@@ -170,10 +183,12 @@ describe('ResponseActions', () => {
|
|
170
183
|
onClick: action[key].onClick,
|
171
184
|
// doing this just because it's easier to test without a regex for the button name
|
172
185
|
ariaLabel: action[key].ariaLabel.toLowerCase(),
|
173
|
-
icon: action[key].icon
|
186
|
+
icon: action[key].icon,
|
187
|
+
'data-testid': action[key]
|
174
188
|
}
|
175
189
|
} }));
|
176
190
|
expect(react_2.screen.getByRole('button', { name: key })).toBeTruthy();
|
191
|
+
expect(react_2.screen.getByTestId(action[key])).toBeTruthy();
|
177
192
|
});
|
178
193
|
});
|
179
194
|
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { TooltipProps } from '@patternfly/react-core';
|
3
|
-
export interface ResponseActionButtonProps {
|
2
|
+
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
3
|
+
export interface ResponseActionButtonProps extends ButtonProps {
|
4
4
|
/** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
|
5
5
|
ariaLabel?: string;
|
6
6
|
/** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
|
@@ -26,9 +26,12 @@ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
26
26
|
/** Id for content controlled by the button, such as the feedback form */
|
27
27
|
'aria-controls'?: string;
|
28
28
|
}
|
29
|
+
type ExtendedActionProps = ActionProps & {
|
30
|
+
[key: string]: any;
|
31
|
+
};
|
29
32
|
export interface ResponseActionProps {
|
30
33
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
31
|
-
actions: Record<string,
|
34
|
+
actions: Record<string, ExtendedActionProps | undefined> & {
|
32
35
|
positive?: ActionProps;
|
33
36
|
negative?: ActionProps;
|
34
37
|
copy?: ActionProps;
|
@@ -33,14 +33,14 @@ export const ResponseActions = ({ actions }) => {
|
|
33
33
|
onClick && onClick(e);
|
34
34
|
};
|
35
35
|
return (React.createElement("div", { ref: responseActions, className: "pf-chatbot__response-actions" },
|
36
|
-
positive && (React.createElement(ResponseActionButton, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] })),
|
37
|
-
negative && (React.createElement(ResponseActionButton, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] })),
|
38
|
-
copy && (React.createElement(ResponseActionButton, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] })),
|
39
|
-
share && (React.createElement(ResponseActionButton, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] })),
|
40
|
-
listen && (React.createElement(ResponseActionButton, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] })),
|
36
|
+
positive && (React.createElement(ResponseActionButton, Object.assign({}, positive, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', clickedAriaLabel: (_b = positive.ariaLabel) !== null && _b !== void 0 ? _b : 'Response recorded', onClick: (e) => handleClick(e, 'positive', positive.onClick), className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_c = positive.tooltipContent) !== null && _c !== void 0 ? _c : 'Good response', clickedTooltipContent: (_d = positive.clickedTooltipContent) !== null && _d !== void 0 ? _d : 'Response recorded', tooltipProps: positive.tooltipProps, icon: React.createElement(OutlinedThumbsUpIcon, null), isClicked: activeButton === 'positive', ref: positive.ref, "aria-expanded": positive['aria-expanded'], "aria-controls": positive['aria-controls'] }))),
|
37
|
+
negative && (React.createElement(ResponseActionButton, Object.assign({}, negative, { ariaLabel: (_e = negative.ariaLabel) !== null && _e !== void 0 ? _e : 'Bad response', clickedAriaLabel: (_f = negative.ariaLabel) !== null && _f !== void 0 ? _f : 'Response recorded', onClick: (e) => handleClick(e, 'negative', negative.onClick), className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_g = negative.tooltipContent) !== null && _g !== void 0 ? _g : 'Bad response', clickedTooltipContent: (_h = negative.clickedTooltipContent) !== null && _h !== void 0 ? _h : 'Response recorded', tooltipProps: negative.tooltipProps, icon: React.createElement(OutlinedThumbsDownIcon, null), isClicked: activeButton === 'negative', ref: negative.ref, "aria-expanded": negative['aria-expanded'], "aria-controls": negative['aria-controls'] }))),
|
38
|
+
copy && (React.createElement(ResponseActionButton, Object.assign({}, copy, { ariaLabel: (_j = copy.ariaLabel) !== null && _j !== void 0 ? _j : 'Copy', clickedAriaLabel: (_k = copy.ariaLabel) !== null && _k !== void 0 ? _k : 'Copied', onClick: (e) => handleClick(e, 'copy', copy.onClick), className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_l = copy.tooltipContent) !== null && _l !== void 0 ? _l : 'Copy', clickedTooltipContent: (_m = copy.clickedTooltipContent) !== null && _m !== void 0 ? _m : 'Copied', tooltipProps: copy.tooltipProps, icon: React.createElement(OutlinedCopyIcon, null), isClicked: activeButton === 'copy', ref: copy.ref, "aria-expanded": copy['aria-expanded'], "aria-controls": copy['aria-controls'] }))),
|
39
|
+
share && (React.createElement(ResponseActionButton, Object.assign({}, share, { ariaLabel: (_o = share.ariaLabel) !== null && _o !== void 0 ? _o : 'Share', clickedAriaLabel: (_p = share.ariaLabel) !== null && _p !== void 0 ? _p : 'Shared', onClick: (e) => handleClick(e, 'share', share.onClick), className: share.className, isDisabled: share.isDisabled, tooltipContent: (_q = share.tooltipContent) !== null && _q !== void 0 ? _q : 'Share', clickedTooltipContent: (_r = share.clickedTooltipContent) !== null && _r !== void 0 ? _r : 'Shared', tooltipProps: share.tooltipProps, icon: React.createElement(ExternalLinkAltIcon, null), isClicked: activeButton === 'share', ref: share.ref, "aria-expanded": share['aria-expanded'], "aria-controls": share['aria-controls'] }))),
|
40
|
+
listen && (React.createElement(ResponseActionButton, Object.assign({}, listen, { ariaLabel: (_s = listen.ariaLabel) !== null && _s !== void 0 ? _s : 'Listen', clickedAriaLabel: (_t = listen.ariaLabel) !== null && _t !== void 0 ? _t : 'Listening', onClick: (e) => handleClick(e, 'listen', listen.onClick), className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_u = listen.tooltipContent) !== null && _u !== void 0 ? _u : 'Listen', clickedTooltipContent: (_v = listen.clickedTooltipContent) !== null && _v !== void 0 ? _v : 'Listening', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null), isClicked: activeButton === 'listen', ref: listen.ref, "aria-expanded": listen['aria-expanded'], "aria-controls": listen['aria-controls'] }))),
|
41
41
|
Object.keys(additionalActions).map((action) => {
|
42
42
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
43
|
-
return (React.createElement(ResponseActionButton, { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] }));
|
43
|
+
return (React.createElement(ResponseActionButton, Object.assign({}, additionalActions[action], { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, clickedAriaLabel: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.clickedAriaLabel, onClick: (e) => { var _a; return handleClick(e, action, (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.onClick); }, className: (_c = additionalActions[action]) === null || _c === void 0 ? void 0 : _c.className, isDisabled: (_d = additionalActions[action]) === null || _d === void 0 ? void 0 : _d.isDisabled, tooltipContent: (_e = additionalActions[action]) === null || _e === void 0 ? void 0 : _e.tooltipContent, tooltipProps: (_f = additionalActions[action]) === null || _f === void 0 ? void 0 : _f.tooltipProps, clickedTooltipContent: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.clickedTooltipContent, icon: (_h = additionalActions[action]) === null || _h === void 0 ? void 0 : _h.icon, isClicked: activeButton === action, ref: (_j = additionalActions[action]) === null || _j === void 0 ? void 0 : _j.ref, "aria-expanded": (_k = additionalActions[action]) === null || _k === void 0 ? void 0 : _k['aria-expanded'], "aria-controls": (_l = additionalActions[action]) === null || _l === void 0 ? void 0 : _l['aria-controls'] })));
|
44
44
|
})));
|
45
45
|
};
|
46
46
|
export default ResponseActions;
|
@@ -47,6 +47,13 @@ const CUSTOM_ACTIONS = [
|
|
47
47
|
}
|
48
48
|
}
|
49
49
|
];
|
50
|
+
const ALL_ACTIONS_DATA_TEST = [
|
51
|
+
{ type: 'positive', label: 'Good response', dataTestId: 'positive' },
|
52
|
+
{ type: 'negative', label: 'Bad response', dataTestId: 'negative' },
|
53
|
+
{ type: 'copy', label: 'Copy', dataTestId: 'copy' },
|
54
|
+
{ type: 'share', label: 'Share', dataTestId: 'share' },
|
55
|
+
{ type: 'listen', label: 'Listen', dataTestId: 'listen' }
|
56
|
+
];
|
50
57
|
describe('ResponseActions', () => {
|
51
58
|
afterEach(() => {
|
52
59
|
jest.clearAllMocks();
|
@@ -156,6 +163,12 @@ describe('ResponseActions', () => {
|
|
156
163
|
expect(screen.getByRole('button', { name: label })).toHaveClass('test');
|
157
164
|
});
|
158
165
|
});
|
166
|
+
it('should be able to add custom attributes to buttons', () => {
|
167
|
+
ALL_ACTIONS_DATA_TEST.forEach(({ type, dataTestId }) => {
|
168
|
+
render(React.createElement(ResponseActions, { actions: { [type]: { onClick: jest.fn(), 'data-testid': dataTestId } } }));
|
169
|
+
expect(screen.getByTestId(dataTestId)).toBeTruthy();
|
170
|
+
});
|
171
|
+
});
|
159
172
|
it('should be able to add custom actions', () => {
|
160
173
|
CUSTOM_ACTIONS.forEach((action) => {
|
161
174
|
const key = Object.keys(action)[0];
|
@@ -165,10 +178,12 @@ describe('ResponseActions', () => {
|
|
165
178
|
onClick: action[key].onClick,
|
166
179
|
// doing this just because it's easier to test without a regex for the button name
|
167
180
|
ariaLabel: action[key].ariaLabel.toLowerCase(),
|
168
|
-
icon: action[key].icon
|
181
|
+
icon: action[key].icon,
|
182
|
+
'data-testid': action[key]
|
169
183
|
}
|
170
184
|
} }));
|
171
185
|
expect(screen.getByRole('button', { name: key })).toBeTruthy();
|
186
|
+
expect(screen.getByTestId(action[key])).toBeTruthy();
|
172
187
|
});
|
173
188
|
});
|
174
189
|
});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@patternfly/chatbot",
|
3
|
-
"version": "6.3.0-prerelease.
|
3
|
+
"version": "6.3.0-prerelease.12",
|
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",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { Button, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
|
2
|
+
import { Button, ButtonProps, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
|
3
3
|
|
4
|
-
export interface ResponseActionButtonProps {
|
4
|
+
export interface ResponseActionButtonProps extends ButtonProps {
|
5
5
|
/** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
|
6
6
|
ariaLabel?: string;
|
7
7
|
/** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
|
@@ -41,6 +41,14 @@ const CUSTOM_ACTIONS = [
|
|
41
41
|
}
|
42
42
|
];
|
43
43
|
|
44
|
+
const ALL_ACTIONS_DATA_TEST = [
|
45
|
+
{ type: 'positive', label: 'Good response', dataTestId: 'positive' },
|
46
|
+
{ type: 'negative', label: 'Bad response', dataTestId: 'negative' },
|
47
|
+
{ type: 'copy', label: 'Copy', dataTestId: 'copy' },
|
48
|
+
{ type: 'share', label: 'Share', dataTestId: 'share' },
|
49
|
+
{ type: 'listen', label: 'Listen', dataTestId: 'listen' }
|
50
|
+
];
|
51
|
+
|
44
52
|
describe('ResponseActions', () => {
|
45
53
|
afterEach(() => {
|
46
54
|
jest.clearAllMocks();
|
@@ -181,6 +189,13 @@ describe('ResponseActions', () => {
|
|
181
189
|
});
|
182
190
|
});
|
183
191
|
|
192
|
+
it('should be able to add custom attributes to buttons', () => {
|
193
|
+
ALL_ACTIONS_DATA_TEST.forEach(({ type, dataTestId }) => {
|
194
|
+
render(<ResponseActions actions={{ [type]: { onClick: jest.fn(), 'data-testid': dataTestId } }} />);
|
195
|
+
expect(screen.getByTestId(dataTestId)).toBeTruthy();
|
196
|
+
});
|
197
|
+
});
|
198
|
+
|
184
199
|
it('should be able to add custom actions', () => {
|
185
200
|
CUSTOM_ACTIONS.forEach((action) => {
|
186
201
|
const key = Object.keys(action)[0];
|
@@ -192,12 +207,14 @@ describe('ResponseActions', () => {
|
|
192
207
|
onClick: action[key].onClick,
|
193
208
|
// doing this just because it's easier to test without a regex for the button name
|
194
209
|
ariaLabel: action[key].ariaLabel.toLowerCase(),
|
195
|
-
icon: action[key].icon
|
210
|
+
icon: action[key].icon,
|
211
|
+
'data-testid': action[key]
|
196
212
|
}
|
197
213
|
}}
|
198
214
|
/>
|
199
215
|
);
|
200
216
|
expect(screen.getByRole('button', { name: key })).toBeTruthy();
|
217
|
+
expect(screen.getByTestId(action[key])).toBeTruthy();
|
201
218
|
});
|
202
219
|
});
|
203
220
|
});
|
@@ -36,9 +36,12 @@ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
36
36
|
'aria-controls'?: string;
|
37
37
|
}
|
38
38
|
|
39
|
+
type ExtendedActionProps = ActionProps & {
|
40
|
+
[key: string]: any;
|
41
|
+
};
|
39
42
|
export interface ResponseActionProps {
|
40
43
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
41
|
-
actions: Record<string,
|
44
|
+
actions: Record<string, ExtendedActionProps | undefined> & {
|
42
45
|
positive?: ActionProps;
|
43
46
|
negative?: ActionProps;
|
44
47
|
copy?: ActionProps;
|
@@ -78,6 +81,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
78
81
|
<div ref={responseActions} className="pf-chatbot__response-actions">
|
79
82
|
{positive && (
|
80
83
|
<ResponseActionButton
|
84
|
+
{...positive}
|
81
85
|
ariaLabel={positive.ariaLabel ?? 'Good response'}
|
82
86
|
clickedAriaLabel={positive.ariaLabel ?? 'Response recorded'}
|
83
87
|
onClick={(e) => handleClick(e, 'positive', positive.onClick)}
|
@@ -95,6 +99,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
95
99
|
)}
|
96
100
|
{negative && (
|
97
101
|
<ResponseActionButton
|
102
|
+
{...negative}
|
98
103
|
ariaLabel={negative.ariaLabel ?? 'Bad response'}
|
99
104
|
clickedAriaLabel={negative.ariaLabel ?? 'Response recorded'}
|
100
105
|
onClick={(e) => handleClick(e, 'negative', negative.onClick)}
|
@@ -112,6 +117,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
112
117
|
)}
|
113
118
|
{copy && (
|
114
119
|
<ResponseActionButton
|
120
|
+
{...copy}
|
115
121
|
ariaLabel={copy.ariaLabel ?? 'Copy'}
|
116
122
|
clickedAriaLabel={copy.ariaLabel ?? 'Copied'}
|
117
123
|
onClick={(e) => handleClick(e, 'copy', copy.onClick)}
|
@@ -129,6 +135,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
129
135
|
)}
|
130
136
|
{share && (
|
131
137
|
<ResponseActionButton
|
138
|
+
{...share}
|
132
139
|
ariaLabel={share.ariaLabel ?? 'Share'}
|
133
140
|
clickedAriaLabel={share.ariaLabel ?? 'Shared'}
|
134
141
|
onClick={(e) => handleClick(e, 'share', share.onClick)}
|
@@ -146,6 +153,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
146
153
|
)}
|
147
154
|
{listen && (
|
148
155
|
<ResponseActionButton
|
156
|
+
{...listen}
|
149
157
|
ariaLabel={listen.ariaLabel ?? 'Listen'}
|
150
158
|
clickedAriaLabel={listen.ariaLabel ?? 'Listening'}
|
151
159
|
onClick={(e) => handleClick(e, 'listen', listen.onClick)}
|
@@ -163,6 +171,7 @@ export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({
|
|
163
171
|
)}
|
164
172
|
{Object.keys(additionalActions).map((action) => (
|
165
173
|
<ResponseActionButton
|
174
|
+
{...additionalActions[action]}
|
166
175
|
key={action}
|
167
176
|
ariaLabel={additionalActions[action]?.ariaLabel}
|
168
177
|
clickedAriaLabel={additionalActions[action]?.clickedAriaLabel}
|