Skip to content

Commit 97a1d44

Browse files
authored
feat(content-explorer): Add toggle button for grid view (#1349)
* feat: added toggle between list and grid view * fix: added data-testid to ViewModeChangeButton
1 parent e71409c commit 97a1d44

File tree

15 files changed

+277
-100
lines changed

15 files changed

+277
-100
lines changed

examples/src/features.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ export default {
1212
enabled: false,
1313
},
1414
},
15+
contentExplorer: {
16+
gridView: {
17+
enabled: false,
18+
},
19+
},
1520
};

i18n/en-US.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ be.fileDescriptionInlineErrorTitleMessage = Something went wrong when saving the
252252
be.folderState = There are no items in this folder.
253253
# Aria label for button to get information about a file’s versions
254254
be.getVersionInfo = Get version information
255+
# Label for switching to grid view
256+
be.gridView = Switch to Grid View
255257
# Label for in action.
256258
be.in = In
257259
# Button text to cancel inline item deletion
@@ -280,6 +282,8 @@ be.keywordSkill = Topics
280282
be.keywordsAppliedList = Keywords were applied
281283
# Label for a list of keywords. {words} are the list of keywords.
282284
be.keywordsList = Keywords: {words}
285+
# Label for switching to list view
286+
be.listView = Switch to List View
283287
# Message shown when folder items are still fetching.
284288
be.loadingState = Please wait while the items load...
285289
# Placeholder for a logo.

src/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export const VIEW_UPLOAD_EMPTY: 'upload-empty' = 'upload-empty';
2424
export const VIEW_UPLOAD_IN_PROGRESS: 'upload-inprogress' = 'upload-inprogress';
2525
export const VIEW_UPLOAD_SUCCESS: 'upload-success' = 'upload-success';
2626

27+
/* ----------------------- ViewModes ---------------------------- */
28+
export const VIEW_MODE_LIST: 'list' = 'list';
29+
export const VIEW_MODE_GRID: 'grid' = 'grid';
30+
2731
/* ----------------------- Types ---------------------------- */
2832
export const TYPE_FOLDER: 'folder' = 'folder';
2933
export const TYPE_FILE: 'file' = 'file';

src/elements/common/flowTypes.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
// @flow
2+
import { VIEW_MODE_GRID, VIEW_MODE_LIST } from '../../constants';
3+
4+
type ViewMode = typeof VIEW_MODE_GRID | typeof VIEW_MODE_LIST;
25

