Skip to content

Commit 80cb2e5

Browse files
authored
feat(content-explorer): migrate subHeader to typescript (#3999)
* feat(content-explorer): migrate subHeader to typescript * feat(content-explorer): update test * feat(content-explorer): update variant prop in pageHeader
1 parent 6d299a1 commit 80cb2e5

File tree

18 files changed

+371
-325
lines changed

18 files changed

+371
-325
lines changed

i18n/en-US.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ be.gridView = Switch to Grid View
486486
be.gridView.decreaseColumnSize = Decrease column size
487487
# Label for increasing the size of columns in grid view
488488
be.gridView.increaseColumnSize = Increase column size
489+
# Label for the grid view size slider
490+
be.gridView.sliderLabel = Grid view size
489491
# Aria label for file icon
490492
be.iconFile = {extension} File
491493
# Label for in action.

src/components/grid-view/GridViewSlider.js renamed to src/components/grid-view/GridViewSlider.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @flow
21
import * as React from 'react';
32
import { useIntl } from 'react-intl';
43
import { Slider } from '@box/blueprint-web';
@@ -7,15 +6,21 @@ import './GridViewSlider.scss';
76

87
import messages from '../../elements/common/messages';
98

10-
type Props = {
11-
columnCount: number,
12-
gridMaxColumns: number,
13-
gridMinColumns: number,
14-
maxColumnCount: number,
15-
onChange: (newSliderValue: number) => void,
16-
};
9+
export interface GridViewSliderProps {
10+
columnCount: number;
11+
gridMaxColumns: number;
12+
gridMinColumns: number;
13+
maxColumnCount: number;
14+
onChange: (newSliderValue: number) => void;
15+
}
1716

18-
const GridViewSlider = ({ columnCount, gridMaxColumns, gridMinColumns, maxColumnCount, onChange }: Props) => {
17+
const GridViewSlider = ({
18+
columnCount,
19+
gridMaxColumns,
20+
gridMinColumns,
21+
maxColumnCount,
22+
onChange,
23+
}: GridViewSliderProps) => {
1924
const { formatMessage } = useIntl();
2025
const RANGE_STEP = 1;
2126

@@ -34,6 +39,7 @@ const GridViewSlider = ({ columnCount, gridMaxColumns, gridMinColumns, maxColumn
3439
minusButtonLabel={formatMessage(messages.gridViewDecreaseColumnSize)}
3540
onValueChange={onChange}
3641
plusButtonLabel={formatMessage(messages.gridViewIncreaseColumnSize)}
42+
sliderLabel={formatMessage(messages.gridViewSliderLabel)}
3743
step={RANGE_STEP}
3844
value={sliderValue}
3945
/>

src/components/grid-view/__tests__/GridViewSlider.test.js

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as React from 'react';
2+
import userEvent from '@testing-library/user-event';
3+
import { screen, render } from '../../../test-utils/testing-library';
4+
import GridViewSlider, { GridViewSliderProps } from '../GridViewSlider';
5+
6+
describe('GridViewSlider', () => {
7+
const defaultProps = {
8+
columnCount: 3,
9+
gridMaxColumns: 5,
10+
gridMinColumns: 1,
11+
maxColumnCount: 4,
12+
onChange: jest.fn(),
13+
};
14+
15+
const renderComponent = (props: Partial<GridViewSliderProps> = {}) =>
16+
render(<GridViewSlider {...defaultProps} {...props} />);
17+
18+
test('should render slider with correct initial value', () => {
19+
renderComponent();
20+
const slider = screen.getByRole('slider');
21+
expect(slider).toBeInTheDocument();
22+
expect(slider).toHaveAttribute('aria-valuenow', '3');
23+
});
24+
25+
test('should render slider with correct labels', () => {
26+
renderComponent();
27+
expect(screen.getByLabelText('Increase column size')).toBeInTheDocument();
28+
expect(screen.getByLabelText('Decrease column size')).toBeInTheDocument();
29+
expect(screen.getByLabelText('Grid view size')).toBeInTheDocument();
30+
});
31+
32+
test('should call onChange when slider value changes', async () => {
33+
const onChange = jest.fn();
34+
renderComponent({ onChange });
35+
36+
const increaseButton = screen.getByRole('button', { name: 'Increase column size' });
37+
await userEvent.click(increaseButton);
38+
expect(onChange).toHaveBeenCalledTimes(1);
39+
40+
const decreaseButton = screen.getByRole('button', { name: 'Decrease column size' });
41+
await userEvent.click(decreaseButton);
42+
expect(onChange).toHaveBeenCalledTimes(2);
43+
});
44+
45+
test('should not render slider if gridMinColumns is greater than or equal to maxColumnCount', () => {
46+
renderComponent({ gridMinColumns: 4, maxColumnCount: 4 });
47+
const slider = screen.queryByRole('slider');
48+
expect(slider).not.toBeInTheDocument();
49+
});
50+
});

src/components/grid-view/__tests__/__snapshots__/GridViewSlider.test.js.snap

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/elements/common/messages.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ const messages = defineMessages({
182182
description: 'Label for decreasing the size of columns in grid view',
183183
defaultMessage: 'Decrease column size',
184184
},
185+
gridViewSliderLabel: {
186+
id: 'be.gridView.sliderLabel',
187+
description: 'Label for the grid view size slider',
188+
defaultMessage: 'Grid view size',
189+
},
185190
listView: {
186191
id: 'be.listView',
187192
description: 'Label for switching to list view',

src/elements/common/sub-header/Add.js

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as React from 'react';
2+
import { FormattedMessage, useIntl } from 'react-intl';
3+
import { DropdownMenu, IconButton } from '@box/blueprint-web';
4+
import { Plus } from '@box/blueprint-web-assets/icons/Fill';
5+
6+
import messages from '../messages';
7+
8+
export interface AddProps {
9+
isDisabled: boolean;
10+
onCreate: () => void;
11+
onUpload: () => void;
12+
showCreate: boolean;
13+
showUpload: boolean;
14+
}
15+
16+
const Add = ({ isDisabled, onUpload, onCreate, showUpload = true, showCreate = true }: AddProps) => {
17+
const { formatMessage } = useIntl();
18+
19+
return (
20+
<DropdownMenu.Root>
21+
<DropdownMenu.Trigger>
22+
<IconButton
23+
aria-label={formatMessage(messages.add)}
24+
className="be-btn-add"
25+
disabled={isDisabled}
26+
icon={Plus}
27+
/>
28+
</DropdownMenu.Trigger>
29+
<DropdownMenu.Content>
30+
{showUpload && (
31+
<DropdownMenu.Item onClick={onUpload}>
32+
<FormattedMessage {...messages.upload} />
33+
</DropdownMenu.Item>
34+
)}
35+
{showCreate && (
36+
<DropdownMenu.Item onClick={onCreate}>
37+
<FormattedMessage {...messages.newFolder} />
38+
</DropdownMenu.Item>
39+
)}
40+
</DropdownMenu.Content>
41+
</DropdownMenu.Root>
42+
);
43+
};
44+
45+
export default Add;

src/elements/common/sub-header/Sort.js

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as React from 'react';
2+
import { FormattedMessage, useIntl } from 'react-intl';
3+
import { DropdownMenu, IconButton } from '@box/blueprint-web';
4+
import IconSort from '../../../icons/general/IconSort';
5+
import type { SortBy, SortDirection } from '../../../common/types/core';
6+
import { FIELD_NAME, FIELD_DATE, FIELD_SIZE, SORT_ASC, SORT_DESC } from '../../../constants';
7+
8+
import messages from '../messages';
9+
10+
export interface SortProps {
11+
onSortChange: (sortBy: SortBy, sortDirection: SortDirection) => void;
12+
}
13+
14+
type SortItem = [SortBy, SortDirection];
15+
16+
const SORT_ITEMS: Array<SortItem> = [
17+
[FIELD_NAME, SORT_ASC],
18+
[FIELD_NAME, SORT_DESC],
19+
[FIELD_DATE, SORT_ASC],
20+
[FIELD_DATE, SORT_DESC],
21+
[FIELD_SIZE, SORT_ASC],
22+
[FIELD_SIZE, SORT_DESC],
23+
];
24+
25+
const Sort = ({ onSortChange }: SortProps) => {
26+
const { formatMessage } = useIntl();
27+
28+
return (
29+
<DropdownMenu.Root>
30+
<DropdownMenu.Trigger>
31+
<IconButton aria-label={formatMessage(messages.sort)} className="be-btn-sort" icon={IconSort} />
32+
</DropdownMenu.Trigger>
33+
<DropdownMenu.Content>
34+
{SORT_ITEMS.map(([sortByValue, sortDirectionValue]) => {
35+
const sortItemKey = `${sortByValue}${sortDirectionValue}`;
36+
37+
return (
38+
<DropdownMenu.Item
39+
key={sortItemKey}
40+
onClick={() => onSortChange(sortByValue, sortDirectionValue)}
41+
>
42+
<FormattedMessage {...messages[sortItemKey]} />
43+
</DropdownMenu.Item>
44+
);
45+
})}
46+
</DropdownMenu.Content>
47+
</DropdownMenu.Root>
48+
);
49+
};
50+
51+
export default Sort;

0 commit comments

Comments
 (0)