@patternfly/chatbot 2.1.0 → 2.2.0-prerelease.10

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.
Files changed (177) hide show
  1. package/dist/cjs/Chatbot/Chatbot.js +0 -9
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  5. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  6. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
  7. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  8. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  9. package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
  10. package/dist/cjs/ChatbotHeader/index.js +1 -0
  11. package/dist/cjs/CodeModal/CodeModal.js +2 -12
  12. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  13. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
  14. package/dist/cjs/Message/Message.d.ts +16 -6
  15. package/dist/cjs/Message/Message.js +6 -6
  16. package/dist/cjs/Message/Message.test.js +51 -0
  17. package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +15 -0
  18. package/dist/cjs/Message/QuickResponse/QuickResponse.js +33 -0
  19. package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
  20. package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
  21. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  22. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
  23. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  24. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
  25. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  26. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
  27. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  28. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
  29. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  30. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
  31. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  32. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
  33. package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
  34. package/dist/cjs/Message/QuickStarts/types.js +17 -0
  35. package/dist/cjs/MessageBar/SendButton.js +1 -1
  36. package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
  37. package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
  38. package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  39. package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
  40. package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
  41. package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
  42. package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
  43. package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
  44. package/dist/cjs/Settings/SettingsForm.js +27 -0
  45. package/dist/cjs/Settings/index.d.ts +2 -0
  46. package/dist/cjs/Settings/index.js +23 -0
  47. package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +34 -0
  48. package/dist/cjs/TermsOfUse/TermsOfUse.js +49 -0
  49. package/dist/cjs/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  50. package/dist/cjs/TermsOfUse/TermsOfUse.test.js +79 -0
  51. package/dist/cjs/TermsOfUse/index.d.ts +2 -0
  52. package/dist/cjs/TermsOfUse/index.js +23 -0
  53. package/dist/cjs/index.d.ts +4 -0
  54. package/dist/cjs/index.js +7 -1
  55. package/dist/css/main.css +191 -30
  56. package/dist/css/main.css.map +1 -1
  57. package/dist/dynamic/Settings/package.json +1 -0
  58. package/dist/dynamic/TermsOfUse/package.json +1 -0
  59. package/dist/esm/Chatbot/Chatbot.js +0 -9
  60. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  61. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  62. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  63. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  64. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
  65. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  66. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  67. package/dist/esm/ChatbotHeader/index.d.ts +1 -0
  68. package/dist/esm/ChatbotHeader/index.js +1 -0
  69. package/dist/esm/CodeModal/CodeModal.js +2 -12
  70. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  71. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
  72. package/dist/esm/Message/Message.d.ts +16 -6
  73. package/dist/esm/Message/Message.js +7 -7
  74. package/dist/esm/Message/Message.test.js +51 -0
  75. package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +15 -0
  76. package/dist/esm/Message/QuickResponse/QuickResponse.js +26 -0
  77. package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
  78. package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
  79. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  80. package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
  81. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  82. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
  83. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  84. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
  85. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  86. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
  87. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  88. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
  89. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  90. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
  91. package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
  92. package/dist/esm/Message/QuickStarts/types.js +14 -0
  93. package/dist/esm/MessageBar/SendButton.js +1 -1
  94. package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
  95. package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
  96. package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  97. package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
  98. package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
  99. package/dist/esm/ResponseActions/ResponseActions.js +26 -9
  100. package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
  101. package/dist/esm/Settings/SettingsForm.d.ts +13 -0
  102. package/dist/esm/Settings/SettingsForm.js +20 -0
  103. package/dist/esm/Settings/index.d.ts +2 -0
  104. package/dist/esm/Settings/index.js +2 -0
  105. package/dist/esm/TermsOfUse/TermsOfUse.d.ts +34 -0
  106. package/dist/esm/TermsOfUse/TermsOfUse.js +42 -0
  107. package/dist/esm/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  108. package/dist/esm/TermsOfUse/TermsOfUse.test.js +74 -0
  109. package/dist/esm/TermsOfUse/index.d.ts +2 -0
  110. package/dist/esm/TermsOfUse/index.js +2 -0
  111. package/dist/esm/index.d.ts +4 -0
  112. package/dist/esm/index.js +4 -0
  113. package/dist/tsconfig.tsbuildinfo +1 -1
  114. package/package.json +7 -13
  115. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
  116. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
  117. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +26 -4
  118. package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
  119. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
  120. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +2 -2
  121. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +2 -2
  122. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerNavigation.tsx +67 -0
  123. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +78 -0
  124. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarDisabled.tsx +26 -0
  125. package/patternfly-docs/content/extensions/chatbot/examples/UI/PF-TermsAndConditionsHeader.svg +148 -0
  126. package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
  127. package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
  128. package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUse.tsx +147 -0
  129. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +56 -0
  130. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +2 -2
  131. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +2 -2
  132. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +20 -19
  133. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
  134. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +2 -2
  135. package/src/Chatbot/Chatbot.scss +0 -10
  136. package/src/Chatbot/Chatbot.tsx +0 -9
  137. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
  138. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +3 -3
  139. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +11 -3
  140. package/src/ChatbotFooter/ChatbotFooter.scss +2 -1
  141. package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
  142. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
  143. package/src/ChatbotHeader/index.ts +1 -0
  144. package/src/CodeModal/CodeModal.scss +8 -0
  145. package/src/CodeModal/CodeModal.tsx +2 -13
  146. package/src/FileDropZone/__snapshots__/FileDropZone.test.tsx.snap +1 -1
  147. package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
  148. package/src/Message/Message.scss +0 -14
  149. package/src/Message/Message.test.tsx +76 -0
  150. package/src/Message/Message.tsx +35 -26
  151. package/src/Message/QuickResponse/QuickResponse.scss +33 -0
  152. package/src/Message/QuickResponse/QuickResponse.tsx +50 -0
  153. package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
  154. package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
  155. package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
  156. package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
  157. package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
  158. package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
  159. package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
  160. package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
  161. package/src/Message/QuickStarts/types.ts +154 -0
  162. package/src/MessageBar/SendButton.scss +24 -0
  163. package/src/MessageBar/SendButton.tsx +1 -1
  164. package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
  165. package/src/ResponseActions/ResponseActionButton.tsx +46 -27
  166. package/src/ResponseActions/ResponseActions.scss +10 -8
  167. package/src/ResponseActions/ResponseActions.test.tsx +103 -5
  168. package/src/ResponseActions/ResponseActions.tsx +54 -7
  169. package/src/Settings/Settings.scss +34 -0
  170. package/src/Settings/SettingsForm.tsx +25 -0
  171. package/src/Settings/index.ts +3 -0
  172. package/src/TermsOfUse/TermsOfUse.scss +66 -0
  173. package/src/TermsOfUse/TermsOfUse.test.tsx +138 -0
  174. package/src/TermsOfUse/TermsOfUse.tsx +117 -0
  175. package/src/TermsOfUse/index.ts +3 -0
  176. package/src/index.ts +6 -0
  177. package/src/main.scss +7 -3
