@patternfly/chatbot 2.2.0-prerelease.44 → 2.2.0-prerelease.45

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.
@@ -5,7 +5,7 @@ export interface SourcesCardProps extends CardProps {
5
5
  className?: string;
6
6
  /** Flag indicating if the pagination is disabled. */
7
7
  isDisabled?: boolean;
8
- /** Label for the English word "of". */
8
+ /** @deprecated ofWord has been deprecated. Label for the English word "of." */
9
9
  ofWord?: string;
10
10
  /** Accessible label for the pagination component. */
11
11
  paginationAriaLabel?: string;
@@ -15,6 +15,7 @@ export interface SourcesCardProps extends CardProps {
15
15
  link: string;
16
16
  body?: React.ReactNode | string;
17
17
  isExternal?: boolean;
18
+ hasShowMore?: boolean;
18
19
  }[];
19
20
  /** Label for the English word "source" */
20
21
  sourceWord?: string;
@@ -30,6 +31,10 @@ export interface SourcesCardProps extends CardProps {
30
31
  onPreviousClick?: (event: React.SyntheticEvent<HTMLButtonElement>, page: number) => void;
31
32
  /** Function called when page is changed. */
32
33
  onSetPage?: (event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => void;
34
+ /** Label for English words "show more" */
35
+ showMoreWords?: string;
36
+ /** Label for English words "show less" */
37
+ showLessWords?: string;
33
38
  }
34
39
  declare const SourcesCard: React.FunctionComponent<SourcesCardProps>;
35
40
  export default SourcesCard;
@@ -22,8 +22,12 @@ const react_1 = __importDefault(require("react"));
22
22
  const react_core_1 = require("@patternfly/react-core");
23
23
  const react_icons_1 = require("@patternfly/react-icons");
24
24
  const SourcesCard = (_a) => {
25
- var { className, isDisabled, ofWord = 'of', paginationAriaLabel = 'Pagination', sources, sourceWord = 'source', sourceWordPlural = 'sources', toNextPageAriaLabel = 'Go to next page', toPreviousPageAriaLabel = 'Go to previous page', onNextClick, onPreviousClick, onSetPage } = _a, props = __rest(_a, ["className", "isDisabled", "ofWord", "paginationAriaLabel", "sources", "sourceWord", "sourceWordPlural", "toNextPageAriaLabel", "toPreviousPageAriaLabel", "onNextClick", "onPreviousClick", "onSetPage"]);
25
+ var { className, isDisabled, paginationAriaLabel = 'Pagination', sources, sourceWord = 'source', sourceWordPlural = 'sources', toNextPageAriaLabel = 'Go to next page', toPreviousPageAriaLabel = 'Go to previous page', onNextClick, onPreviousClick, onSetPage, showMoreWords = 'show more', showLessWords = 'show less' } = _a, props = __rest(_a, ["className", "isDisabled", "paginationAriaLabel", "sources", "sourceWord", "sourceWordPlural", "toNextPageAriaLabel", "toPreviousPageAriaLabel", "onNextClick", "onPreviousClick", "onSetPage", "showMoreWords", "showLessWords"]);
26
26
  const [page, setPage] = react_1.default.useState(1);
27
+ const [isExpanded, setIsExpanded] = react_1.default.useState(false);
28
+ const onToggle = (_event, isExpanded) => {
29
+ setIsExpanded(isExpanded);
30
+ };
27
31
  const handleNewPage = (_evt, newPage) => {
28
32
  setPage(newPage);
29
33
  onSetPage && onSetPage(_evt, newPage);
@@ -39,7 +43,10 @@ const SourcesCard = (_a) => {
39
43
  react_1.default.createElement(react_core_1.Card, Object.assign({ className: "pf-chatbot__sources-card" }, props),
40
44
  react_1.default.createElement(react_core_1.CardTitle, { className: "pf-chatbot__sources-card-title" },
41
45
  react_1.default.createElement(react_core_1.Button, { component: "a", variant: react_core_1.ButtonVariant.link, href: sources[page - 1].link, icon: sources[page - 1].isExternal ? react_1.default.createElement(react_icons_1.ExternalLinkSquareAltIcon, null) : undefined, iconPosition: "end", isInline: true, rel: sources[page - 1].isExternal ? 'noreferrer' : undefined, target: sources[page - 1].isExternal ? '_blank' : undefined }, renderTitle(sources[page - 1].title))),
42
- sources[page - 1].body && (react_1.default.createElement(react_core_1.CardBody, { className: `pf-chatbot__sources-card-body ${sources.length === 1 && 'pf-chatbot__sources-card-no-footer'}` }, sources[page - 1].body)),
46
+ sources[page - 1].body && (react_1.default.createElement(react_core_1.CardBody, { className: `pf-chatbot__sources-card-body` }, sources[page - 1].hasShowMore ? (
47
+ // prevents extra VO announcements of button text - parent Message has aria-live
48
+ react_1.default.createElement("div", { "aria-live": "off" },
49
+ react_1.default.createElement(react_core_1.ExpandableSection, { variant: react_core_1.ExpandableSectionVariant.truncate, toggleText: isExpanded ? showLessWords : showMoreWords, onToggle: onToggle, isExpanded: isExpanded, truncateMaxLines: 2 }, sources[page - 1].body))) : (react_1.default.createElement("div", { className: "pf-chatbot__sources-card-body-text" }, sources[page - 1].body)))),
43
50
  sources.length > 1 && (react_1.default.createElement(react_core_1.CardFooter, { className: "pf-chatbot__sources-card-footer-container" },
44
51
  react_1.default.createElement("div", { className: "pf-chatbot__sources-card-footer" },
45
52
  react_1.default.createElement("nav", { className: `pf-chatbot__sources-card-footer-buttons ${className}`, "aria-label": paginationAriaLabel },
@@ -51,6 +58,10 @@ const SourcesCard = (_a) => {
51
58
  react_1.default.createElement(react_core_1.Icon, { iconSize: "lg" },
52
59
  react_1.default.createElement("svg", { className: "pf-v6-svg", viewBox: "0 0 280 500", fill: "currentColor", "aria-hidden": "true", role: "img", width: "1em", height: "1em" },
53
60
  react_1.default.createElement("path", { d: "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z" })))),
61
+ react_1.default.createElement("span", { "aria-hidden": "true" },
62
+ page,
63
+ "/",
64
+ sources.length),
54
65
  react_1.default.createElement(react_core_1.Button, { variant: react_core_1.ButtonVariant.plain, isDisabled: isDisabled || page === sources.length, "aria-label": toNextPageAriaLabel, "data-action": "next", onClick: (event) => {
55
66
  const newPage = page + 1 <= sources.length ? page + 1 : sources.length;
56
67
  onNextClick && onNextClick(event, newPage);
@@ -58,12 +69,6 @@ const SourcesCard = (_a) => {
58
69
  } },
59
70
  react_1.default.createElement(react_core_1.Icon, { isInline: true, iconSize: "lg" },
60
71
  react_1.default.createElement("svg", { className: "pf-v6-svg", viewBox: "0 0 180 500", fill: "currentColor", "aria-hidden": "true", role: "img", width: "1em", height: "1em" },
61
- react_1.default.createElement("path", { d: "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" }))))),
62
- react_1.default.createElement("span", { "aria-hidden": "true" },
63
- page,
64
- " ",
65
- ofWord,
66
- " ",
67
- sources.length)))))));
72
+ react_1.default.createElement("path", { d: "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" })))))))))));
68
73
  };
