Skip to content

Commit b6386bd

Browse files
authored
Refactor frontend part 4 (#2745)
* Use CSS modules for file system views and menu * Remove unused classes and unnecessary CSS API use Replaced the CSS API to use props instead. * Update Login imports and typings * Use CSS modules for Login component * Define custom class for login icon This allows us to incrementally move away from the Blueprint's CSS API. * Move ConfirmDialog styles to use CSS modules * Fix SCSS warning * Use CSS modules in CSE machine and utils * Fix remote execution saga typing of returned value * Fix format * Simplify achievement dashboard styles * Remove unnecessary navbar styles * Fix deprecated prop * Update test snapshots
1 parent 5812721 commit b6386bd

24 files changed

+91
-142
lines changed

src/commons/dialogs/ConfirmDialog.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
Intent
99
} from '@blueprintjs/core';
1010
import classNames from 'classnames';
11-
import * as React from 'react';
11+
import React from 'react';
12+
import classes from 'src/styles/ConfirmDialog.module.scss';
1213

1314
export interface ConfirmDialogProps<T> {
1415
icon?: IconName;
@@ -31,7 +32,7 @@ export function ConfirmDialog<T>(
3132
onClick={() => props.onResponse && props.onResponse(choice.key)}
3233
intent={choice.intent}
3334
fill={props.largeButtons}
34-
className={classNames(props.largeButtons && 'large-button')}
35+
className={classNames(props.largeButtons && classes['large-button'])}
3536
{...choice.props}
3637
>
3738
{choice.label}
@@ -44,7 +45,7 @@ export function ConfirmDialog<T>(
4445
: () => props.onResponse && props.onResponse(escapeResponse);
4546
return (
4647
<Dialog
47-
className={classNames(Classes.DARK, 'ConfirmDialog')}
48+
className={classNames(Classes.DARK, classes['ConfirmDialog'])}
4849
title={props.title}
4950
isCloseButtonShown={typeof props.title === 'undefined' ? undefined : false}
5051
canEscapeKeyClose={!!escapeHandler}

src/commons/fileSystemView/FileSystemView.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Icon } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
33
import path from 'path';
44
import React from 'react';
5+
import classes from 'src/styles/FileSystemView.module.scss';
56

67
import { showSimpleErrorDialog } from '../utils/DialogHelper';
78
import { useTypedSelector } from '../utils/Hooks';
@@ -32,7 +33,7 @@ const FileSystemView: React.FC<FileSystemViewProps> = (props: FileSystemViewProp
3233
setFileSystemViewListKey((fileSystemViewListKey + 1) % 2);
3334

3435
if (fileSystem === null) {
35-
return <div className="file-system-view-error">Unable to load file system.</div>;
36+
return <div className={classes['file-system-view-error']}>Unable to load file system.</div>;
3637
}
3738

3839
const createNewFile = (fileName: string) => {
@@ -93,7 +94,7 @@ const FileSystemView: React.FC<FileSystemViewProps> = (props: FileSystemViewProp
9394
};
9495

9596
return (
96-
<div className="file-system-view-container">
97+
<div className={classes['file-system-view-container']}>
9798
<FileSystemViewList
9899
workspaceLocation={workspaceLocation}
99100
key={fileSystemViewListKey}
@@ -102,7 +103,7 @@ const FileSystemView: React.FC<FileSystemViewProps> = (props: FileSystemViewProp
102103
indentationLevel={0}
103104
/>
104105
{isAddingNewFile && (
105-
<div className="file-system-view-node-container">
106+
<div className={classes['file-system-view-node-container']}>
106107
<FileSystemViewIndentationPadding indentationLevel={0} />
107108
<Icon icon={IconNames.DOCUMENT} />
108109
<FileSystemViewPlaceholderNode
@@ -112,7 +113,7 @@ const FileSystemView: React.FC<FileSystemViewProps> = (props: FileSystemViewProp
112113
</div>
113114
)}
114115
{isAddingNewDirectory && (
115-
<div className="file-system-view-node-container">
116+
<div className={classes['file-system-view-node-container']}>
116117
<FileSystemViewIndentationPadding indentationLevel={0} />
117118
<Icon icon={IconNames.CHEVRON_RIGHT} />
118119
<FileSystemViewPlaceholderNode
@@ -122,7 +123,7 @@ const FileSystemView: React.FC<FileSystemViewProps> = (props: FileSystemViewProp
122123
</div>
123124
)}
124125
<FileSystemViewContextMenu
125-
className="file-system-view-empty-space"
126+
className={classes['file-system-view-empty-space']}
126127
createNewFile={handleCreateNewFile}
127128
createNewDirectory={handleCreateNewDirectory}
128129
/>

src/commons/fileSystemView/FileSystemViewContextMenu.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Classes } from '@blueprintjs/core';
22
import { ControlledMenu, MenuItem, useMenuState } from '@szhsin/react-menu';
33
import classNames from 'classnames';
44
import React from 'react';
5+
import classes from 'src/styles/ContextMenu.module.scss';
56

67
export type FileSystemViewContextMenuProps = {
78
children?: JSX.Element;
@@ -30,33 +31,33 @@ const FileSystemViewContextMenu: React.FC<FileSystemViewContextMenuProps> = (
3031
<div className={className} onContextMenu={onContextMenu}>
3132
{children}
3233
<ControlledMenu
33-
menuClassName={classNames(Classes.CARD, Classes.DARK, 'context-menu')}
34+
menuClassName={classNames(Classes.CARD, Classes.DARK, classes['context-menu'])}
3435
{...menuProps}
3536
anchorPoint={anchorPoint}
3637
onClose={() => toggleMenu(false)}
3738
>
3839
{createNewFile && (
39-
<MenuItem className="context-menu-item" onClick={createNewFile}>
40+
<MenuItem className={classes['context-menu-item']} onClick={createNewFile}>
4041
New File
4142
</MenuItem>
4243
)}
4344
{createNewDirectory && (
44-
<MenuItem className="context-menu-item" onClick={createNewDirectory}>
45+
<MenuItem className={classes['context-menu-item']} onClick={createNewDirectory}>
4546
New Directory
4647
</MenuItem>
4748
)}
4849
{open && (
49-
<MenuItem className="context-menu-item" onClick={open}>
50+
<MenuItem className={classes['context-menu-item']} onClick={open}>
5051
Open
5152
</MenuItem>
5253
)}
5354
{rename && (
54-
<MenuItem className="context-menu-item" onClick={rename}>
55+
<MenuItem className={classes['context-menu-item']} onClick={rename}>
5556
Rename
5657
</MenuItem>
5758
)}
5859
{remove && (
59-
<MenuItem className="context-menu-item" onClick={remove}>
60+
<MenuItem className={classes['context-menu-item']} onClick={remove}>
6061
Delete
6162
</MenuItem>
6263
)}

src/commons/fileSystemView/FileSystemViewDirectoryNode.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { FSModule } from 'browserfs/dist/node/core/FS';
44
import path from 'path';
55
import React from 'react';
66
import { useDispatch } from 'react-redux';
7+
import classes from 'src/styles/FileSystemView.module.scss';
78

89
import { rmdirRecursively } from '../fileSystem/utils';
910
import { showSimpleConfirmDialog, showSimpleErrorDialog } from '../utils/DialogHelper';
@@ -147,14 +148,14 @@ const FileSystemViewDirectoryNode: React.FC<FileSystemViewDirectoryNodeProps> =
147148
};
148149

149150
return (
150-
<div className="file-system-view-directory-node-container">
151+
<div className={classes['file-system-view-directory-node-container']}>
151152
<FileSystemViewContextMenu
152153
createNewFile={handleCreateNewFile}
153154
createNewDirectory={handleCreateNewDirectory}
154155
rename={handleRenameDirectory}
155156
remove={handleRemoveDirectory}
156157
>
157-
<div className="file-system-view-node-container" onClick={toggleIsExpanded}>
158+
<div className={classes['file-system-view-node-container']} onClick={toggleIsExpanded}>
158159
<FileSystemViewIndentationPadding indentationLevel={indentationLevel} />
159160
{isExpanded && <Icon icon={IconNames.CHEVRON_DOWN} />}
160161
{!isExpanded && <Icon icon={IconNames.CHEVRON_RIGHT} />}
@@ -171,7 +172,7 @@ const FileSystemViewDirectoryNode: React.FC<FileSystemViewDirectoryNodeProps> =
171172
</div>
172173
</FileSystemViewContextMenu>
173174
{isAddingNewFile && (
174-
<div className="file-system-view-node-container">
175+
<div className={classes['file-system-view-node-container']}>
175176
<FileSystemViewIndentationPadding indentationLevel={indentationLevel + 1} />
176177
<Icon icon={IconNames.DOCUMENT} />
177178
<FileSystemViewPlaceholderNode
@@ -181,7 +182,7 @@ const FileSystemViewDirectoryNode: React.FC<FileSystemViewDirectoryNodeProps> =
181182
</div>
182183
)}
183184
{isAddingNewDirectory && (
184-
<div className="file-system-view-node-container">
185+
<div className={classes['file-system-view-node-container']}>
185186
<FileSystemViewIndentationPadding indentationLevel={indentationLevel + 1} />
186187
<Icon icon={IconNames.CHEVRON_RIGHT} />
187188
<FileSystemViewPlaceholderNode

src/commons/fileSystemView/FileSystemViewFileName.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { FSModule } from 'browserfs/dist/node/core/FS';
22
import path from 'path';
33
import React from 'react';
44
import { useDispatch } from 'react-redux';
5+
import classes from 'src/styles/FileSystemView.module.scss';
56

67
import { showSimpleErrorDialog } from '../utils/DialogHelper';
78
import {
@@ -104,15 +105,15 @@ const FileSystemViewFileName: React.FC<FileSystemViewFileNameProps> = (
104105
type="text"
105106
autoFocus
106107
spellCheck={false}
107-
className="file-system-view-input"
108+
className={classes['file-system-view-input']}
108109
value={editedFileName}
109110
onChange={handleInputOnChange}
110111
onKeyDown={handleInputOnKeyDown}
111112
onFocus={handleInputOnFocus}
112113
onBlur={handleInputOnBlur}
113114
/>
114115
)}
115-
{!isEditing && <div className="file-system-view-file-name">{fileName}</div>}
116+
{!isEditing && <div className={classes['file-system-view-file-name']}>{fileName}</div>}
116117
</>
117118
);
118119
};

src/commons/fileSystemView/FileSystemViewFileNode.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { FSModule } from 'browserfs/dist/node/core/FS';
44
import path from 'path';
55
import React from 'react';
66
import { useDispatch } from 'react-redux';
7+
import classes from 'src/styles/FileSystemView.module.scss';
78

89
import { showSimpleConfirmDialog } from '../utils/DialogHelper';
910
import { addEditorTab, removeEditorTabForFile } from '../workspace/WorkspaceActions';
@@ -90,7 +91,7 @@ const FileSystemViewFileNode: React.FC<FileSystemViewFileNodeProps> = (
9091
rename={handleRenameFile}
9192
remove={handleRemoveFile}
9293
>
93-
<div className="file-system-view-node-container" onClick={onClick}>
94+
<div className={classes['file-system-view-node-container']} onClick={onClick}>
9495
<FileSystemViewIndentationPadding indentationLevel={indentationLevel} />
9596
<Icon icon={IconNames.DOCUMENT} />
9697
<FileSystemViewFileName

src/commons/fileSystemView/FileSystemViewList.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Spinner, SpinnerSize } from '@blueprintjs/core';
22
import { FSModule } from 'browserfs/dist/node/core/FS';
33
import path from 'path';
44
import React from 'react';
5+
import classes from 'src/styles/FileSystemView.module.scss';
56

67
import Delay from '../delay/Delay';
78
import { WorkspaceLocation } from '../workspace/WorkspaceTypes';
@@ -66,13 +67,13 @@ const FileSystemViewList: React.FC<FileSystemViewListProps> = (props: FileSystem
6667
if (!fileNames || !dirNames) {
6768
return (
6869
<Delay waitInMsBeforeRender={200}>
69-
<Spinner className="file-system-view-spinner" size={SpinnerSize.SMALL} />
70+
<Spinner className={classes['file-system-view-spinner']} size={SpinnerSize.SMALL} />
7071
</Delay>
7172
);
7273
}
7374

7475
return (
75-
<div className="file-system-view-list-container">
76+
<div className={classes['file-system-view-list-container']}>
7677
{dirNames.map(dirName => {
7778
return (
7879
<FileSystemViewDirectoryNode

src/commons/fileSystemView/FileSystemViewPlaceholderNode.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import classes from 'src/styles/FileSystemView.module.scss';
23

34
export type FileSystemViewPlaceholderNodeProps = {
45
processFileName: (fileName: string) => void;
@@ -29,7 +30,7 @@ const FileSystemViewPlaceholderNode: React.FC<FileSystemViewPlaceholderNodeProps
2930
type="text"
3031
autoFocus
3132
spellCheck={false}
32-
className="file-system-view-input"
33+
className={classes['file-system-view-input']}
3334
value={fileName}
3435
onChange={handleInputOnChange}
3536
onKeyDown={handleInputOnKeyDown}

src/commons/navigationBar/NavigationBar.tsx

+1-9
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,7 @@ const NavigationBar: React.FC = () => {
7070
<NavLink
7171
to={navbarEntry.to}
7272
className={({ isActive }) =>
73-
classNames(
74-
'NavigationBar__link__mobile',
75-
Classes.BUTTON,
76-
Classes.MINIMAL,
77-
Classes.LARGE,
78-
{
79-
[Classes.ACTIVE]: isActive
80-
}
81-
)
73+
classNames(Classes.BUTTON, Classes.MINIMAL, Classes.LARGE, { [Classes.ACTIVE]: isActive })
8274
}
8375
onClick={() => setMobileSideMenuOpen(false)}
8476
key={navbarEntry.text}

src/commons/navigationBar/subcomponents/GitHubAssessmentsNavigationBar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const GitHubAssessmentsNavigationBar: React.FC<GitHubAssessmentsNavigationBarPro
6464
}
6565
>
6666
<Icon icon={idx < 5 ? icons[idx] : icons[0]} />
67-
<div className="navbar-button-text hidden-xs hidden-sm">{type}</div>
67+
<div className="hidden-xs hidden-sm">{type}</div>
6868
</NavLink>
6969
);
7070
})}

src/commons/navigationBar/subcomponents/__tests__/__snapshots__/GitHubAssessmentsNavigationBar.tsx.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ exports[`Navbar renders correctly 1`] = `
2222
icon="flame"
2323
/>
2424
<div
25-
className="navbar-button-text hidden-xs hidden-sm"
25+
className="hidden-xs hidden-sm"
2626
>
2727
Missions
2828
</div>
@@ -42,7 +42,7 @@ exports[`Navbar renders correctly 1`] = `
4242
icon="lightbulb"
4343
/>
4444
<div
45-
className="navbar-button-text hidden-xs hidden-sm"
45+
className="hidden-xs hidden-sm"
4646
>
4747
Quests
4848
</div>

src/commons/sagas/RemoteExecutionSaga.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SlingClient } from '@sourceacademy/sling-client';
2-
import { assemble, compile, compileFiles, Context } from 'js-slang';
2+
import { assemble, compileFiles, Context } from 'js-slang';
33
import { ExceptionError } from 'js-slang/dist/errors/errors';
44
import { Chapter, Variant } from 'js-slang/dist/types';
55
import _ from 'lodash';
@@ -288,7 +288,7 @@ export function* remoteExecutionSaga(): SagaIterator {
288288
// clear the context of errors (note: the way this works is that the context
289289
// is mutated by js-slang anyway, so it's ok to do it like this)
290290
context.errors.length = 0;
291-
const compiled: MaybePromise<ReturnType<typeof compile>> = yield call(
291+
const compiled: MaybePromise<ReturnType<typeof compileFiles>> = yield call(
292292
compileFiles,
293293
files,
294294
entrypointFilePath,

src/commons/sideContent/SideContent.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const renderTab = (
5151
const tabTitle = (
5252
<Tooltip2 content={tab.label}>
5353
<div className={generateClassName(tab.id)} id={generateIconId(tabId)}>
54-
<Icon icon={tab.iconName} iconSize={iconSize} />
54+
<Icon icon={tab.iconName} size={iconSize} />
5555
</div>
5656
</Tooltip2>
5757
);

src/features/envVisualizer/EnvVisualizerLayout.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Frame } from 'js-slang/dist/types';
33
import { KonvaEventObject } from 'konva/lib/Node';
44
import React, { RefObject } from 'react';
55
import { Layer, Rect, Stage } from 'react-konva';
6+
import classes from 'src/styles/Draggable.module.scss';
67

78
import { ControlStack } from './compactComponents/ControlStack';
89
import { Level as CompactLevel } from './compactComponents/Level';
@@ -554,7 +555,7 @@ export class Layout {
554555
ref={this.stageRef}
555556
draggable
556557
onWheel={Layout.zoomStage}
557-
className="draggable"
558+
className={classes['draggable']}
558559
>
559560
<Layer>
560561
<Rect

src/features/envVisualizer/EnvVisualizerUtils.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Group } from 'konva/lib/Group';
1515
import { Node } from 'konva/lib/Node';
1616
import { Shape } from 'konva/lib/Shape';
1717
import { cloneDeep } from 'lodash';
18+
import classes from 'src/styles/Draggable.module.scss';
1819

1920
import { ControlItemComponent } from './compactComponents/ControlItemComponent';
2021
import { Frame } from './compactComponents/Frame';
@@ -253,16 +254,16 @@ export function getBodyText(data: () => any): string {
253254
export function setHoveredCursor(target: Node | Group) {
254255
const container = target.getStage()?.container();
255256
if (container) {
256-
container.classList.remove('draggable');
257-
container.classList.add('clickable');
257+
container.classList.remove(classes['draggable']);
258+
container.classList.add(classes['clickable']);
258259
}
259260
}
260261

261262
export function setUnhoveredCursor(target: Node | Group) {
262263
const container = target.getStage()?.container();
263264
if (container) {
264-
container.classList.remove('clickable');
265-
container.classList.add('draggable');
265+
container.classList.remove(classes['clickable']);
266+
container.classList.add(classes['draggable']);
266267
}
267268
}
268269

0 commit comments

Comments
 (0)