@@ -0,0 +1,132 @@
1
+ import { ButtonProps } from '@patternfly/react-core';
2
+ export interface AccessReviewResourceAttributes {
3
+ group?: string;
4
+ resource?: string;
5
+ subresource?: string;
6
+ verb?: K8sVerb;
7
+ name?: string;
8
+ namespace?: string;
9
+ }
10
+ export type K8sVerb = 'create' | 'get' | 'list' | 'update' | 'patch' | 'delete' | 'deletecollection' | 'watch';
11
+ export interface QuickStart {
12
+ apiVersion?: string;
13
+ kind?: string;
14
+ metadata: ObjectMetadata;
15
+ spec: QuickStartSpec;
16
+ }
17
+ export interface ObjectMetadata {
18
+ name: string;
19
+ annotations?: {
20
+ [key: string]: string;
21
+ };
22
+ clusterName?: string;
23
+ creationTimestamp?: string;
24
+ deletionGracePeriodSeconds?: number;
25
+ deletionTimestamp?: string;
26
+ finalizers?: string[];
27
+ generateName?: string;
28
+ generation?: number;
29
+ labels?: {
30
+ [key: string]: string;
31
+ };
32
+ managedFields?: any[];
33
+ namespace?: string;
34
+ ownerReferences?: OwnerReference[];
35
+ resourceVersion?: string;
36
+ uid?: string;
37
+ language?: string;
38
+ country?: string;
39
+ locale?: string;
40
+ [key: string]: any;
41
+ }
42
+ export interface OwnerReference {
43
+ name: string;
44
+ kind: string;
45
+ uid: string;
46
+ apiVersion: string;
47
+ controller?: boolean;
48
+ blockOwnerDeletion?: boolean;
49
+ }
50
+ export interface QuickStartTask {
51
+ title?: string;
52
+ description?: string;
53
+ review?: QuickStartTaskReview;
54
+ summary?: QuickStartTaskSummary;
55
+ proc?: string;
56
+ }
57
+ export interface QuickStartTaskReview {
58
+ instructions?: string;
59
+ failedTaskHelp?: string;
60
+ }
61
+ export interface QuickStartTaskSummary {
62
+ success?: string;
63
+ failed?: string;
64
+ }
65
+ export interface QuickstartAction {
66
+ /** Screen reader aria label. */
67
+ 'aria-label': string;
68
+ /** Icon to be rendered as a plain button, by default Bookmark outlined will be used. */
69
+ icon?: React.ComponentType<unknown>;
70
+ /** Callback with synthetic event parameter. */
71
+ onClick?: (e: React.SyntheticEvent) => void;
72
+ /** Additional button props to be rendered as extra props. */
73
+ buttonProps?: ButtonProps;
74
+ }
75
+ export interface QuickStart {
76
+ apiVersion?: string;
77
+ kind?: string;
78
+ metadata: ObjectMetadata;
79
+ spec: QuickStartSpec;
80
+ }
81
+ export interface QuickStartSpec {
82
+ version?: number;
83
+ displayName: string;
84
+ durationMinutes?: number;
85
+ icon: React.ReactNode;
86
+ description: string;
87
+ prerequisites?: string[];
88
+ introduction?: string;
89
+ tasks?: QuickStartTask[];
90
+ conclusion?: string;
91
+ nextQuickStart?: string[];
92
+ accessReviewResources?: AccessReviewResourceAttributes[];
93
+ link?: QuickStartExternal;
94
+ type?: QuickStartType;
95
+ }
96
+ export interface QuickStartTask {
97
+ title?: string;
98
+ description?: string;
99
+ review?: QuickStartTaskReview;
100
+ summary?: QuickStartTaskSummary;
101
+ proc?: string;
102
+ }
103
+ export interface QuickStartTaskReview {
104
+ instructions?: string;
105
+ failedTaskHelp?: string;
106
+ }
107
+ export interface QuickStartTaskSummary {
108
+ success?: string;
109
+ failed?: string;
110
+ }
111
+ export type AllQuickStartStates = Record<string, QuickStartState>;
112
+ export type QuickStartState = Record<string, string | number | QuickStartStatus>;
113
+ export declare enum QuickStartStatus {
114
+ COMPLETE = "Complete",
115
+ IN_PROGRESS = "In Progress",
116
+ NOT_STARTED = "Not started"
117
+ }
118
+ export declare enum QuickStartTaskStatus {
119
+ INIT = "Initial",
120
+ VISITED = "Visited",
121
+ REVIEW = "Review",
122
+ SUCCESS = "Success",
123
+ FAILED = "Failed"
124
+ }
125
+ export interface QuickStartExternal {
126
+ href: string;
127
+ text?: string;
128
+ }
129
+ export interface QuickStartType {
130
+ text: string;
131
+ color?: 'green' | 'purple' | 'grey' | 'blue' | 'orange' | 'red' | 'teal' | 'orangered' | 'yellow';
132
+ }
@@ -0,0 +1,14 @@
1
+ export var QuickStartStatus;
2
+ (function (QuickStartStatus) {
3
+ QuickStartStatus["COMPLETE"] = "Complete";
4
+ QuickStartStatus["IN_PROGRESS"] = "In Progress";
5
+ QuickStartStatus["NOT_STARTED"] = "Not started";
6
+ })(QuickStartStatus || (QuickStartStatus = {}));
7
+ export var QuickStartTaskStatus;
8
+ (function (QuickStartTaskStatus) {
9
+ QuickStartTaskStatus["INIT"] = "Initial";
10
+ QuickStartTaskStatus["VISITED"] = "Visited";
11
+ QuickStartTaskStatus["REVIEW"] = "Review";
12
+ QuickStartTaskStatus["SUCCESS"] = "Success";
13
+ QuickStartTaskStatus["FAILED"] = "Failed";
14
+ })(QuickStartTaskStatus || (QuickStartTaskStatus = {}));
@@ -19,7 +19,7 @@ import { PaperPlaneIcon } from '@patternfly/react-icons/dist/esm/icons/paper-pla
19
19
  export const SendButton = (_a) => {
20
20
  var { className, onClick, tooltipProps, tooltipContent = 'Send' } = _a, props = __rest(_a, ["className", "onClick", "tooltipProps", "tooltipContent"]);
21
21
  return (React.createElement(Tooltip, Object.assign({ id: "pf-chatbot__tooltip--send", content: tooltipContent, position: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.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 }, tooltipProps),
22
- React.createElement(Button, Object.assign({ className: `pf-chatbot__button--send ${className !== null && className !== void 0 ? className : ''}`, variant: "link", "aria-label": props['aria-label'] || 'Send button', onClick: onClick, icon: React.createElement(Icon, { iconSize: "xl", isInline: true },
22
+ React.createElement(Button, Object.assign({ variant: "plain", className: `pf-chatbot__button--send ${className !== null && className !== void 0 ? className : ''}`, "aria-label": props['aria-label'] || 'Send button', onClick: onClick, icon: React.createElement(Icon, { iconSize: "xl", isInline: true },
23
23
  React.createElement(PaperPlaneIcon, null)) }, props))));
24
24
  };
25
25
  export default SendButton;
@@ -3,6 +3,8 @@ import { TooltipProps } from '@patternfly/react-core';
3
3
  export interface ResponseActionButtonProps {
4
4
  /** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
5
5
  ariaLabel?: string;
6
+ /** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
7
+ clickedAriaLabel?: string;
6
8
  /** Icon for the button */
7
9
  icon: React.ReactNode;
8
10
  /** On-click handler for the button */
@@ -13,8 +15,12 @@ export interface ResponseActionButtonProps {
13
15
  isDisabled?: boolean;
14
16
  /** Content shown in the tooltip */
15
17
  tooltipContent?: string;
18
+ /** Content shown in the tooltip when the button is clicked. Defaults to the value of tooltipContent if not provided. */
19
+ clickedTooltipContent?: string;
16
20
  /** Props to control the PF Tooltip component */
17
21
  tooltipProps?: TooltipProps;
22
+ /** Whether button is in clicked state */
23
+ isClicked?: boolean;
18
24
  }
19
25
  export declare const ResponseActionButton: React.FunctionComponent<ResponseActionButtonProps>;
20
26
  export default ResponseActionButton;
@@ -1,5 +1,13 @@
1
1
  import React from 'react';
2
2
  import { Button, Icon, Tooltip } from '@patternfly/react-core';
3
- export const ResponseActionButton = ({ ariaLabel, className, icon, isDisabled, onClick, tooltipContent, tooltipProps }) => (React.createElement(Tooltip, Object.assign({ id: `pf-chatbot__tooltip-response-action-${tooltipContent}`, content: tooltipContent, position: "bottom", 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 }, tooltipProps),
4
- React.createElement(Button, { variant: "plain", className: `pf-chatbot__button--response-action ${className !== null && className !== void 0 ? className : ''}`, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : tooltipContent, icon: React.createElement(Icon, { isInline: true, size: "lg" }, icon), isDisabled: isDisabled, onClick: onClick, size: "sm" })));
3
+ export const ResponseActionButton = ({ ariaLabel, clickedAriaLabel = ariaLabel, className, icon, isDisabled, onClick, tooltipContent, clickedTooltipContent = tooltipContent, tooltipProps, isClicked = false }) => {
4
+ const generateAriaLabel = () => {
5
+ if (ariaLabel) {
6
+ return isClicked ? clickedAriaLabel : ariaLabel;
7
+ }
8
+ return isClicked ? clickedTooltipContent : tooltipContent;
9
+ };
10
+ return (React.createElement(Tooltip, Object.assign({ id: `pf-chatbot__tooltip-response-action-${tooltipContent}`, content: isClicked ? clickedTooltipContent : tooltipContent, "aria-live": "polite", position: "bottom", 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 }, tooltipProps),
11
+ React.createElement(Button, { variant: "plain", className: `pf-chatbot__button--response-action ${isClicked ? 'pf-chatbot__button--response-action-clicked' : ''} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": generateAriaLabel(), icon: React.createElement(Icon, { isInline: true, size: "lg" }, icon), isDisabled: isDisabled, onClick: onClick, size: "sm" })));
12
+ };
5
13
  export default ResponseActionButton;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,49 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from 'react';
11
+ import { render, screen } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import userEvent from '@testing-library/user-event';
14
+ import { DownloadIcon } from '@patternfly/react-icons';
15
+ import ResponseActionButton from './ResponseActionButton';
16
+ describe('ResponseActionButton', () => {
17
+ it('renders aria-label correctly if not clicked', () => {
18
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), ariaLabel: "Download", clickedAriaLabel: "Downloaded" }));
19
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
20
+ });
21
+ it('renders aria-label correctly if clicked', () => {
22
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), ariaLabel: "Download", clickedAriaLabel: "Downloaded", isClicked: true }));
23
+ expect(screen.getByRole('button', { name: 'Downloaded' })).toBeTruthy();
24
+ });
25
+ it('renders tooltip correctly if not clicked', () => __awaiter(void 0, void 0, void 0, function* () {
26
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), tooltipContent: "Download", clickedTooltipContent: "Downloaded" }));
27
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
28
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
29
+ yield userEvent.click(screen.getByRole('button', { name: 'Download' }));
30
+ expect(screen.getByRole('tooltip', { name: 'Download' })).toBeTruthy();
31
+ }));
32
+ it('renders tooltip correctly if clicked', () => __awaiter(void 0, void 0, void 0, function* () {
33
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), tooltipContent: "Download", clickedTooltipContent: "Downloaded", isClicked: true }));
34
+ expect(screen.getByRole('button', { name: 'Downloaded' })).toBeTruthy();
35
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
36
+ yield userEvent.click(screen.getByRole('button', { name: 'Downloaded' }));
37
+ expect(screen.getByRole('tooltip', { name: 'Downloaded' })).toBeTruthy();
38
+ }));
39
+ it('if clicked variant for tooltip is not supplied, it uses the default', () => __awaiter(void 0, void 0, void 0, function* () {
40
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), tooltipContent: "Download", isClicked: true }));
41
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
42
+ yield userEvent.click(screen.getByRole('button', { name: 'Download' }));
43
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
44
+ }));
45
+ it('if clicked variant for aria label is not supplied, it uses the default', () => __awaiter(void 0, void 0, void 0, function* () {
46
+ render(React.createElement(ResponseActionButton, { icon: React.createElement(DownloadIcon, null), ariaLabel: "Download", isClicked: true }));
47
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
48
+ }));
49
+ });
@@ -3,6 +3,8 @@ import { TooltipProps } from '@patternfly/react-core';
3
3
  export interface ActionProps {
4
4
  /** Aria-label for the button */
5
5
  ariaLabel?: string;
6
+ /** Aria-label for the button, shown when the button is clicked. */
7
+ clickedAriaLabel?: string;
6
8
  /** On-click handler for the button */
7
9
  onClick?: ((event: MouseEvent | React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => void) | undefined;
8
10
  /** Class name for the button */
@@ -11,6 +13,8 @@ export interface ActionProps {
11
13
  isDisabled?: boolean;
12
14
  /** Content shown in the tooltip */
13
15
  tooltipContent?: string;
16
+ /** Content shown in the tooltip when the button is clicked. */
17
+ clickedTooltipContent?: string;
14
18
  /** Props to control the PF Tooltip component */
15
19
  tooltipProps?: TooltipProps;
16
20
  /** Icon for custom response action */
@@ -13,17 +13,34 @@ import React from 'react';
13
13
  import { ExternalLinkAltIcon, VolumeUpIcon, OutlinedThumbsUpIcon, OutlinedThumbsDownIcon, OutlinedCopyIcon } from '@patternfly/react-icons';
14
14
  import ResponseActionButton from './ResponseActionButton';
15
15
  export const ResponseActions = ({ actions }) => {
16
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
16
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
17
+ const [activeButton, setActiveButton] = React.useState();
17
18
  const { positive, negative, copy, share, listen } = actions, additionalActions = __rest(actions, ["positive", "negative", "copy", "share", "listen"]);
18
- return (React.createElement("div", { className: "pf-chatbot__response-actions" },
19
- positive && (React.createElement(ResponseActionButton, { ariaLabel: (_a = positive.ariaLabel) !== null && _a !== void 0 ? _a : 'Good response', onClick: positive.onClick, className: positive.className, isDisabled: positive.isDisabled, tooltipContent: (_b = positive.tooltipContent) !== null && _b !== void 0 ? _b : 'Good response', tooltipProps: positive.tooltipProps, icon: React.createElement(OutlinedThumbsUpIcon, null) })),
20
- negative && (React.createElement(ResponseActionButton, { ariaLabel: (_c = negative.ariaLabel) !== null && _c !== void 0 ? _c : 'Bad response', onClick: negative.onClick, className: negative.className, isDisabled: negative.isDisabled, tooltipContent: (_d = negative.tooltipContent) !== null && _d !== void 0 ? _d : 'Bad response', tooltipProps: negative.tooltipProps, icon: React.createElement(OutlinedThumbsDownIcon, null) })),
21
- copy && (React.createElement(ResponseActionButton, { ariaLabel: (_e = copy.ariaLabel) !== null && _e !== void 0 ? _e : 'Copy', onClick: copy.onClick, className: copy.className, isDisabled: copy.isDisabled, tooltipContent: (_f = copy.tooltipContent) !== null && _f !== void 0 ? _f : 'Copy', tooltipProps: copy.tooltipProps, icon: React.createElement(OutlinedCopyIcon, null) })),
22
- share && (React.createElement(ResponseActionButton, { ariaLabel: (_g = share.ariaLabel) !== null && _g !== void 0 ? _g : 'Share', onClick: share.onClick, className: share.className, isDisabled: share.isDisabled, tooltipContent: (_h = share.tooltipContent) !== null && _h !== void 0 ? _h : 'Share', tooltipProps: share.tooltipProps, icon: React.createElement(ExternalLinkAltIcon, null) })),
23
- listen && (React.createElement(ResponseActionButton, { ariaLabel: (_j = listen.ariaLabel) !== null && _j !== void 0 ? _j : 'Listen', onClick: listen.onClick, className: listen.className, isDisabled: listen.isDisabled, tooltipContent: (_k = listen.tooltipContent) !== null && _k !== void 0 ? _k : 'Listen', tooltipProps: listen.tooltipProps, icon: React.createElement(VolumeUpIcon, null) })),
19
+ const responseActions = React.useRef(null);
20
+ React.useEffect(() => {
21
+ const handleClickOutside = (e) => {
22
+ if (responseActions.current && !responseActions.current.contains(e.target)) {
23
+ setActiveButton(undefined);
24
+ }
25
+ };
26
+ window.addEventListener('click', handleClickOutside);
27
+ return () => {
28
+ window.removeEventListener('click', handleClickOutside);
29
+ };
30
+ }, []);
31
+ const handleClick = (e, id, onClick) => {
32
+ setActiveButton(id);
33
+ onClick && onClick(e);
34
+ };
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' })),
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' })),
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' })),
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' })),
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' })),
24
41
  Object.keys(additionalActions).map((action) => {
25
- var _a, _b, _c, _d, _e, _f, _g;
26
- return (React.createElement(ResponseActionButton, { key: action, ariaLabel: (_a = additionalActions[action]) === null || _a === void 0 ? void 0 : _a.ariaLabel, onClick: (_b = additionalActions[action]) === null || _b === void 0 ? void 0 : _b.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, icon: (_g = additionalActions[action]) === null || _g === void 0 ? void 0 : _g.icon }));
42
+ var _a, _b, _c, _d, _e, _f, _g, _h;
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 }));
27
44
  })));
28
45
  };
29
46
  export default ResponseActions;
@@ -13,25 +13,30 @@ import '@testing-library/jest-dom';
13
13
  import ResponseActions from './ResponseActions';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import { DownloadIcon, InfoCircleIcon, RedoIcon } from '@patternfly/react-icons';
16
+ import Message from '../Message';
16
17
  const ALL_ACTIONS = [
17
- { type: 'positive', label: 'Good response' },
18
- { type: 'negative', label: 'Bad response' },
19
- { type: 'copy', label: 'Copy' },
20
- { type: 'share', label: 'Share' },
21
- { type: 'listen', label: 'Listen' }
18
+ { type: 'positive', label: 'Good response', clickedLabel: 'Response recorded' },
19
+ { type: 'negative', label: 'Bad response', clickedLabel: 'Response recorded' },
20
+ { type: 'copy', label: 'Copy', clickedLabel: 'Copied' },
21
+ { type: 'share', label: 'Share', clickedLabel: 'Shared' },
22
+ { type: 'listen', label: 'Listen', clickedLabel: 'Listening' }
22
23
  ];
23
24
  const CUSTOM_ACTIONS = [
24
25
  {
25
26
  regenerate: {
26
27
  ariaLabel: 'Regenerate',
28
+ clickedAriaLabel: 'Regenerated',
27
29
  onClick: jest.fn(),
28
30
  tooltipContent: 'Regenerate',
31
+ clickedTooltipContent: 'Regenerated',
29
32
  icon: React.createElement(RedoIcon, null)
30
33
  },
31
34
  download: {
32
35
  ariaLabel: 'Download',
36
+ clickedAriaLabel: 'Downloaded',
33
37
  onClick: jest.fn(),
34
38
  tooltipContent: 'Download',
39
+ clickedTooltipContent: 'Downloaded',
35
40
  icon: React.createElement(DownloadIcon, null)
36
41
  },
37
42
  info: {
@@ -43,6 +48,59 @@ const CUSTOM_ACTIONS = [
43
48
  }
44
49
  ];
45
50
  describe('ResponseActions', () => {
51
+ afterEach(() => {
52
+ jest.clearAllMocks();
53
+ });
54
+ it('should handle click within group of buttons correctly', () => __awaiter(void 0, void 0, void 0, function* () {
55
+ render(React.createElement(ResponseActions, { actions: {
56
+ positive: { onClick: jest.fn() },
57
+ negative: { onClick: jest.fn() },
58
+ copy: { onClick: jest.fn() },
59
+ share: { onClick: jest.fn() },
60
+ listen: { onClick: jest.fn() }
61
+ } }));
62
+ const goodBtn = screen.getByRole('button', { name: 'Good response' });
63
+ const badBtn = screen.getByRole('button', { name: 'Bad response' });
64
+ const copyBtn = screen.getByRole('button', { name: 'Copy' });
65
+ const shareBtn = screen.getByRole('button', { name: 'Share' });
66
+ const listenBtn = screen.getByRole('button', { name: 'Listen' });
67
+ const buttons = [goodBtn, badBtn, copyBtn, shareBtn, listenBtn];
68
+ buttons.forEach((button) => {
69
+ expect(button).toBeTruthy();
70
+ });
71
+ yield userEvent.click(goodBtn);
72
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass('pf-chatbot__button--response-action-clicked');
73
+ let unclickedButtons = buttons.filter((button) => button !== goodBtn);
74
+ unclickedButtons.forEach((button) => {
75
+ expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
76
+ });
77
+ yield userEvent.click(badBtn);
78
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass('pf-chatbot__button--response-action-clicked');
79
+ unclickedButtons = buttons.filter((button) => button !== badBtn);
80
+ unclickedButtons.forEach((button) => {
81
+ expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
82
+ });
83
+ }));
84
+ it('should handle click outside of group of buttons correctly', () => __awaiter(void 0, void 0, void 0, function* () {
85
+ // using message just so we have something outside the group that's rendered
86
+ render(React.createElement(Message, { name: "Bot", role: "bot", avatar: "", content: "Example with all prebuilt actions", actions: {
87
+ positive: {},
88
+ negative: {}
89
+ } }));
90
+ const goodBtn = screen.getByRole('button', { name: 'Good response' });
91
+ const badBtn = screen.getByRole('button', { name: 'Bad response' });
92
+ expect(goodBtn).toBeTruthy();
93
+ expect(badBtn).toBeTruthy();
94
+ yield userEvent.click(goodBtn);
95
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass('pf-chatbot__button--response-action-clicked');
96
+ expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
97
+ yield userEvent.click(badBtn);
98
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass('pf-chatbot__button--response-action-clicked');
99
+ expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
100
+ yield userEvent.click(screen.getByText('Example with all prebuilt actions'));
101
+ expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
102
+ expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
103
+ }));
46
104
  it('should render buttons correctly', () => {
47
105
  ALL_ACTIONS.forEach(({ type, label }) => {
48
106
  render(React.createElement(ResponseActions, { actions: { [type]: { onClick: jest.fn() } } }));
@@ -57,6 +115,22 @@ describe('ResponseActions', () => {
57
115
  expect(spy).toHaveBeenCalledTimes(1);
58
116
  }));
59
117
  }));
118
+ it('should swap clicked and non-clicked aria labels on click', () => __awaiter(void 0, void 0, void 0, function* () {
119
+ ALL_ACTIONS.forEach((_a) => __awaiter(void 0, [_a], void 0, function* ({ type, label, clickedLabel }) {
120
+ render(React.createElement(ResponseActions, { actions: { [type]: { onClick: jest.fn() } } }));
121
+ expect(screen.getByRole('button', { name: label })).toBeTruthy();
122
+ yield userEvent.click(screen.getByRole('button', { name: label }));
123
+ expect(screen.getByRole('button', { name: clickedLabel })).toBeTruthy();
124
+ }));
125
+ }));
126
+ it('should swap clicked and non-clicked tooltips on click', () => __awaiter(void 0, void 0, void 0, function* () {
127
+ ALL_ACTIONS.forEach((_a) => __awaiter(void 0, [_a], void 0, function* ({ type, label, clickedLabel }) {
128
+ render(React.createElement(ResponseActions, { actions: { [type]: { onClick: jest.fn() } } }));
129
+ expect(screen.getByRole('button', { name: label })).toBeTruthy();
130
+ yield userEvent.click(screen.getByRole('button', { name: label }));
131
+ expect(screen.getByRole('tooltip', { name: clickedLabel })).toBeTruthy();
132
+ }));
133
+ }));
60
134
  it('should be able to change aria labels', () => {
61
135
  const actions = [
62
136
  { type: 'positive', ariaLabel: 'Thumbs up' },
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export interface SettingsFormProps {
3
+ /** Class applied to form container */
4
+ className?: string;
5
+ /** Array of fields to display in the settings layout */
6
+ fields?: {
7
+ id: string;
8
+ label: string;
9
+ field: React.ReactElement;
10
+ }[];
11
+ }
12
+ export declare const SettingsForm: React.FunctionComponent<SettingsFormProps>;
13
+ export default SettingsForm;
@@ -0,0 +1,20 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React from 'react';
13
+ export const SettingsForm = (_a) => {
14
+ var { className, fields = [] } = _a, props = __rest(_a, ["className", "fields"]);
15
+ return (React.createElement("div", Object.assign({ className: `pf-chatbot__settings-form-container ${className}` }, props),
16
+ React.createElement("form", { className: "pf-chatbot__settings-form" }, fields.map((field) => (React.createElement("div", { className: "pf-chatbot__settings-form-row", key: field.label },
17
+ React.createElement("label", { className: "pf-chatbot__settings-label", htmlFor: field.id }, field.label),
18
+ field.field))))));
19
+ };
20
+ export default SettingsForm;
@@ -0,0 +1,2 @@
1
+ export { default } from './SettingsForm';
2
+ export * from './SettingsForm';
@@ -0,0 +1,2 @@
1
+ export { default } from './SettingsForm';
2
+ export * from './SettingsForm';
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { ModalProps } from '@patternfly/react-core';
3
+ import { ChatbotDisplayMode } from '../Chatbot';
4
+ export interface TermsOfUseProps extends ModalProps {
5
+ /** Class applied to modal */
6
+ className?: string;
7
+ /** Action assigned to primary modal button */
8
+ onPrimaryAction?: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
9
+ /** Action assigned to secondary modal button */
10
+ onSecondaryAction: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
11
+ /** Name of primary modal button */
12
+ primaryActionBtn?: string;
13
+ /** Name of secondary modal button */
14
+ secondaryActionBtn?: string;
15
+ /** Function that handles modal toggle */
16
+ handleModalToggle: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
17
+ /** Whether modal is open */
18
+ isModalOpen: boolean;
19
+ /** Title of modal */
20
+ title?: string;
21
+ /** Display mode for the Chatbot parent; this influences the styles applied */
22
+ displayMode?: ChatbotDisplayMode;
23
+ /** Optional image displayed in header */
24
+ image?: string;
25
+ /** Alt text for optional image displayed in header */
26
+ altText?: string;
27
+ /** Ref applied to modal */
28
+ innerRef?: React.Ref<HTMLDivElement>;
29
+ /** OuiaID applied to modal */
30
+ ouiaId?: string;
31
+ }
32
+ export declare const TermsOfUseBase: React.FunctionComponent<TermsOfUseProps>;
33
+ declare const TermsOfUse: React.ForwardRefExoticComponent<Omit<TermsOfUseProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
34
+ export default TermsOfUse;
@@ -0,0 +1,42 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ // ============================================================================
13
+ // Terms of Use Modal - Chatbot Modal Extension
14
+ // ============================================================================
15
+ import React from 'react';
16
+ import { Button, Content, ModalBody, ModalFooter, ModalHeader } from '@patternfly/react-core';
17
+ import { ChatbotDisplayMode } from '../Chatbot';
18
+ import ChatbotModal from '../ChatbotModal/ChatbotModal';
19
+ export const TermsOfUseBase = (_a) => {
20
+ var { handleModalToggle, isModalOpen, onPrimaryAction, onSecondaryAction, primaryActionBtn = 'Accept', secondaryActionBtn = 'Decline', title = 'Terms of use', image, altText, displayMode = ChatbotDisplayMode.default, className, children, innerRef, ouiaId = 'TermsOfUse' } = _a, props = __rest(_a, ["handleModalToggle", "isModalOpen", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "image", "altText", "displayMode", "className", "children", "innerRef", "ouiaId"]);
21
+ const handlePrimaryAction = (_event) => {
22
+ handleModalToggle(_event);
23
+ onPrimaryAction && onPrimaryAction(_event);
24
+ };
25
+ const handleSecondaryAction = (_event) => {
26
+ onSecondaryAction(_event);
27
+ };
28
+ const modal = (React.createElement(ChatbotModal, Object.assign({ isOpen: isModalOpen, ouiaId: ouiaId, "aria-labelledby": "terms-of-use-title", "aria-describedby": "terms-of-use-modal", className: `pf-chatbot__terms-of-use-modal pf-chatbot__terms-of-use-modal--${displayMode} ${className ? className : ''}`, displayMode: displayMode }, props),
29
+ React.createElement("section", { className: `pf-chatbot__terms-of-use--section`, "aria-label": title, tabIndex: -1, ref: innerRef },
30
+ React.createElement(ModalHeader, null,
31
+ React.createElement("div", { className: "pf-chatbot__terms-of-use--header" },
32
+ image && altText && React.createElement("img", { src: image, className: "pf-chatbot__terms-of-use--image", alt: altText }),
33
+ React.createElement("h1", { className: "pf-chatbot__terms-of-use--title" }, title))),
34
+ React.createElement(ModalBody, null,
35
+ React.createElement(Content, null, children)),
36
+ React.createElement(ModalFooter, { className: "pf-chatbot__terms-of-use--footer" },
37
+ React.createElement(Button, { isBlock: true, key: "terms-of-use-modal-primary", variant: "primary", onClick: handlePrimaryAction, form: "terms-of-use-form", size: "lg" }, primaryActionBtn),
38
+ React.createElement(Button, { isBlock: true, key: "terms-of-use-modal-secondary", variant: "secondary", onClick: handleSecondaryAction, size: "lg" }, secondaryActionBtn)))));
39
+ return modal;
40
+ };
41
+ const TermsOfUse = React.forwardRef((props, ref) => (React.createElement(TermsOfUseBase, Object.assign({ innerRef: ref }, props))));
42
+ export default TermsOfUse;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';