69
74
  exports.default = SourcesCard;
@@ -24,7 +24,7 @@ describe('SourcesCard', () => {
24
24
  expect(react_2.screen.getByText('Source 1')).toBeTruthy();
25
25
  // no buttons or navigation when there is only 1 source
26
26
  expect(react_2.screen.queryByRole('button')).toBeFalsy();
27
- expect(react_2.screen.queryByText('1 of 1')).toBeFalsy();
27
+ expect(react_2.screen.queryByText('1/1')).toBeFalsy();
28
28
  });
29
29
  it('should render card correctly if one source with a title is passed in', () => {
30
30
  (0, react_2.render)(react_1.default.createElement(SourcesCard_1.default, { sources: [{ title: 'How to make an apple pie', link: '' }] }));
@@ -49,7 +49,7 @@ describe('SourcesCard', () => {
49
49
  ] }));
50
50
  expect(react_2.screen.getByText('2 sources')).toBeTruthy();
51
51
  expect(react_2.screen.getByText('How to make an apple pie')).toBeTruthy();
52
- expect(react_2.screen.getByText('1 of 2')).toBeTruthy();
52
+ expect(react_2.screen.getByText('1/2')).toBeTruthy();
53
53
  react_2.screen.getByRole('button', { name: /Go to previous page/i });
54
54
  react_2.screen.getByRole('button', { name: /Go to next page/i });
55
55
  });
@@ -59,12 +59,12 @@ describe('SourcesCard', () => {
59
59
  { title: 'How to make cookies', link: '' }
60
60
  ] }));
61
61
  expect(react_2.screen.getByText('How to make an apple pie')).toBeTruthy();
62
- expect(react_2.screen.getByText('1 of 2')).toBeTruthy();
62
+ expect(react_2.screen.getByText('1/2')).toBeTruthy();
63
63
  expect(react_2.screen.getByRole('button', { name: /Go to previous page/i })).toBeDisabled();
64
64
  yield user_event_1.default.click(react_2.screen.getByRole('button', { name: /Go to next page/i }));
65
65
  expect(react_2.screen.queryByText('How to make an apple pie')).toBeFalsy();
66
66
  expect(react_2.screen.getByText('How to make cookies')).toBeTruthy();
67
- expect(react_2.screen.getByText('2 of 2')).toBeTruthy();
67
+ expect(react_2.screen.getByText('2/2')).toBeTruthy();
68
68
  expect(react_2.screen.getByRole('button', { name: /Go to previous page/i })).toBeEnabled();
69
69
  expect(react_2.screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
70
70
  }));
