Skip to content

Commit d98a5f2

Browse files
authored
[UIE-51] Move InfoBox to components package (#4367)
1 parent 27d0505 commit d98a5f2

File tree

9 files changed

+95
-49
lines changed

9 files changed

+95
-49
lines changed
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { screen } from '@testing-library/react';
2+
import userEvent from '@testing-library/user-event';
3+
import { h } from 'react-hyperscript-helpers';
4+
5+
import { InfoBox } from './InfoBox';
6+
import { renderWithTheme } from './internal/test-utils';
7+
8+
describe('InfoBox', () => {
9+
it('renders an icon button', async () => {
10+
// Act
11+
renderWithTheme(h(InfoBox, ['More information about the thing.']));
12+
const trigger = screen.getByRole('button');
13+
14+
// Assert
15+
expect(trigger).toHaveAccessibleName('More info');
16+
17+
const icon = trigger.querySelector('svg')!;
18+
expect(icon).toHaveAttribute('data-icon', 'info-circle');
19+
});
20+
21+
it('allows overriding the default icon', async () => {
22+
// Act
23+
renderWithTheme(h(InfoBox, { icon: 'error-standard' }, ['More information about the thing.']));
24+
const trigger = screen.getByRole('button');
25+
26+
// Assert
27+
const icon = trigger.querySelector('svg')!;
28+
expect(icon).toHaveAttribute('data-icon', 'error-standard');
29+
});
30+
31+
it('renders children in a dialog', async () => {
32+
// Arrange
33+
const user = userEvent.setup();
34+
35+
renderWithTheme(h(InfoBox, ['More information about the thing.']));
36+
37+
// Act
38+
const trigger = screen.getByRole('button');
39+
await user.click(trigger);
40+
41+
// Assert
42+
const dialog = screen.getByRole('dialog');
43+
expect(dialog).toHaveTextContent('More information about the thing.');
44+
});
45+
});

packages/components/src/InfoBox.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { CSSProperties, ReactNode } from 'react';
2+
import { div, h } from 'react-hyperscript-helpers';
3+
4+
import { Clickable } from './Clickable';
5+
import { icon } from './icon';
6+
import { IconId } from './icon-library';
7+
import { PopupTrigger, PopupTriggerProps } from './PopupTrigger';
8+
import { useThemeFromContext } from './theme';
9+
10+
export interface InfoBoxProps {
11+
children?: ReactNode;
12+
icon?: IconId;
13+
side?: PopupTriggerProps['side'];
14+
size?: number;
15+
style?: CSSProperties;
16+
tooltip?: ReactNode;
17+
}
18+
19+
export const InfoBox = (props: InfoBoxProps): ReactNode => {
20+
const { children, icon: iconId = 'info-circle', side, size, style, tooltip } = props;
21+
22+
const { colors } = useThemeFromContext();
23+
24+
return h(
25+
PopupTrigger,
26+
{
27+
side,
28+
content: div({ style: { padding: '0.5rem', width: 300 } }, [children]),
29+
},
30+
[
31+
h(
32+
Clickable,
33+
{
34+
'aria-label': 'More info',
35+
tagName: 'span',
36+
tooltip,
37+
},
38+
[icon(iconId, { size, style: { color: colors.accent(), cursor: 'pointer', ...style } })]
39+
),
40+
]
41+
);
42+
};

packages/components/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export * from './hooks/useUniqueId';
77
export * from './hooks/useWindowDimensions';
88
export * from './icon';
99
export type { IconId } from './icon-library';
10+
export * from './InfoBox';
1011
export { Interactive } from './Interactive';
1112
export * from './Link';
1213
export * from './PopupTrigger';

src/components/InfoBox.ts

+1-41
Original file line numberDiff line numberDiff line change
@@ -1,41 +1 @@
1-
import { IconId } from '@terra-ui-packages/components';
2-
import { CSSProperties, PropsWithChildren, ReactNode, useState } from 'react';
3-
import { div, h } from 'react-hyperscript-helpers';
4-
import { Clickable } from 'src/components/common';
5-
import { icon } from 'src/components/icons';
6-
import PopupTrigger from 'src/components/PopupTrigger';
7-
import colors from 'src/libs/colors';
8-
9-
interface InfoBoxProps {
10-
size?: number;
11-
style?: CSSProperties;
12-
side?: 'top' | 'bottom' | 'left' | 'right';
13-
tooltip?: ReactNode;
14-
iconOverride?: IconId;
15-
}
16-
17-
export const InfoBox = (props: PropsWithChildren<InfoBoxProps>) => {
18-
const { size, children, style, side, tooltip, iconOverride } = props;
19-
const [open, setOpen] = useState(false);
20-
return h(
21-
PopupTrigger,
22-
{
23-
side,
24-
onChange: setOpen,
25-
content: div({ style: { padding: '0.5rem', width: 300 } }, [children]),
26-
},
27-
[
28-
h(
29-
Clickable,
30-
{
31-
tooltip,
32-
tagName: 'span',
33-
'aria-label': 'More info',
34-
'aria-expanded': open,
35-
'aria-haspopup': true,
36-
},
37-
[icon(iconOverride || 'info-circle', { size, style: { cursor: 'pointer', color: colors.accent(), ...style } })]
38-
),
39-
]
40-
);
41-
};
1+
export { InfoBox } from '@terra-ui-packages/components';

src/pages/workspaces/migration/WorkspaceItem.ts

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ export const WorkspaceItem = (props: WorkspaceItemProps): ReactNode => {
9090
side: 'bottom',
9191
tooltip: 'Failure information',
9292
size: 18,
93-
iconOverride: undefined,
9493
},
9594
[workspaceInfo.failureReason]
9695
),

