]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/common/searchable-select.tsx
component classes v2
[lemmy-ui.git] / src / shared / components / common / searchable-select.tsx
index a5a75f2328507927fffc91725affc808f80efbba..1d98de3d625d75687b5b09bc1e9d707bb60632c1 100644 (file)
@@ -38,12 +38,38 @@ function handleSearch(i: SearchableSelect, e: ChangeEvent<HTMLInputElement>) {
   });
 }
 
+function focusSearch(i: SearchableSelect) {
+  if (i.toggleButtonRef.current?.ariaExpanded !== "true") {
+    i.searchInputRef.current?.focus();
+
+    if (i.props.onSearch) {
+      i.props.onSearch("");
+    }
+
+    i.setState({
+      searchText: "",
+    });
+  }
+}
+
+function handleChange({ option, i }: { option: Choice; i: SearchableSelect }) {
+  const { onChange, value } = i.props;
+
+  if (option.value !== value?.toString()) {
+    if (onChange) {
+      onChange(option);
+    }
+
+    i.setState({ searchText: "" });
+  }
+}
+
 export class SearchableSelect extends Component<
   SearchableSelectProps,
   SearchableSelectState
 > {
-  private searchInputRef: RefObject<HTMLInputElement> = createRef();
-  private toggleButtonRef: RefObject<HTMLButtonElement> = createRef();
+  searchInputRef: RefObject<HTMLInputElement> = createRef();
+  toggleButtonRef: RefObject<HTMLButtonElement> = createRef();
   private loadingEllipsesInterval?: NodeJS.Timer = undefined;
 
   state: SearchableSelectState = {
@@ -55,9 +81,6 @@ export class SearchableSelect extends Component<
   constructor(props: SearchableSelectProps, context: any) {
     super(props, context);
 
-    this.handleChange = this.handleChange.bind(this);
-    this.focusSearch = this.focusSearch.bind(this);
-
     if (props.value) {
       let selectedIndex = props.options.findIndex(
         ({ value }) => value === props.value?.toString()
@@ -79,14 +102,15 @@ export class SearchableSelect extends Component<
     const { searchText, selectedIndex, loadingEllipses } = this.state;
 
     return (
-      <div className="dropdown">
+      <div className="searchable-select dropdown">
         <button
           id={id}
           type="button"
-          className="custom-select text-start"
+          className="form-select d-inline-block text-start"
           aria-haspopup="listbox"
           data-bs-toggle="dropdown"
-          onClick={this.focusSearch}
+          onClick={linkEvent(this, focusSearch)}
+          ref={this.toggleButtonRef}
         >
           {loading
             ? `${i18n.t("loading")}${loadingEllipses}`
@@ -127,7 +151,7 @@ export class SearchableSelect extends Component<
                 aria-disabled={option.disabled}
                 disabled={option.disabled}
                 aria-selected={selectedIndex === index}
-                onClick={() => this.handleChange(option)}
+                onClick={linkEvent({ i: this, option }, handleChange)}
                 type="button"
               >
                 {option.label}
@@ -138,20 +162,6 @@ export class SearchableSelect extends Component<
     );
   }
 
-  focusSearch() {
-    if (this.toggleButtonRef.current?.ariaExpanded !== "true") {
-      this.searchInputRef.current?.focus();
-
-      if (this.props.onSearch) {
-        this.props.onSearch("");
-      }
-
-      this.setState({
-        searchText: "",
-      });
-    }
-  }
-
   static getDerivedStateFromProps({
     value,
     options,
@@ -189,16 +199,4 @@ export class SearchableSelect extends Component<
       clearInterval(this.loadingEllipsesInterval);
     }
   }
-
-  handleChange(option: Choice) {
-    const { onChange, value } = this.props;
-
-    if (option.value !== value?.toString()) {
-      if (onChange) {
-        onChange(option);
-      }
-
-      this.setState({ searchText: "" });
-    }
-  }
 }