diff --git a/CHANGELOG.md b/CHANGELOG.md index b86d4e54..dd38e914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ ## UNRELEASED +* **Improvement** + * Allows filtering the list of entrypoints ([#624](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/624) by [@chriskrogh](https://github.com/chriskrogh)) + * **Internal** * 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). diff --git a/client/components/Dropdown.css b/client/components/Dropdown.css index 86653a6e..f3b78e8a 100644 --- a/client/components/Dropdown.css +++ b/client/components/Dropdown.css @@ -3,7 +3,13 @@ white-space: nowrap; } -.select { +.label { + font-size: 11px; + font-weight: bold; + margin-bottom: 7px; +} + +.input { border: 1px solid #aaa; border-radius: 4px; display: block; @@ -12,8 +18,7 @@ height: 27px; } -.label { - font-size: 11px; - font-weight: bold; - margin-bottom: 7px; +.option { + padding: 4px 0; + cursor: pointer; } diff --git a/client/components/Dropdown.jsx b/client/components/Dropdown.jsx index a539bb0c..6540a5c9 100644 --- a/client/components/Dropdown.jsx +++ b/client/components/Dropdown.jsx @@ -1,25 +1,88 @@ +import {createRef} from 'preact'; import PureComponent from '../lib/PureComponent'; import s from './Dropdown.css'; + export default class Dropdown extends PureComponent { + input = createRef(); + + state = { + query: '', + showOptions: false + }; + + componentDidMount() { + document.addEventListener('click', this.handleClickOutside, true); + } + + componentWillUnmount() { + document.removeEventListener('click', this.handleClickOutside, true); + } render() { - const {label, defaultOption, onSelectionChange, options} = this.props; + const {label, options} = this.props; + + const filteredOptions = + this.state.query + ? options.filter((option) => + option.toLowerCase().includes(this.state.query.toLowerCase()) + ) + : options; return (
-
- {label}: -
+
{label}:
- + + {this.state.showOptions ? ( +
+ {filteredOptions.map((option) => ( +
+ {option} +
+ ))} +
+ ) : null}
); } + + handleClickOutside = (event) => { + const el = this.input.current; + if (el && event && !el.contains(event.target)) { + this.setState({showOptions: false}); + // If the query is not in the options, reset the selection + if (this.state.query && !this.props.options.some((option) => option === this.state.query)) { + this.setState({query: ''}); + this.props.onSelectionChange(undefined); + } + } + }; + + handleInput = (event) => { + const {value} = event.target; + this.setState({query: value}); + if (!value) { + this.props.onSelectionChange(undefined); + } + } + + handleFocus = () => { + // move the cursor to the end of the input + this.input.current.value = this.state.query; + this.setState({showOptions: true}); + } + + getOptionClickHandler = (option) => () => { + this.props.onSelectionChange(option); + this.setState({query: option, showOptions: false}); + }; } diff --git a/client/components/ModulesTreemap.jsx b/client/components/ModulesTreemap.jsx index 39786deb..f397d267 100644 --- a/client/components/ModulesTreemap.jsx +++ b/client/components/ModulesTreemap.jsx @@ -25,8 +25,6 @@ const SIZE_SWITCH_ITEMS = [ {label: 'Gzipped', prop: 'gzipSize'} ]; -const DEFAULT_DROPDOWN_SELECTION = 'Select an entrypoint'; - @observer export default class ModulesTreemap extends Component { mouseCoords = { @@ -83,7 +81,6 @@ export default class ModulesTreemap extends Component {
@@ -215,10 +212,8 @@ export default class ModulesTreemap extends Component { } } - handleSelectionChange = (event) => { - const selected = event.target.value; - - if (selected === DEFAULT_DROPDOWN_SELECTION) { + handleSelectionChange = (selected) => { + if (!selected) { store.selectedChunks = store.allChunks; return; }