@patternfly/chatbot 2.2.0-prerelease.4 → 2.2.0-prerelease.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
- package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
- package/dist/cjs/Settings/SettingsForm.js +27 -0
- package/dist/cjs/Settings/index.d.ts +2 -0
- package/dist/cjs/Settings/index.js +23 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/css/main.css +46 -4
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/Settings/package.json +1 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/esm/ResponseActions/ResponseActions.js +26 -9
- package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/esm/Settings/SettingsForm.d.ts +13 -0
- package/dist/esm/Settings/SettingsForm.js +20 -0
- package/dist/esm/Settings/index.d.ts +2 -0
- package/dist/esm/Settings/index.js +2 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +13 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +14 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +2 -2
- package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
- package/src/ResponseActions/ResponseActionButton.tsx +46 -27
- package/src/ResponseActions/ResponseActions.scss +10 -8
- package/src/ResponseActions/ResponseActions.test.tsx +103 -5
- package/src/ResponseActions/ResponseActions.tsx +54 -7
- package/src/Settings/Settings.scss +34 -0
- package/src/Settings/SettingsForm.tsx +25 -0
- package/src/Settings/index.ts +3 -0
- package/src/index.ts +3 -0
- package/src/main.scss +1 -0
@@ -4,27 +4,32 @@ import '@testing-library/jest-dom';
|
|
4
4
|
import ResponseActions from './ResponseActions';
|
5
5
|
import userEvent from '@testing-library/user-event';
|
6
6
|
import { DownloadIcon, InfoCircleIcon, RedoIcon } from '@patternfly/react-icons';
|
7
|
+
import Message from '../Message';
|
7
8
|
|
8
9
|
const ALL_ACTIONS = [
|
9
|
-
{ type: 'positive', label: 'Good response' },
|
10
|
-
{ type: 'negative', label: 'Bad response' },
|
11
|
-
{ type: 'copy', label: 'Copy' },
|
12
|
-
{ type: 'share', label: 'Share' },
|
13
|
-
{ type: 'listen', label: 'Listen' }
|
10
|
+
{ type: 'positive', label: 'Good response', clickedLabel: 'Response recorded' },
|
11
|
+
{ type: 'negative', label: 'Bad response', clickedLabel: 'Response recorded' },
|
12
|
+
{ type: 'copy', label: 'Copy', clickedLabel: 'Copied' },
|
13
|
+
{ type: 'share', label: 'Share', clickedLabel: 'Shared' },
|
14
|
+
{ type: 'listen', label: 'Listen', clickedLabel: 'Listening' }
|
14
15
|
];
|
15
16
|
|
16
17
|
const CUSTOM_ACTIONS = [
|
17
18
|
{
|
18
19
|
regenerate: {
|
19
20
|
ariaLabel: 'Regenerate',
|
21
|
+
clickedAriaLabel: 'Regenerated',
|
20
22
|
onClick: jest.fn(),
|
21
23
|
tooltipContent: 'Regenerate',
|
24
|
+
clickedTooltipContent: 'Regenerated',
|
22
25
|
icon: <RedoIcon />
|
23
26
|
},
|
24
27
|
download: {
|
25
28
|
ariaLabel: 'Download',
|
29
|
+
clickedAriaLabel: 'Downloaded',
|
26
30
|
onClick: jest.fn(),
|
27
31
|
tooltipContent: 'Download',
|
32
|
+
clickedTooltipContent: 'Downloaded',
|
28
33
|
icon: <DownloadIcon />
|
29
34
|
},
|
30
35
|
info: {
|
@@ -37,6 +42,81 @@ const CUSTOM_ACTIONS = [
|
|
37
42
|
];
|
38
43
|
|
39
44
|
describe('ResponseActions', () => {
|
45
|
+
afterEach(() => {
|
46
|
+
jest.clearAllMocks();
|
47
|
+
});
|
48
|
+
it('should handle click within group of buttons correctly', async () => {
|
49
|
+
render(
|
50
|
+
<ResponseActions
|
51
|
+
actions={{
|
52
|
+
positive: { onClick: jest.fn() },
|
53
|
+
negative: { onClick: jest.fn() },
|
54
|
+
copy: { onClick: jest.fn() },
|
55
|
+
share: { onClick: jest.fn() },
|
56
|
+
listen: { onClick: jest.fn() }
|
57
|
+
}}
|
58
|
+
/>
|
59
|
+
);
|
60
|
+
const goodBtn = screen.getByRole('button', { name: 'Good response' });
|
61
|
+
const badBtn = screen.getByRole('button', { name: 'Bad response' });
|
62
|
+
const copyBtn = screen.getByRole('button', { name: 'Copy' });
|
63
|
+
const shareBtn = screen.getByRole('button', { name: 'Share' });
|
64
|
+
const listenBtn = screen.getByRole('button', { name: 'Listen' });
|
65
|
+
const buttons = [goodBtn, badBtn, copyBtn, shareBtn, listenBtn];
|
66
|
+
buttons.forEach((button) => {
|
67
|
+
expect(button).toBeTruthy();
|
68
|
+
});
|
69
|
+
await userEvent.click(goodBtn);
|
70
|
+
expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
|
71
|
+
'pf-chatbot__button--response-action-clicked'
|
72
|
+
);
|
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
|
+
await userEvent.click(badBtn);
|
78
|
+
expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
|
79
|
+
'pf-chatbot__button--response-action-clicked'
|
80
|
+
);
|
81
|
+
unclickedButtons = buttons.filter((button) => button !== badBtn);
|
82
|
+
unclickedButtons.forEach((button) => {
|
83
|
+
expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
84
|
+
});
|
85
|
+
});
|
86
|
+
it('should handle click outside of group of buttons correctly', async () => {
|
87
|
+
// using message just so we have something outside the group that's rendered
|
88
|
+
render(
|
89
|
+
<Message
|
90
|
+
name="Bot"
|
91
|
+
role="bot"
|
92
|
+
avatar=""
|
93
|
+
content="Example with all prebuilt actions"
|
94
|
+
actions={{
|
95
|
+
positive: {},
|
96
|
+
negative: {}
|
97
|
+
}}
|
98
|
+
/>
|
99
|
+
);
|
100
|
+
const goodBtn = screen.getByRole('button', { name: 'Good response' });
|
101
|
+
const badBtn = screen.getByRole('button', { name: 'Bad response' });
|
102
|
+
expect(goodBtn).toBeTruthy();
|
103
|
+
expect(badBtn).toBeTruthy();
|
104
|
+
|
105
|
+
await userEvent.click(goodBtn);
|
106
|
+
expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
|
107
|
+
'pf-chatbot__button--response-action-clicked'
|
108
|
+
);
|
109
|
+
expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
110
|
+
|
111
|
+
await userEvent.click(badBtn);
|
112
|
+
expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
|
113
|
+
'pf-chatbot__button--response-action-clicked'
|
114
|
+
);
|
115
|
+
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
116
|
+
await userEvent.click(screen.getByText('Example with all prebuilt actions'));
|
117
|
+
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
118
|
+
expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
119
|
+
});
|
40
120
|
it('should render buttons correctly', () => {
|
41
121
|
ALL_ACTIONS.forEach(({ type, label }) => {
|
42
122
|
render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
|
@@ -53,6 +133,24 @@ describe('ResponseActions', () => {
|
|
53
133
|
});
|
54
134
|
});
|
55
135
|
|
136
|
+
it('should swap clicked and non-clicked aria labels on click', async () => {
|
137
|
+
ALL_ACTIONS.forEach(async ({ type, label, clickedLabel }) => {
|
138
|
+
render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
|
139
|
+
expect(screen.getByRole('button', { name: label })).toBeTruthy();
|
140
|
+
await userEvent.click(screen.getByRole('button', { name: label }));
|
141
|
+
expect(screen.getByRole('button', { name: clickedLabel })).toBeTruthy();
|
142
|
+
});
|
143
|
+
});
|
144
|
+
|
145
|
+
it('should swap clicked and non-clicked tooltips on click', async () => {
|
146
|
+
ALL_ACTIONS.forEach(async ({ type, label, clickedLabel }) => {
|
147
|
+
render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
|
148
|
+
expect(screen.getByRole('button', { name: label })).toBeTruthy();
|
149
|
+
await userEvent.click(screen.getByRole('button', { name: label }));
|
150
|
+
expect(screen.getByRole('tooltip', { name: clickedLabel })).toBeTruthy();
|
151
|
+
});
|
152
|
+
});
|
153
|
+
|
56
154
|
it('should be able to change aria labels', () => {
|
57
155
|
const actions = [
|
58
156
|
{ type: 'positive', ariaLabel: 'Thumbs up' },
|
@@ -12,6 +12,8 @@ import { TooltipProps } from '@patternfly/react-core';
|
|
12
12
|
export interface ActionProps {
|
13
13
|
/** Aria-label for the button */
|
14
14
|
ariaLabel?: string;
|
15
|
+
/** Aria-label for the button, shown when the button is clicked. */
|
16
|
+
clickedAriaLabel?: string;
|
15
17
|
/** On-click handler for the button */
|
16
18
|
onClick?: ((event: MouseEvent | React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => void) | undefined;
|
17
19
|
/** Class name for the button */
|
@@ -20,6 +22,8 @@ export interface ActionProps {
|
|
20
22
|
isDisabled?: boolean;
|
21
23
|
/** Content shown in the tooltip */
|
22
24
|
tooltipContent?: string;
|
25
|
+
/** Content shown in the tooltip when the button is clicked. */
|
26
|
+
clickedTooltipContent?: string;
|
23
27
|
/** Props to control the PF Tooltip component */
|
24
28
|
tooltipProps?: TooltipProps;
|
25
29
|
/** Icon for custom response action */
|
@@ -38,74 +42,117 @@ export interface ResponseActionProps {
|
|
38
42
|
}
|
39
43
|
|
40
44
|
export const ResponseActions: React.FunctionComponent<ResponseActionProps> = ({ actions }) => {
|
45
|
+
const [activeButton, setActiveButton] = React.useState<string>();
|
41
46
|
const { positive, negative, copy, share, listen, ...additionalActions } = actions;
|
47
|
+
const responseActions = React.useRef<HTMLDivElement>(null);
|
48
|
+
|
49
|
+
React.useEffect(() => {
|
50
|
+
const handleClickOutside = (e) => {
|
51
|
+
if (responseActions.current && !responseActions.current.contains(e.target)) {
|
52
|
+
setActiveButton(undefined);
|
53
|
+
}
|
54
|
+
};
|
55
|
+
window.addEventListener('click', handleClickOutside);
|
56
|
+
|
57
|
+
return () => {
|
58
|
+
window.removeEventListener('click', handleClickOutside);
|
59
|
+
};
|
60
|
+
}, []);
|
61
|
+
|
62
|
+
const handleClick = (
|
63
|
+
e: MouseEvent | React.MouseEvent<Element, MouseEvent> | KeyboardEvent,
|
64
|
+
id: string,
|
65
|
+
onClick?: (event: MouseEvent | React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => void
|
66
|
+
) => {
|
67
|
+
setActiveButton(id);
|
68
|
+
onClick && onClick(e);
|
69
|
+
};
|
70
|
+
|
42
71
|
return (
|
43
|
-
<div className="pf-chatbot__response-actions">
|
72
|
+
<div ref={responseActions} className="pf-chatbot__response-actions">
|
44
73
|
{positive && (
|
45
74
|
<ResponseActionButton
|
46
75
|
ariaLabel={positive.ariaLabel ?? 'Good response'}
|
47
|
-
|
76
|
+
clickedAriaLabel={positive.ariaLabel ?? 'Response recorded'}
|
77
|
+
onClick={(e) => handleClick(e, 'positive', positive.onClick)}
|
48
78
|
className={positive.className}
|
49
79
|
isDisabled={positive.isDisabled}
|
50
80
|
tooltipContent={positive.tooltipContent ?? 'Good response'}
|
81
|
+
clickedTooltipContent={positive.clickedTooltipContent ?? 'Response recorded'}
|
51
82
|
tooltipProps={positive.tooltipProps}
|
52
83
|
icon={<OutlinedThumbsUpIcon />}
|
84
|
+
isClicked={activeButton === 'positive'}
|
53
85
|
></ResponseActionButton>
|
54
86
|
)}
|
55
87
|
{negative && (
|
56
88
|
<ResponseActionButton
|
57
89
|
ariaLabel={negative.ariaLabel ?? 'Bad response'}
|
58
|
-
|
90
|
+
clickedAriaLabel={negative.ariaLabel ?? 'Response recorded'}
|
91
|
+
onClick={(e) => handleClick(e, 'negative', negative.onClick)}
|
59
92
|
className={negative.className}
|
60
93
|
isDisabled={negative.isDisabled}
|
61
94
|
tooltipContent={negative.tooltipContent ?? 'Bad response'}
|
95
|
+
clickedTooltipContent={negative.clickedTooltipContent ?? 'Response recorded'}
|
62
96
|
tooltipProps={negative.tooltipProps}
|
63
97
|
icon={<OutlinedThumbsDownIcon />}
|
98
|
+
isClicked={activeButton === 'negative'}
|
64
99
|
></ResponseActionButton>
|
65
100
|
)}
|
66
101
|
{copy && (
|
67
102
|
<ResponseActionButton
|
68
103
|
ariaLabel={copy.ariaLabel ?? 'Copy'}
|
69
|
-
|
104
|
+
clickedAriaLabel={copy.ariaLabel ?? 'Copied'}
|
105
|
+
onClick={(e) => handleClick(e, 'copy', copy.onClick)}
|
70
106
|
className={copy.className}
|
71
107
|
isDisabled={copy.isDisabled}
|
72
108
|
tooltipContent={copy.tooltipContent ?? 'Copy'}
|
109
|
+
clickedTooltipContent={copy.clickedTooltipContent ?? 'Copied'}
|
73
110
|
tooltipProps={copy.tooltipProps}
|
74
111
|
icon={<OutlinedCopyIcon />}
|
112
|
+
isClicked={activeButton === 'copy'}
|
75
113
|
></ResponseActionButton>
|
76
114
|
)}
|
77
115
|
{share && (
|
78
116
|
<ResponseActionButton
|
79
117
|
ariaLabel={share.ariaLabel ?? 'Share'}
|
80
|
-
|
118
|
+
clickedAriaLabel={share.ariaLabel ?? 'Shared'}
|
119
|
+
onClick={(e) => handleClick(e, 'share', share.onClick)}
|
81
120
|
className={share.className}
|
82
121
|
isDisabled={share.isDisabled}
|
83
122
|
tooltipContent={share.tooltipContent ?? 'Share'}
|
123
|
+
clickedTooltipContent={share.clickedTooltipContent ?? 'Shared'}
|
84
124
|
tooltipProps={share.tooltipProps}
|
85
125
|
icon={<ExternalLinkAltIcon />}
|
126
|
+
isClicked={activeButton === 'share'}
|
86
127
|
></ResponseActionButton>
|
87
128
|
)}
|
88
129
|
{listen && (
|
89
130
|
<ResponseActionButton
|
90
131
|
ariaLabel={listen.ariaLabel ?? 'Listen'}
|
91
|
-
|
132
|
+
clickedAriaLabel={listen.ariaLabel ?? 'Listening'}
|
133
|
+
onClick={(e) => handleClick(e, 'listen', listen.onClick)}
|
92
134
|
className={listen.className}
|
93
135
|
isDisabled={listen.isDisabled}
|
94
136
|
tooltipContent={listen.tooltipContent ?? 'Listen'}
|
137
|
+
clickedTooltipContent={listen.clickedTooltipContent ?? 'Listening'}
|
95
138
|
tooltipProps={listen.tooltipProps}
|
96
139
|
icon={<VolumeUpIcon />}
|
140
|
+
isClicked={activeButton === 'listen'}
|
97
141
|
></ResponseActionButton>
|
98
142
|
)}
|
99
143
|
{Object.keys(additionalActions).map((action) => (
|
100
144
|
<ResponseActionButton
|
101
145
|
key={action}
|
102
146
|
ariaLabel={additionalActions[action]?.ariaLabel}
|
103
|
-
|
147
|
+
clickedAriaLabel={additionalActions[action]?.clickedAriaLabel}
|
148
|
+
onClick={(e) => handleClick(e, action, additionalActions[action]?.onClick)}
|
104
149
|
className={additionalActions[action]?.className}
|
105
150
|
isDisabled={additionalActions[action]?.isDisabled}
|
106
151
|
tooltipContent={additionalActions[action]?.tooltipContent}
|
107
152
|
tooltipProps={additionalActions[action]?.tooltipProps}
|
153
|
+
clickedTooltipContent={additionalActions[action]?.clickedTooltipContent}
|
108
154
|
icon={additionalActions[action]?.icon}
|
155
|
+
isClicked={activeButton === action}
|
109
156
|
/>
|
110
157
|
))}
|
111
158
|
</div>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
.pf-chatbot__settings-form-container {
|
2
|
+
width: 100%;
|
3
|
+
display: flex;
|
4
|
+
justify-content: center;
|
5
|
+
overflow: scroll;
|
6
|
+
}
|
7
|
+
|
8
|
+
.pf-chatbot__settings-form {
|
9
|
+
display: flex;
|
10
|
+
flex-direction: column;
|
11
|
+
max-width: 60rem;
|
12
|
+
flex: 1;
|
13
|
+
}
|
14
|
+
|
15
|
+
.pf-chatbot__settings-form-row {
|
16
|
+
font-size: var(--pf-t--global--font--size--body--lg);
|
17
|
+
display: flex;
|
18
|
+
align-items: center;
|
19
|
+
justify-content: space-between;
|
20
|
+
border-bottom: 1px solid var(--pf-t--global--border--color--default);
|
21
|
+
padding: var(--pf-t--global--spacer--lg);
|
22
|
+
font-weight: 500;
|
23
|
+
}
|
24
|
+
|
25
|
+
.pf-chatbot__settings-form-row:last-of-type {
|
26
|
+
border-bottom: 0px;
|
27
|
+
}
|
28
|
+
|
29
|
+
.pf-chatbot__settings--title {
|
30
|
+
font-family: var(--pf-t--global--font--family--heading);
|
31
|
+
font-size: var(--pf-t--global--font--size--xl);
|
32
|
+
font-weight: 500;
|
33
|
+
text-align: center;
|
34
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
export interface SettingsFormProps {
|
4
|
+
/** Class applied to form container */
|
5
|
+
className?: string;
|
6
|
+
/** Array of fields to display in the settings layout */
|
7
|
+
fields?: { id: string; label: string; field: React.ReactElement }[];
|
8
|
+
}
|
9
|
+
|
10
|
+
export const SettingsForm: React.FunctionComponent<SettingsFormProps> = ({ className, fields = [], ...props }) => (
|
11
|
+
<div className={`pf-chatbot__settings-form-container ${className}`} {...props}>
|
12
|
+
<form className="pf-chatbot__settings-form">
|
13
|
+
{fields.map((field) => (
|
14
|
+
<div className="pf-chatbot__settings-form-row" key={field.label}>
|
15
|
+
<label className="pf-chatbot__settings-label" htmlFor={field.id}>
|
16
|
+
{field.label}
|
17
|
+
</label>
|
18
|
+
{field.field}
|
19
|
+
</div>
|
20
|
+
))}
|
21
|
+
</form>
|
22
|
+
</div>
|
23
|
+
);
|
24
|
+
|
25
|
+
export default SettingsForm;
|
package/src/index.ts
CHANGED
@@ -66,6 +66,9 @@ export * from './PreviewAttachment';
|
|
66
66
|
export { default as ResponseActions } from './ResponseActions';
|
67
67
|
export * from './ResponseActions';
|
68
68
|
|
69
|
+
export { default as Settings } from './Settings';
|
70
|
+
export * from './Settings';
|
71
|
+
|
69
72
|
export { default as SourceDetailsMenuItem } from './SourceDetailsMenuItem';
|
70
73
|
export * from './SourceDetailsMenuItem';
|
71
74
|
|
package/src/main.scss
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
@import './MessageBox/MessageBox';
|
23
23
|
@import './MessageBox/JumpButton';
|
24
24
|
@import './ResponseActions/ResponseActions';
|
25
|
+
@import './Settings/Settings';
|
25
26
|
@import './SourcesCard/SourcesCard.scss';
|
26
27
|
@import './SourceDetailsMenuItem/SourceDetailsMenuItem';
|
27
28
|
@import './TermsOfUse/TermsOfUse';
|