import React, { Component, ReactNode } from "react"; import styled from "styled-components"; import { MenuItem, Menu, ControlGroup, InputGroup, IMenuProps, } from "@blueprintjs/core"; import { BaseButton } from "components/designSystems/blueprint/ButtonComponent"; import { ItemRenderer, Select, ItemListRenderer, IItemListRendererProps, } from "@blueprintjs/select"; import { DropdownOption } from "widgets/DropdownWidget"; import { WrappedFieldInputProps } from "redux-form"; interface ButtonWrapperProps { width?: string; } interface MenuProps { width?: string; } type MenuComponentProps = IMenuProps & MenuProps; const Dropdown = Select.ofType(); const StyledDropdown = styled(Dropdown)``; const StyledButtonWrapper = styled.div` width: ${(props) => props.width || "100%"}; `; const StyledMenu = styled(Menu)` min-width: ${(props) => props.width || "100%"}; border-radius: 0; `; const StyledMenuItem = styled(MenuItem)` border-radius: 0; &&&.bp3-active { background: ${(props) => props.theme.colors.propertyPane.activeButtonText}; } `; class DropdownComponent extends Component { componentDidMount() { const { input, selected } = this.props; input && input.onChange(selected?.value); } private newItemTextInput: HTMLInputElement | null = null; private setNewItemTextInput = (element: HTMLInputElement | null) => { this.newItemTextInput = element; }; public state = { isEditing: false, }; showTextBox = (): void => { this.setState({ isEditing: true, }); }; handleAddItem = (): void => { this.props.addItem && this.newItemTextInput && this.props.addItem.addItemHandler(this.newItemTextInput.value); this.setState({ isEditing: false, }); }; renderItemList: ItemListRenderer = ( props: IItemListRendererProps, ) => { const { items, renderItem } = props; const { addItem, width } = this.props; const renderItems = items.map(renderItem).filter(Boolean); const displayMode = ( ); const editMode = ( ); return ( {renderItems} {addItem && (!this.state.isEditing ? displayMode : editMode)} ); }; searchItem = (query: string, option: DropdownOption): boolean => { return ( option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 || option.value.toLowerCase().indexOf(query.toLowerCase()) > -1 || (!!option.label && option.label.toLowerCase().indexOf(query.toLowerCase()) > -1) ); }; onItemSelect = (item: DropdownOption): void => { this.props.input?.onChange(item.value); this.props.selectHandler(item.value); }; renderItem: ItemRenderer = ( option: DropdownOption, { handleClick, modifiers }, ) => { if (!modifiers.matchesPredicate) { return null; } return ( ); }; getSelectedDisplayText = () => { if (this.props.selected) { const selectedValue = this.props.selected.value; const item: DropdownOption | undefined = this.props.options.find( (option) => option.value === selectedValue, ); return item && item.label; } return ""; }; render() { const { autocomplete, input, options, selected, width } = this.props; return ( } onItemSelect={this.onItemSelect} popoverProps={{ minimal: true }} {...input} > {this.props.toggle || ( )} ); } } export interface DropdownComponentProps { hasLabel?: boolean; options: DropdownOption[]; selectHandler: (selectedValue: string) => void; selected?: DropdownOption; multiselectDisplayType?: "TAGS" | "CHECKBOXES"; checked?: boolean; multi?: boolean; autocomplete?: boolean; addItem?: { displayText: string; addItemHandler: (name: string) => void; }; toggle?: ReactNode; input?: WrappedFieldInputProps; width?: string; } export default DropdownComponent;