@@ -84,13 +84,6 @@ describe('SourcesCard', () => {
84
84
  expect(react_2.screen.getByRole('button', { name: /Go to previous page/i })).toBeDisabled();
85
85
  expect(react_2.screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
86
86
  });
87
- it('should change ofWord appropriately', () => {
88
- (0, react_2.render)(react_1.default.createElement(SourcesCard_1.default, { sources: [
89
- { title: 'How to make an apple pie', link: '' },
90
- { title: 'How to make cookies', link: '' }
91
- ], ofWord: 'de' }));
92
- expect(react_2.screen.getByText('1 de 2')).toBeTruthy();
93
- });
94
87
  it('should render navigation aria label appropriately', () => {
95
88
  (0, react_2.render)(react_1.default.createElement(SourcesCard_1.default, { sources: [
96
89
  { title: 'How to make an apple pie', link: '' },
@@ -160,4 +153,25 @@ describe('SourcesCard', () => {
160
153
  yield user_event_1.default.click(react_2.screen.getByRole('button', { name: /Go to previous page/i }));
161
154
  expect(spy).toHaveBeenCalledTimes(2);
162
155
  }));
156
+ it('should handle showMore appropriately', () => __awaiter(void 0, void 0, void 0, function* () {
157
+ (0, react_2.render)(react_1.default.createElement(SourcesCard_1.default, { sources: [
158
+ {
159
+ title: 'Getting started with Red Hat OpenShift',
160
+ link: '#',
161
+ body: 'Red Hat OpenShift on IBM Cloud is a managed offering to create your own cluster of compute hosts where you can deploy and manage containerized apps on IBM Cloud ...',
162
+ hasShowMore: true
163
+ },
164
+ {
165
+ title: 'Azure Red Hat OpenShift documentation',
166
+ link: '#',
167
+ body: 'Microsoft Azure Red Hat OpenShift allows you to deploy a production ready Red Hat OpenShift cluster in Azure ...'
168
+ },
169
+ {
170
+ title: 'OKD Documentation: Home',
171
+ link: '#',
172
+ body: 'OKD is a distribution of Kubernetes optimized for continuous application development and multi-tenant deployment. OKD also serves as the upstream code base upon ...'
173
+ }
174
+ ] }));
175
+ expect(react_2.screen.getByRole('region')).toHaveAttribute('class', 'pf-v6-c-expandable-section__content');
176
+ }));
163
177
  });
package/dist/css/main.css CHANGED
@@ -1895,7 +1895,7 @@
1895
1895
  box-shadow: var(--pf-t--global--box-shadow--sm);
1896
1896
  }
1897
1897
 
1898
- .pf-chatbot__sources-card-body {
1898
+ .pf-chatbot__sources-card-body-text {
1899
1899
  display: block;
1900
1900
  display: -webkit-box;
1901
1901
  height: 2.8125rem;
@@ -1904,11 +1904,6 @@
1904
1904
  -webkit-box-orient: vertical;
1905
1905
  overflow: hidden;
1906
1906
  text-overflow: ellipsis;
1907
- margin-bottom: var(--pf-t--global--spacer--md);
1908
- }
1909
-
1910
- .pf-chatbot__sources-card-no-footer {
1911
- margin-bottom: var(--pf-t--global--spacer--lg);
1912
1907
  }
1913
1908
 
1914
1909
  .pf-chatbot__sources-card-footer-container {
@@ -1917,13 +1912,14 @@
1917
1912
  }
1918
1913
  .pf-chatbot__sources-card-footer-container .pf-chatbot__sources-card-footer {
1919
1914
  display: flex;
1920
- justify-content: space-between;
1921
1915
  align-items: center;
1922
1916
  }
1923
1917
  .pf-chatbot__sources-card-footer-container .pf-chatbot__sources-card-footer-buttons {
1924
1918
  display: flex;
1925
1919
  gap: var(--pf-t--global--spacer--xs);
1926
1920
  align-items: center;
1921
+ justify-content: space-between;
1922
+ flex: 1;
1927
1923
  }
1928
1924
  .pf-chatbot__sources-card-footer-container .pf-chatbot__sources-card-footer-buttons .pf-v6-c-button {
1929
1925
  border-radius: var(--pf-t--global--border--radius--pill);
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AC5HJ;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACrBJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;ACzMF;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;ACrDJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;ACzIF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC5CN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;ACrFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAMJ;EACE;EACA;EACA;;;AC7FF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;ADrDN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AEhFF;EACE;EACA;EACA;EACA;EAGA;;;ADDE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;AEpDN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ALjBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AMjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;ACxGN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;ADvCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;AC3ER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC5BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EACA;EACA;EAEA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AC5HJ;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACrBJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;ACzMF;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;ACrDJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;ACzIF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC5CN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;ACrFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAMJ;EACE;EACA;EACA;;;AC7FF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;ADrDN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AEhFF;EACE;EACA;EACA;EACA;EAGA;;;ADDE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;;AEpDN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ALjBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AMjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;ACxGN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;ADvCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACvER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC5BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EACA;EACA;EAEA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
@@ -5,7 +5,7 @@ export interface SourcesCardProps extends CardProps {
5
5
  className?: string;
6
6
  /** Flag indicating if the pagination is disabled. */
7
7
  isDisabled?: boolean;
8
- /** Label for the English word "of". */
8
+ /** @deprecated ofWord has been deprecated. Label for the English word "of." */
9
9
  ofWord?: string;
10
10
  /** Accessible label for the pagination component. */
11
11
  paginationAriaLabel?: string;
@@ -15,6 +15,7 @@ export interface SourcesCardProps extends CardProps {
15
15
  link: string;
16
16
  body?: React.ReactNode | string;
17
17
  isExternal?: boolean;
18
+ hasShowMore?: boolean;
18
19
  }[];
19
20
  /** Label for the English word "source" */
20
21
  sourceWord?: string;
@@ -30,6 +31,10 @@ export interface SourcesCardProps extends CardProps {
30
31
  onPreviousClick?: (event: React.SyntheticEvent<HTMLButtonElement>, page: number) => void;
31
32
  /** Function called when page is changed. */
32
33
  onSetPage?: (event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => void;
34
+ /** Label for English words "show more" */
35
+ showMoreWords?: string;
36
+ /** Label for English words "show less" */
37
+ showLessWords?: string;
33
38
  }
34
39
  declare const SourcesCard: React.FunctionComponent<SourcesCardProps>;
35
40
  export default SourcesCard;
@@ -14,11 +14,15 @@ var __rest = (this && this.__rest) || function (s, e) {
14
14
  // ============================================================================
15
15
  import React from 'react';
16
16
  // Import PatternFly components
17
- import { Button, ButtonVariant, Card, CardBody, CardFooter, CardTitle, Icon, pluralize, Truncate } from '@patternfly/react-core';
17
+ import { Button, ButtonVariant, Card, CardBody, CardFooter, CardTitle, ExpandableSection, ExpandableSectionVariant, Icon, pluralize, Truncate } from '@patternfly/react-core';
18
18
  import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons';
19
19
  const SourcesCard = (_a) => {
20
- var { className, isDisabled, ofWord = 'of', paginationAriaLabel = 'Pagination', sources, sourceWord = 'source', sourceWordPlural = 'sources', toNextPageAriaLabel = 'Go to next page', toPreviousPageAriaLabel = 'Go to previous page', onNextClick, onPreviousClick, onSetPage } = _a, props = __rest(_a, ["className", "isDisabled", "ofWord", "paginationAriaLabel", "sources", "sourceWord", "sourceWordPlural", "toNextPageAriaLabel", "toPreviousPageAriaLabel", "onNextClick", "onPreviousClick", "onSetPage"]);
20
+ var { className, isDisabled, paginationAriaLabel = 'Pagination', sources, sourceWord = 'source', sourceWordPlural = 'sources', toNextPageAriaLabel = 'Go to next page', toPreviousPageAriaLabel = 'Go to previous page', onNextClick, onPreviousClick, onSetPage, showMoreWords = 'show more', showLessWords = 'show less' } = _a, props = __rest(_a, ["className", "isDisabled", "paginationAriaLabel", "sources", "sourceWord", "sourceWordPlural", "toNextPageAriaLabel", "toPreviousPageAriaLabel", "onNextClick", "onPreviousClick", "onSetPage", "showMoreWords", "showLessWords"]);
21
21
  const [page, setPage] = React.useState(1);
22
+ const [isExpanded, setIsExpanded] = React.useState(false);
23
+ const onToggle = (_event, isExpanded) => {
24
+ setIsExpanded(isExpanded);
25
+ };
22
26
  const handleNewPage = (_evt, newPage) => {
23
27
  setPage(newPage);
24
28
  onSetPage && onSetPage(_evt, newPage);
@@ -34,7 +38,10 @@ const SourcesCard = (_a) => {
34
38
  React.createElement(Card, Object.assign({ className: "pf-chatbot__sources-card" }, props),
35
39
  React.createElement(CardTitle, { className: "pf-chatbot__sources-card-title" },
36
40
  React.createElement(Button, { component: "a", variant: ButtonVariant.link, href: sources[page - 1].link, icon: sources[page - 1].isExternal ? React.createElement(ExternalLinkSquareAltIcon, null) : undefined, iconPosition: "end", isInline: true, rel: sources[page - 1].isExternal ? 'noreferrer' : undefined, target: sources[page - 1].isExternal ? '_blank' : undefined }, renderTitle(sources[page - 1].title))),
37
- sources[page - 1].body && (React.createElement(CardBody, { className: `pf-chatbot__sources-card-body ${sources.length === 1 && 'pf-chatbot__sources-card-no-footer'}` }, sources[page - 1].body)),
41
+ sources[page - 1].body && (React.createElement(CardBody, { className: `pf-chatbot__sources-card-body` }, sources[page - 1].hasShowMore ? (
42
+ // prevents extra VO announcements of button text - parent Message has aria-live
43
+ React.createElement("div", { "aria-live": "off" },
44
+ React.createElement(ExpandableSection, { variant: ExpandableSectionVariant.truncate, toggleText: isExpanded ? showLessWords : showMoreWords, onToggle: onToggle, isExpanded: isExpanded, truncateMaxLines: 2 }, sources[page - 1].body))) : (React.createElement("div", { className: "pf-chatbot__sources-card-body-text" }, sources[page - 1].body)))),
38
45
  sources.length > 1 && (React.createElement(CardFooter, { className: "pf-chatbot__sources-card-footer-container" },
39
46
  React.createElement("div", { className: "pf-chatbot__sources-card-footer" },
40
47
  React.createElement("nav", { className: `pf-chatbot__sources-card-footer-buttons ${className}`, "aria-label": paginationAriaLabel },
@@ -46,6 +53,10 @@ const SourcesCard = (_a) => {
46
53
  React.createElement(Icon, { iconSize: "lg" },
47
54
  React.createElement("svg", { className: "pf-v6-svg", viewBox: "0 0 280 500", fill: "currentColor", "aria-hidden": "true", role: "img", width: "1em", height: "1em" },
48
55
  React.createElement("path", { d: "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z" })))),
56
+ React.createElement("span", { "aria-hidden": "true" },
57
+ page,
58
+ "/",
59
+ sources.length),
49
60
  React.createElement(Button, { variant: ButtonVariant.plain, isDisabled: isDisabled || page === sources.length, "aria-label": toNextPageAriaLabel, "data-action": "next", onClick: (event) => {
50
61
  const newPage = page + 1 <= sources.length ? page + 1 : sources.length;
51
62
  onNextClick && onNextClick(event, newPage);
@@ -53,12 +64,6 @@ const SourcesCard = (_a) => {
53
64
  } },
54
65
  React.createElement(Icon, { isInline: true, iconSize: "lg" },
55
66
  React.createElement("svg", { className: "pf-v6-svg", viewBox: "0 0 180 500", fill: "currentColor", "aria-hidden": "true", role: "img", width: "1em", height: "1em" },
56
- React.createElement("path", { d: "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" }))))),
57
- React.createElement("span", { "aria-hidden": "true" },
58
- page,
59
- " ",
60
- ofWord,
61
- " ",
62
- sources.length)))))));
67
+ React.createElement("path", { d: "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" })))))))))));
63
68
  };
