Skip to content

Commit 4f52add

Browse files
authored
Allow filtering the list of entrypoints (#624)
* filter entrypoints * changelog
1 parent f01056a commit 4f52add

File tree

4 files changed

+88
-22
lines changed

4 files changed

+88
-22
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
1212

1313
## UNRELEASED
1414

15+
* **Improvement**
16+
* Allows filtering the list of entrypoints ([#624](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/624) by [@chriskrogh](https://github.com/chriskrogh))
17+
1518
* **Internal**
1619
* Make module much slimmer by replacing all `lodash.*` packages ([#612](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/612)) by [@sukkaw](https://github.com/sukkaw).
1720

client/components/Dropdown.css

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
white-space: nowrap;
44
}
55

6-
.select {
6+
.label {
7+
font-size: 11px;
8+
font-weight: bold;
9+
margin-bottom: 7px;
10+
}
11+
12+
.input {
713
border: 1px solid #aaa;
814
border-radius: 4px;
915
display: block;
@@ -12,8 +18,7 @@
1218
height: 27px;
1319
}
1420

15-
.label {
16-
font-size: 11px;
17-
font-weight: bold;
18-
margin-bottom: 7px;
21+
.option {
22+
padding: 4px 0;
23+
cursor: pointer;
1924
}

client/components/Dropdown.jsx

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,88 @@
1+
import {createRef} from 'preact';
12
import PureComponent from '../lib/PureComponent';
23

34
import s from './Dropdown.css';
5+
46
export default class Dropdown extends PureComponent {
7+
input = createRef();
8+
9+
state = {
10+
query: '',
11+
showOptions: false
12+
};
13+
14+
componentDidMount() {
15+
document.addEventListener('click', this.handleClickOutside, true);
16+
}
17+
18+
componentWillUnmount() {
19+
document.removeEventListener('click', this.handleClickOutside, true);
20+
}
521

622
render() {
7-
const {label, defaultOption, onSelectionChange, options} = this.props;
23+
const {label, options} = this.props;
24+
25+
const filteredOptions =
26+
this.state.query
27+
? options.filter((option) =>
28+
option.toLowerCase().includes(this.state.query.toLowerCase())
29+
)
30+
: options;
831

932
return (
1033
<div className={s.container}>
11-
<div className={s.label}>
12-
{label}:
13-
</div>
34+
<div className={s.label}>{label}:</div>
1435
<div>
15-
<select className={s.select} id={label} name={label} onChange={onSelectionChange}>
16-
<option value={defaultOption}>{defaultOption}</option>
17-
{options.map(option =>
18-
<option key={option} value={option}>{option}</option>
19-
)}
20-
</select>
36+
<input ref={this.input}
37+
className={s.input}
38+
type="text"
39+
value={this.state.query}
40+
onInput={this.handleInput}
41+
onFocus={this.handleFocus}/>
42+
{this.state.showOptions ? (
43+
<div className={s.options}>
44+
{filteredOptions.map((option) => (
45+
<div key={option}
46+
className={s.option}
47+
onClick={this.getOptionClickHandler(option)}>
48+
{option}
49+
</div>
50+
))}
51+
</div>
52+
) : null}
2153
</div>
2254
</div>
2355
);
2456
}
57+
58+
handleClickOutside = (event) => {
59+
const el = this.input.current;
60+
if (el && event && !el.contains(event.target)) {
61+
this.setState({showOptions: false});
62+
// If the query is not in the options, reset the selection
63+
if (this.state.query && !this.props.options.some((option) => option === this.state.query)) {
64+
this.setState({query: ''});
65+
this.props.onSelectionChange(undefined);
66+
}
67+
}
68+
};
69+
70+
handleInput = (event) => {
71+
const {value} = event.target;
72+
this.setState({query: value});
73+
if (!value) {
74+
this.props.onSelectionChange(undefined);
75+
}
76+
}
77+
78+
handleFocus = () => {
79+
// move the cursor to the end of the input
80+
this.input.current.value = this.state.query;
81+
this.setState({showOptions: true});
82+
}
83+
84+
getOptionClickHandler = (option) => () => {
85+
this.props.onSelectionChange(option);
86+
this.setState({query: option, showOptions: false});
87+
};
2588
}

client/components/ModulesTreemap.jsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ const SIZE_SWITCH_ITEMS = [
2525
{label: 'Gzipped', prop: 'gzipSize'}
2626
];
2727

28-
const DEFAULT_DROPDOWN_SELECTION = 'Select an entrypoint';
29-
3028
@observer
3129
export default class ModulesTreemap extends Component {
3230
mouseCoords = {
@@ -83,7 +81,6 @@ export default class ModulesTreemap extends Component {
8381
</div>
8482
<div className={s.sidebarGroup}>
8583
<Dropdown label="Filter to initial chunks"
86-
defaultOption={DEFAULT_DROPDOWN_SELECTION}
8784
options={store.entrypoints}
8885
onSelectionChange={this.handleSelectionChange}/>
8986
</div>
@@ -215,10 +212,8 @@ export default class ModulesTreemap extends Component {
215212
}
216213
}
217214

218-
handleSelectionChange = (event) => {
219-
const selected = event.target.value;
220-
221-
if (selected === DEFAULT_DROPDOWN_SELECTION) {
215+
handleSelectionChange = (selected) => {
216+
if (!selected) {
222217
store.selectedChunks = store.allChunks;
223218
return;
224219
}

0 commit comments

Comments
 (0)