Skip to content

Commit 9f6c1a6

Browse files
committed
Allow user to filter and select modules; display reasons why module was included
1 parent 59d087e commit 9f6c1a6

16 files changed

Lines changed: 377 additions & 45 deletions

client/components/ModuleButton.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.button {
2+
display: block;
3+
background: none;
4+
border: none;
5+
font-family: inherit;
6+
font-size: inherit;
7+
max-width: 100%;
8+
float: right;
9+
white-space: nowrap;
10+
overflow: hidden;
11+
text-overflow: initial;
12+
line-height: 1.25em;
13+
cursor: pointer;
14+
}
15+
16+
.button:after {
17+
content: ".";
18+
display: block;
19+
float: left;
20+
width: 4em;
21+
margin: -1em -2em;
22+
color: #fff;
23+
background: #fff;
24+
background: linear-gradient(to right, rgba(255,255,255,1) 50%,rgba(255,255,255,0) 100%);
25+
}
26+
27+
.content {
28+
float: right;
29+
min-width: 100%;
30+
margin-top: 0;
31+
margin-left: -1px;
32+
}
33+
34+
35+
36+
.button:hover {
37+
text-decoration: underline;
38+
}

client/components/ModuleButton.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/** @jsx h */
2+
import { h } from 'preact';
3+
import s from './ModuleButton.css';
4+
5+
const ModuleButton = ( { module, onClick } ) => (
6+
<button className={s.button} type="button" onClick={onClick}>
7+
<div className={s.content}>
8+
{module.path.replace('./node_modules/', '~')
9+
.replace(/\/index\.(js|jsx)$/, '')
10+
}
11+
{module.reasons.length > 0 && ` (${module.reasons.length})`}
12+
</div>
13+
</button>
14+
);
15+
16+
export default ModuleButton;

client/components/ModuleInfo.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.wrapper {
2+
font-size: 11px;
3+
font-family: Verdana;
4+
}
5+
6+
.path {
7+
overflow-wrap: break-word;
8+
}
9+
10+
.reasons {
11+
margin-top: 10px;
12+
font-weight: bold;
13+
}
14+
15+
.list {
16+
margin-top: 10px;
17+
}

client/components/ModuleInfo.jsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/** @jsx h */
2+
/* eslint-disable react/no-multi-comp */
3+
import { h } from 'preact';
4+
import cls from 'classnames';
5+
import ModuleList from './ModuleList';
6+
import s from './ModuleInfo.css';
7+
import filesize from 'filesize';
8+
9+
import { SIZE_SWITCH_ITEMS } from '../constants';
10+
11+
const ModuleSize = ({ module, sizeType } ) => {
12+
const sizeProp = `${sizeType}Size`;
13+
const size = module[sizeProp];
14+
const sizeLabel = SIZE_SWITCH_ITEMS.find(item => item.prop === sizeProp).label;
15+
16+
return (typeof size === 'number') ?
17+
<div>
18+
{sizeLabel} size: <strong>{filesize(size)}</strong>
19+
</div>
20+
:
21+
null;
22+
};
23+
24+
const ModuleInfo = ({ module, className, onModuleClick } ) => (
25+
<div className={cls(className, s.wrapper)}>
26+
<div><strong>{module.label}</strong></div>
27+
<br/>
28+
<ModuleSize module={module} sizeType="stat"/>
29+
<ModuleSize module={module} sizeType="parsed"/>
30+
<ModuleSize module={module} sizeType="gzip"/>
31+
{module.path &&
32+
<span className={s.path}>Path: <strong>{module.path}</strong></span>
33+
}
34+
{module.reasons &&
35+
[
36+
<div key="reasons-header" className={s.reasons}>Reasons:</div>,
37+
<ModuleList key="reasons-list" className={s.list} modules={module.reasons} onModuleClick={onModuleClick}/>
38+
]
39+
}
40+
</div>
41+
);
42+
43+
export default ModuleInfo;

client/components/ModuleList.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.list {
2+
padding: 0;
3+
margin: 0;
4+
list-style: none;
5+
}
6+
7+
.listItem {
8+
display: flex;
9+
padding: 0;
10+
}

client/components/ModuleList.jsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/** @jsx h */
2+
import { h } from 'preact';
3+
import cls from 'classnames';
4+
import ModuleButton from './ModuleButton';
5+
import s from './ModuleList.css';
6+
7+
const ModuleList = ( { modules, onModuleClick, className } ) => (
8+
<ul className={cls(s.list, className)}>
9+
{modules.map(module => (
10+
<li key={module.id} className={s.listItem}>
11+
{
12+
// eslint-disable-next-line react/jsx-no-bind
13+
}<ModuleButton module={module} onClick={onModuleClick.bind(null, module)}/>
14+
</li>
15+
))}
16+
</ul>
17+
);
18+
19+
export default ModuleList;

client/components/ModuleSearch.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.wrapper {
2+
font-family: Verdana;
3+
font-size: 11px;
4+
}
5+
6+
.input {
7+
padding: 2px;
8+
width: 100%;
9+
}
10+
11+
.list {
12+
padding: 10px 0;
13+
}

client/components/ModuleSearch.jsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/** @jsx h */
2+
import { h, Component } from 'preact';
3+
import ModuleList from './ModuleList';
4+
import s from './ModuleSearch.css';
5+
6+
export default class ModuleSearch extends Component {
7+
8+
constructor( props ) {
9+
super(props);
10+
}
11+
12+
componentDidMount( ) {
13+
this.input.focus();
14+
}
15+
16+
render( ) {
17+
18+
const { query } = this.props;
19+
let modules = [];
20+
21+
if (query) {
22+
modules = this.props.modules.filter(module => (
23+
module.path.indexOf(query) !== -1
24+
));
25+
}
26+
27+
return (
28+
<div className={s.wrapper}>
29+
<input ref={this.onRef}
30+
value={query}
31+
className={s.input}
32+
onInput={this.props.onChange}/>
33+
<ModuleList className={s.list} modules={modules} onModuleClick={this.props.onModuleClick}/>
34+
</div>
35+
);
36+
}
37+
38+
onRef = ref => {
39+
this.input = ref;
40+
}
41+
42+
}
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
.container, .map {
2-
position: relative;
2+
position: absolute;
3+
top: 0;
34
width: 100%;
45
height: 100%;
56
}
67

78
.sidebarGroup {
89
margin-bottom: 20px;
10+
clear: both;
911
}
1012

1113
.activeSize {
1214
font-weight: bold;
1315
}
16+
17+
.moduleInfo {
18+
padding-bottom: 10px;
19+
border-bottom: 1px solid lightgrey;
20+
margin-bottom: 10px;
21+
}
22+
23+
.backButton {
24+
margin-bottom: 10px;
25+
}

0 commit comments

Comments
 (0)