64
69
  export default SourcesCard;
@@ -19,7 +19,7 @@ describe('SourcesCard', () => {
19
19
  expect(screen.getByText('Source 1')).toBeTruthy();
20
20
  // no buttons or navigation when there is only 1 source
21
21
  expect(screen.queryByRole('button')).toBeFalsy();
22
- expect(screen.queryByText('1 of 1')).toBeFalsy();
22
+ expect(screen.queryByText('1/1')).toBeFalsy();
23
23
  });
24
24
  it('should render card correctly if one source with a title is passed in', () => {
25
25
  render(React.createElement(SourcesCard, { sources: [{ title: 'How to make an apple pie', link: '' }] }));
@@ -44,7 +44,7 @@ describe('SourcesCard', () => {
44
44
  ] }));
45
45
  expect(screen.getByText('2 sources')).toBeTruthy();
46
46
  expect(screen.getByText('How to make an apple pie')).toBeTruthy();
47
- expect(screen.getByText('1 of 2')).toBeTruthy();
47
+ expect(screen.getByText('1/2')).toBeTruthy();
48
48
  screen.getByRole('button', { name: /Go to previous page/i });
49
49
  screen.getByRole('button', { name: /Go to next page/i });
50
50
  });
@@ -54,12 +54,12 @@ describe('SourcesCard', () => {
54
54
  { title: 'How to make cookies', link: '' }
55
55
  ] }));
