MCPcopy
hub / github.com/element-hq/element-web / Dropdown

Class Dropdown

apps/web/src/components/views/elements/Dropdown.tsx:118–421  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

116 * javascript.
117 */
118export default class Dropdown extends React.Component<DropdownProps, IState> {
119 private readonly buttonRef = createRef<HTMLDivElement>();
120 private dropdownRootElement: HTMLDivElement | null = null;
121 private ignoreEvent: MouseEvent | null = null;
122 private childrenByKey: Record<string, ReactNode> = {};
123
124 public constructor(props: DropdownProps) {
125 super(props);
126
127 this.reindexChildren(this.props.children);
128
129 const firstChild = props.children[0];
130
131 this.state = {
132 // True if the menu is dropped-down
133 expanded: false,
134 // The key of the highlighted option
135 // (the option that would become selected if you pressed enter)
136 highlightedOption: firstChild.key,
137 // the current search query
138 searchQuery: "",
139 };
140 }
141
142 public componentDidMount(): void {
143 // Listen for all clicks on the document so we can close the
144 // menu when the user clicks somewhere else
145 document.addEventListener("click", this.onDocumentClick, false);
146 }
147
148 public componentDidUpdate(prevProps: Readonly<DropdownProps>): void {
149 if (objectHasDiff(this.props, prevProps) && this.props.children?.length) {
150 this.reindexChildren(this.props.children);
151 const firstChild = this.props.children[0];
152 this.setState({
153 highlightedOption: firstChild.key,
154 });
155 }
156 }
157
158 public componentWillUnmount(): void {
159 document.removeEventListener("click", this.onDocumentClick, false);
160 }
161
162 private reindexChildren(children: ReactElement[]): void {
163 this.childrenByKey = {};
164 React.Children.forEach(children, (child) => {
165 this.childrenByKey[(child as DropdownProps["children"][number]).key] = child;
166 });
167 }
168
169 private onDocumentClick = (ev: MouseEvent): void => {
170 // Close the dropdown if the user clicks anywhere that isn't
171 // within our root element
172 if (ev !== this.ignoreEvent) {
173 this.setState({
174 expanded: false,
175 });

Callers

nothing calls this directly

Calls 11

closeMethod · 0.95
nextOptionMethod · 0.95
prevOptionMethod · 0.95
getKeyBindingsManagerFunction · 0.90
onSearchChangeMethod · 0.80
onOptionChangeMethod · 0.65
focusMethod · 0.65
setStateMethod · 0.45
removeEventListenerMethod · 0.45
addEventListenerMethod · 0.45

Tested by

no test coverage detected