36
type ErrorType = {
47
code: string,
@@ -7,5 +10,5 @@ type ErrorType = {
710
message?: string,
811
};
912

10-
// eslint-disable-next-line import/prefer-default-export
1113
export type { ErrorType };
14+
export type { ViewMode };

src/elements/common/messages.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ const messages = defineMessages({
127127
description: 'Label for add action',
128128
defaultMessage: 'Add',
129129
},
130+
gridView: {
131+
id: 'be.gridView',
132+
description: 'Label for switching to grid view',
133+
defaultMessage: 'Switch to Grid View',
134+
},
135+
listView: {
136+
id: 'be.listView',
137+
description: 'Label for switching to list view',
138+
defaultMessage: 'Switch to List View',
139+
},
130140
sort: {
131141
id: 'be.sort',
132142
description: 'Label for sort action',

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import React from 'react';
88
import SubHeaderLeft from './SubHeaderLeft';
99
import SubHeaderRight from './SubHeaderRight';
10+
import type { ViewMode } from '../flowTypes';
11+
import { VIEW_MODE_LIST } from '../../../constants';
1012

1113
import './SubHeader.scss';
1214

@@ -19,23 +21,27 @@ type Props = {
1921
onItemClick: Function,
2022
onSortChange: Function,
2123
onUpload: Function,
24+
onViewModeChange?: (viewMode: ViewMode) => void,
2225
rootId: string,
2326
rootName?: string,
2427
view: View,
28+
viewMode?: ViewMode,
2529
};
2630

2731
const SubHeader = ({
28-
rootId,
29-
rootName,
32+
canCreateNewFolder,
33+
canUpload,
34+
currentCollection,
35+
isSmall,
36+
onCreate,
3037
onItemClick,
3138
onSortChange,
32-
currentCollection,
3339
onUpload,
34-
onCreate,
35-
canUpload,
36-
canCreateNewFolder,
40+
onViewModeChange,
41+
rootId,
42+
rootName,
3743
view,
38-
isSmall,
44+
viewMode = VIEW_MODE_LIST,
3945
}: Props) => (
4046
<div className="be-sub-header" data-testid="be-sub-header">
4147
<SubHeaderLeft
@@ -50,7 +56,9 @@ const SubHeader = ({
5056
canCreateNewFolder={canCreateNewFolder}
5157
canUpload={canUpload}
5258
currentCollection={currentCollection}
59+
viewMode={viewMode}
5360
onCreate={onCreate}
61+
onViewModeChange={onViewModeChange}
5462
onSortChange={onSortChange}
5563
onUpload={onUpload}
5664
view={view}

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
import React from 'react';
88
import Sort from './Sort';
99
import Add from './Add';
10+
import ViewModeChangeButton from './ViewModeChangeButton';
11+
import { FeatureFlag } from '../feature-checking';
1012
import { VIEW_FOLDER } from '../../../constants';
13+
import type { ViewMode } from '../flowTypes';
1114
import './SubHeaderRight.scss';
1215

1316
type Props = {
@@ -17,25 +20,35 @@ type Props = {
1720
onCreate: Function,
1821
onSortChange: Function,
1922
onUpload: Function,
23+
onViewModeChange?: (viewMode: ViewMode) => void,
2024
view: View,
25+
viewMode: ViewMode,
2126
};
2227

2328
const SubHeaderRight = ({
24-
view,
25-
onUpload,
26-
onCreate,
27-
canUpload,
2829
canCreateNewFolder,
30+
canUpload,
2931
currentCollection,
32+
onCreate,
33+
onViewModeChange,
3034
onSortChange,
35+
onUpload,
36+
view,
37+
viewMode,
3138
}: Props) => {
3239
const { sortBy, sortDirection, items = [] }: Collection = currentCollection;
40+
const hasItems: boolean = items.length > 0;
3341
const isFolder: boolean = view === VIEW_FOLDER;
34-
const showSort: boolean = isFolder && items.length > 0;
42+
const showSort: boolean = isFolder && hasItems;
3543
const showAdd: boolean = (!!canUpload || !!canCreateNewFolder) && isFolder;
44+
const showGridButton: boolean = isFolder && hasItems;
3645

3746
return (
3847
<div className="be-sub-header-right">
48+
<FeatureFlag feature="contentExplorer.gridView.enabled">
49+
{showGridButton && <ViewModeChangeButton viewMode={viewMode} onViewModeChange={onViewModeChange} />}
50+
</FeatureFlag>
51+
3952
{showSort && !!sortBy && !!sortDirection && (
4053
<Sort onSortChange={onSortChange} sortBy={sortBy} sortDirection={sortDirection} />
4154
)}

src/elements/common/sub-header/SubHeaderRight.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@
33
.be-sub-header-right {
44
align-items: center;
55
display: flex;
6+
7+
.be-btn-sort {
8+
margin-left: 7px;
9+
}
610
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// @flow
2+
3+
import React from 'react';
4+
import { injectIntl, FormattedMessage } from 'react-intl';
5+
import classNames from 'classnames';
6+
7+
import Button from '../../../components/button';
8+
import IconGridViewInverted from '../../../icons/general/IconGridViewInverted';
9+
import IconListView from '../../../icons/general/IconListView';
10+
import messages from '../messages';
11+
import Tooltip from '../Tooltip';
12+
import type { ViewMode } from '../flowTypes';
13+
import { VIEW_MODE_GRID, VIEW_MODE_LIST } from '../../../constants';
14+
import './ViewModeChangeButton.scss';
15+
16+
type Props = {
17+
className?: string,
18+
onViewModeChange: (viewMode: ViewMode) => void,
19+
viewMode: ViewMode,
20+
} & InjectIntlProvidedProps;
21+
22+
const ViewModeChangeButton = ({ className = '', onViewModeChange, intl, viewMode, ...rest }: Props) => {
23+
const isGridView = viewMode === VIEW_MODE_GRID;
24+
25+
const onClick = () => {
26+
onViewModeChange(isGridView ? VIEW_MODE_LIST : VIEW_MODE_GRID);
27+
};
28+
29+
return (
30+
<Tooltip
31+
text={
32+
isGridView ? <FormattedMessage {...messages.listView} /> : <FormattedMessage {...messages.gridView} />
33+
}
34+
>
35+
<Button
36+
data-testid="view-mode-change-button"
37+
className={classNames('bdl-ViewModeChangeButton', className)}
38+
type="button"
39+
onClick={onClick}
40+
{...rest}
41+
>
42+
{isGridView ? <IconListView width={17} height={17} /> : <IconGridViewInverted width={17} height={17} />}
43+
</Button>
44+
</Tooltip>
45+
);
46+
};
47+
48+
export default injectIntl(ViewModeChangeButton);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.bdl-ViewModeChangeButton {
2+
padding: 5px 6px;
3+
4+
svg {
5+
display: block;
6+
}
7+
}

0 commit comments

Comments
 (0)