56
56
  expect(screen.getByText('How to make an apple pie')).toBeTruthy();
57
- expect(screen.getByText('1 of 2')).toBeTruthy();
57
+ expect(screen.getByText('1/2')).toBeTruthy();
58
58
  expect(screen.getByRole('button', { name: /Go to previous page/i })).toBeDisabled();
59
59
  yield userEvent.click(screen.getByRole('button', { name: /Go to next page/i }));
60
60
  expect(screen.queryByText('How to make an apple pie')).toBeFalsy();
61
61
  expect(screen.getByText('How to make cookies')).toBeTruthy();
62
- expect(screen.getByText('2 of 2')).toBeTruthy();
62
+ expect(screen.getByText('2/2')).toBeTruthy();
63
63
  expect(screen.getByRole('button', { name: /Go to previous page/i })).toBeEnabled();
64
64
  expect(screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
65
65
  }));
@@ -79,13 +79,6 @@ describe('SourcesCard', () => {
79
79
  expect(screen.getByRole('button', { name: /Go to previous page/i })).toBeDisabled();
80
80
  expect(screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
81
81
  });
82
- it('should change ofWord appropriately', () => {
83
- render(React.createElement(SourcesCard, { sources: [
84
- { title: 'How to make an apple pie', link: '' },
85
- { title: 'How to make cookies', link: '' }
86
- ], ofWord: 'de' }));
87
- expect(screen.getByText('1 de 2')).toBeTruthy();
88
- });
89
82
  it('should render navigation aria label appropriately', () => {
90
83
  render(React.createElement(SourcesCard, { sources: [
91
84
  { title: 'How to make an apple pie', link: '' },
@@ -155,4 +148,25 @@ describe('SourcesCard', () => {
155
148
  yield userEvent.click(screen.getByRole('button', { name: /Go to previous page/i }));
156
149
  expect(spy).toHaveBeenCalledTimes(2);
157
150
  }));
151
+ it('should handle showMore appropriately', () => __awaiter(void 0, void 0, void 0, function* () {
152
+ render(React.createElement(SourcesCard, { sources: [
153
+ {
154
+ title: 'Getting started with Red Hat OpenShift',
155
+ link: '#',
156
+ body: 'Red Hat OpenShift on IBM Cloud is a managed offering to create your own cluster of compute hosts where you can deploy and manage containerized apps on IBM Cloud ...',
157
+ hasShowMore: true
158
+ },
159
+ {
160
+ title: 'Azure Red Hat OpenShift documentation',
161
+ link: '#',
162
+ body: 'Microsoft Azure Red Hat OpenShift allows you to deploy a production ready Red Hat OpenShift cluster in Azure ...'
163
+ },
164
+ {
165
+ title: 'OKD Documentation: Home',
166
+ link: '#',
167
+ body: 'OKD is a distribution of Kubernetes optimized for continuous application development and multi-tenant deployment. OKD also serves as the upstream code base upon ...'
168
+ }
169
+ ] }));
170
+ expect(screen.getByRole('region')).toHaveAttribute('class', 'pf-v6-c-expandable-section__content');
171
+ }));
158
172
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.2.0-prerelease.44",
3
+ "version": "2.2.0-prerelease.45",
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",
@@ -14,7 +14,7 @@ export const MessageWithSourcesExample: React.FunctionComponent = () => {
14
14
  name="Bot"
15
15
  role="bot"
16
16
  avatar={patternflyAvatar}
17
- content="Example with sources"
17
+ content="This example has a body description that's within the recommended limit of 2 lines:"
18
18
  sources={{
19
19
  sources: [
20
20
  {
@@ -43,7 +43,36 @@ export const MessageWithSourcesExample: React.FunctionComponent = () => {
43
43
  name="Bot"
44
44
  role="bot"
45
45
  avatar={patternflyAvatar}
46
- content="Example with very long sources"
46
+ content="This example has a body description that's longer than the recommended limit of 2 lines, with a link to load the rest of the description:"
47
+ sources={{
48
+ sources: [
49
+ {
50
+ title: 'Getting started with Red Hat OpenShift',
51
+ link: '#',
52
+ body: 'Red Hat OpenShift on IBM Cloud is a managed offering to create your own cluster of compute hosts where you can deploy and manage containerized apps on IBM Cloud.',
53
+ hasShowMore: true
54
+ },
55
+ {
56
+ title: 'Azure Red Hat OpenShift documentation',
57
+ link: '#',
58
+ body: 'Microsoft Azure Red Hat OpenShift allows you to deploy a production ready Red Hat OpenShift cluster in Azure.',
59
+ hasShowMore: true
60
+ },
61
+ {
62
+ title: 'OKD Documentation: Home',
63
+ link: '#',
64
+ body: 'OKD is a distribution of Kubernetes optimized for continuous application development and multi-tenant deployment. OKD also serves as the upstream code base upon.',
65
+ hasShowMore: true
66
+ }
67
+ ],
68
+ onSetPage
69
+ }}
70
+ />
71
+ <Message
72
+ name="Bot"
73
+ role="bot"
74
+ avatar={patternflyAvatar}
75
+ content="This example has a truncated title:"
47
76
  sources={{
48
77
  sources: [
49
78
  {
@@ -66,7 +95,7 @@ export const MessageWithSourcesExample: React.FunctionComponent = () => {
66
95
  name="Bot"
67
96
  role="bot"
68
97
  avatar={patternflyAvatar}
69
- content="Example with only 1 source"
98
+ content="This example only includes 1 source:"
70
99
  sources={{
71
100
  sources: [
72
101
  {
@@ -83,7 +112,7 @@ export const MessageWithSourcesExample: React.FunctionComponent = () => {
83
112
  name="Bot"
84
113
  role="bot"
85
114
  avatar={patternflyAvatar}
86
- content="Example with sources that include a title and link"
115
+ content="This example has a title and no body description:"
87
116
  sources={{
88
117
  sources: [
89
118
  { title: 'Getting started with Red Hat OpenShift', link: '#', isExternal: true },
@@ -105,7 +134,7 @@ export const MessageWithSourcesExample: React.FunctionComponent = () => {
105
134
  name="Bot"
106
135
  role="bot"
107
136
  avatar={patternflyAvatar}
108
- content="Example with link-only sources (not recommended)"
137
+ content="This example displays the source as a link, without a title (not recommended)"
109
138
  sources={{
110
139
  sources: [
111
140
  {
@@ -144,7 +144,7 @@ If you are using Retrieval-Augmented Generation, you may want to display sources
144
144
 
145
145
  If a source will open outside of the ChatBot window, add an external link icon via `isExternal`.
146
146
 
147
- The API for a source requires a link at minimum, but we strongly recommend providing a more descriptive title and body description so users have enough context. The title is limited to 1 line and the body is limited to 2 lines.
147
+ The API for a source requires a link at minimum, but we strongly recommend providing a more descriptive title and body description so users have enough context. For the best clarity and readability, we strongly recommend limiting the title to 1 line and the body to 2 lines. If the body description is more than 2 lines, use the "long sources" or "very long sources" variant.
148
148
 
149
149
  ```js file="./MessageWithSources.tsx"
150
150
 
@@ -16,7 +16,7 @@
16
16
  box-shadow: var(--pf-t--global--box-shadow--sm);
17
17
  }
18
18
 
19
- .pf-chatbot__sources-card-body {
19
+ .pf-chatbot__sources-card-body-text {
20
20
  display: block;
21
21
  display: -webkit-box;
22
22
  height: 2.8125rem;
@@ -25,11 +25,6 @@
25
25
  -webkit-box-orient: vertical;
26
26
  overflow: hidden;
27
27
  text-overflow: ellipsis;
28
- margin-bottom: var(--pf-t--global--spacer--md);
29
- }
30
-
31
- .pf-chatbot__sources-card-no-footer {
32
- margin-bottom: var(--pf-t--global--spacer--lg);
33
28
  }
34
29
 
35
30
  .pf-chatbot__sources-card-footer-container {
@@ -38,13 +33,14 @@
38
33
  var(--pf-t--global--spacer--sm) !important;
39
34
  .pf-chatbot__sources-card-footer {
40
35
  display: flex;
41
- justify-content: space-between;
42
36
  align-items: center;
43
37
 
44
38
  &-buttons {
45
39
  display: flex;
46
40
  gap: var(--pf-t--global--spacer--xs);
47
41
  align-items: center;
42
+ justify-content: space-between;
43
+ flex: 1;
48
44
 
49
45
  .pf-v6-c-button {
50
46
  border-radius: var(--pf-t--global--border--radius--pill);
@@ -11,7 +11,7 @@ describe('SourcesCard', () => {
11
11
  expect(screen.getByText('Source 1')).toBeTruthy();
12
12
  // no buttons or navigation when there is only 1 source
13
13
  expect(screen.queryByRole('button')).toBeFalsy();
14
- expect(screen.queryByText('1 of 1')).toBeFalsy();
14
+ expect(screen.queryByText('1/1')).toBeFalsy();
15
15
  });
16
16
 
17
17
  it('should render card correctly if one source with a title is passed in', () => {
@@ -48,7 +48,7 @@ describe('SourcesCard', () => {
48
48
  );
49
49
  expect(screen.getByText('2 sources')).toBeTruthy();
50
50
  expect(screen.getByText('How to make an apple pie')).toBeTruthy();
51
- expect(screen.getByText('1 of 2')).toBeTruthy();
51
+ expect(screen.getByText('1/2')).toBeTruthy();
52
52
  screen.getByRole('button', { name: /Go to previous page/i });
53
53
  screen.getByRole('button', { name: /Go to next page/i });
54
54
  });
@@ -63,12 +63,12 @@ describe('SourcesCard', () => {
63
63
  />
64
64
  );
65
65
  expect(screen.getByText('How to make an apple pie')).toBeTruthy();
66
- expect(screen.getByText('1 of 2')).toBeTruthy();
66
+ expect(screen.getByText('1/2')).toBeTruthy();
67
67
  expect(screen.getByRole('button', { name: /Go to previous page/i })).toBeDisabled();
68
68
  await userEvent.click(screen.getByRole('button', { name: /Go to next page/i }));
69
69
  expect(screen.queryByText('How to make an apple pie')).toBeFalsy();
70
70
  expect(screen.getByText('How to make cookies')).toBeTruthy();
71
- expect(screen.getByText('2 of 2')).toBeTruthy();
71
+ expect(screen.getByText('2/2')).toBeTruthy();
72
72
  expect(screen.getByRole('button', { name: /Go to previous page/i })).toBeEnabled();
73
73
  expect(screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
74
74
  });
@@ -101,19 +101,6 @@ describe('SourcesCard', () => {
101
101
  expect(screen.getByRole('button', { name: /Go to next page/i })).toBeDisabled();
102
102
  });
103
103
 
104
- it('should change ofWord appropriately', () => {
105
- render(
106
- <SourcesCard
107
- sources={[
108
- { title: 'How to make an apple pie', link: '' },
109
- { title: 'How to make cookies', link: '' }
110
- ]}
111
- ofWord={'de'}
112
- />
113
- );
114
- expect(screen.getByText('1 de 2')).toBeTruthy();
115
- });
116
-
117
104
  it('should render navigation aria label appropriately', () => {
118
105
  render(
119
106
  <SourcesCard
@@ -230,4 +217,30 @@ describe('SourcesCard', () => {
230
217
  await userEvent.click(screen.getByRole('button', { name: /Go to previous page/i }));
231
218
  expect(spy).toHaveBeenCalledTimes(2);
232
219
  });
220
+
221
+ it('should handle showMore appropriately', async () => {
222
+ render(
223
+ <SourcesCard
224
+ sources={[
225
+ {
226
+ title: 'Getting started with Red Hat OpenShift',
227
+ link: '#',
228
+ body: 'Red Hat OpenShift on IBM Cloud is a managed offering to create your own cluster of compute hosts where you can deploy and manage containerized apps on IBM Cloud ...',
229
+ hasShowMore: true
230
+ },
231
+ {
232
+ title: 'Azure Red Hat OpenShift documentation',
233
+ link: '#',
234
+ body: 'Microsoft Azure Red Hat OpenShift allows you to deploy a production ready Red Hat OpenShift cluster in Azure ...'
235
+ },
236
+ {
237
+ title: 'OKD Documentation: Home',
238
+ link: '#',
239
+ body: 'OKD is a distribution of Kubernetes optimized for continuous application development and multi-tenant deployment. OKD also serves as the upstream code base upon ...'
240
+ }
241
+ ]}
242
+ />
243
+ );
244
+ expect(screen.getByRole('region')).toHaveAttribute('class', 'pf-v6-c-expandable-section__content');
245
+ });
233
246
  });
@@ -12,6 +12,8 @@ import {
12
12
  CardFooter,
13
13
  CardProps,
14
14
  CardTitle,
15
+ ExpandableSection,
16
+ ExpandableSectionVariant,
15
17
  Icon,
16
18
  pluralize,
17
19
  Truncate
@@ -23,12 +25,18 @@ export interface SourcesCardProps extends CardProps {
23
25
  className?: string;
24
26
  /** Flag indicating if the pagination is disabled. */
25
27
  isDisabled?: boolean;
26
- /** Label for the English word "of". */
28
+ /** @deprecated ofWord has been deprecated. Label for the English word "of." */
27
29
  ofWord?: string;
28
30
  /** Accessible label for the pagination component. */
29
31
  paginationAriaLabel?: string;
30
32
  /** Content rendered inside the paginated card */
31
- sources: { title?: string; link: string; body?: React.ReactNode | string; isExternal?: boolean }[];
33
+ sources: {
34
+ title?: string;
35
+ link: string;
36
+ body?: React.ReactNode | string;
37
+ isExternal?: boolean;
38
+ hasShowMore?: boolean;
39
+ }[];
32
40
  /** Label for the English word "source" */
33
41
  sourceWord?: string;
34
42
  /** Plural for sourceWord */
@@ -43,12 +51,15 @@ export interface SourcesCardProps extends CardProps {
43
51
  onPreviousClick?: (event: React.SyntheticEvent<HTMLButtonElement>, page: number) => void;
44
52
  /** Function called when page is changed. */
45
53
  onSetPage?: (event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => void;
54
+ /** Label for English words "show more" */
55
+ showMoreWords?: string;
56
+ /** Label for English words "show less" */
57
+ showLessWords?: string;
46
58
  }
47
59
 
48
60
  const SourcesCard: React.FunctionComponent<SourcesCardProps> = ({
49
61
  className,
50
62
  isDisabled,
51
- ofWord = 'of',
52
63
  paginationAriaLabel = 'Pagination',
53
64
  sources,
54
65
  sourceWord = 'source',
@@ -58,9 +69,16 @@ const SourcesCard: React.FunctionComponent<SourcesCardProps> = ({
58
69
  onNextClick,
59
70
  onPreviousClick,
60
71
  onSetPage,
72
+ showMoreWords = 'show more',
73
+ showLessWords = 'show less',
61
74
  ...props
62
75
  }: SourcesCardProps) => {
63
76
  const [page, setPage] = React.useState(1);
77
+ const [isExpanded, setIsExpanded] = React.useState(false);
78
+
79
+ const onToggle = (_event: React.MouseEvent, isExpanded: boolean) => {
80
+ setIsExpanded(isExpanded);
81
+ };
64
82
 
65
83
  const handleNewPage = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => {
66
84
  setPage(newPage);
@@ -93,10 +111,23 @@ const SourcesCard: React.FunctionComponent<SourcesCardProps> = ({
93
111
  </Button>
94
112
  </CardTitle>
95
113
  {sources[page - 1].body && (
96
- <CardBody
97
- className={`pf-chatbot__sources-card-body ${sources.length === 1 && 'pf-chatbot__sources-card-no-footer'}`}
98
- >
99
- {sources[page - 1].body}
114
+ <CardBody className={`pf-chatbot__sources-card-body`}>
115
+ {sources[page - 1].hasShowMore ? (
116
+ // prevents extra VO announcements of button text - parent Message has aria-live
117
+ <div aria-live="off">
118
+ <ExpandableSection
119
+ variant={ExpandableSectionVariant.truncate}
120
+ toggleText={isExpanded ? showLessWords : showMoreWords}
121
+ onToggle={onToggle}
122
+ isExpanded={isExpanded}
123
+ truncateMaxLines={2}
124
+ >
125
+ {sources[page - 1].body}
126
+ </ExpandableSection>
127
+ </div>
128
+ ) : (
129
+ <div className="pf-chatbot__sources-card-body-text">{sources[page - 1].body}</div>
130
+ )}
100
131
  </CardBody>
101
132
  )}
102
133
  {sources.length > 1 && (
@@ -129,6 +160,9 @@ const SourcesCard: React.FunctionComponent<SourcesCardProps> = ({
129
160
  </svg>
130
161
  </Icon>
131
162
  </Button>
163
+ <span aria-hidden="true">
164
+ {page}/{sources.length}
165
+ </span>
132
166
  <Button
133
167
  variant={ButtonVariant.plain}
134
168
  isDisabled={isDisabled || page === sources.length}
@@ -156,10 +190,6 @@ const SourcesCard: React.FunctionComponent<SourcesCardProps> = ({
156
190
  </Icon>
157
191
  </Button>
158
192
  </nav>
159
-
160
- <span aria-hidden="true">
161
- {page} {ofWord} {sources.length}
162
- </span>
163
193
  </div>
164
194
  </CardFooter>
165
195
  )}