src/pages/workspaces/workspace/Dashboard/OwnerNotice.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export const OwnerNotice = (props: OwnerNoticeProps): ReactNode => {
4444
: h(
4545
InfoBox,
4646
{
47-
iconOverride: 'error-standard',
47+
icon: 'error-standard',
4848
style: { color: colors.accent() },
4949
},
5050
[notice]

src/pages/workspaces/workspace/jobHistory/SubmissionDetails.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ const deletionDelayYears = 1;
4343
const deletionDelayString = `${deletionDelayYears} year${deletionDelayYears > 1 ? 's' : ''}`;
4444
const isDeleted = (statusLastChangedDate) => differenceInDays(parseISO(statusLastChangedDate), Date.now()) > deletionDelayYears * 365;
4545

46-
const deletedInfoIcon = ({ name, iconOverride }) => {
46+
const deletedInfoIcon = ({ name, icon }) => {
4747
return h(
4848
InfoBox,
4949
{
5050
style: { color: colors.secondary(), margin: '0.5rem' },
5151
tooltip: `${name} unavailable. Click to learn more.`,
52-
iconOverride,
52+
icon,
5353
},
5454
[
5555
div({ style: Style.elements.sectionHeader }, 'Workflow Details Archived'),
@@ -208,8 +208,8 @@ const SubmissionWorkflowsTable = ({ workspace, submission }) => {
208208
h(Fragment, [
209209
isDeleted(filteredWorkflows[rowIndex].statusLastChangedDate)
210210
? [
211-
deletedInfoIcon({ name: 'Job Manager', iconOverride: 'tasks' }),
212-
deletedInfoIcon({ name: 'Workflow Dashboard', iconOverride: 'tachometer' }),
211+
deletedInfoIcon({ name: 'Job Manager', icon: 'tasks' }),
212+
deletedInfoIcon({ name: 'Workflow Dashboard', icon: 'tachometer' }),
213213
]
214214
: [
215215
h(

src/pages/workspaces/workspace/workflows/WorkflowView.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ const WorkflowView = _.flow(
10911091
// We show either an info message or a warning, based on whether increasing memory on retries is
10921092
// enabled and the value of the retry multiplier.
10931093
retryWithMoreMemory && retryMemoryFactor > 2
1094-
? h(InfoBox, { style: { color: colors.warning() }, iconOverride: 'warning-standard' }, [
1094+
? h(InfoBox, { style: { color: colors.warning() }, icon: 'warning-standard' }, [
10951095
'Retry factors above 2 are not recommended. The retry factor compounds and may substantially increase costs. ',
10961096
h(Link, { href: this.getSupportLink('4403215299355'), ...Utils.newTabLinkProps }, [clickToLearnMore]),
10971097
])

src/workflows-app/components/LogViewer.ts

-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ export const LogViewer = ({ modalTitle, logs, onDismiss }: LogViewerProps) => {
150150
tooltip: undefined,
151151
size: undefined,
152152
side: undefined,
153-
iconOverride: undefined,
154153
},
155154
[
156155
dl([

0 commit comments

Comments
 (0)