import * as React from "react"; import styled, { createGlobalStyle } from "styled-components"; import { Alignment, Button, Classes, Menu, MenuItem } from "@blueprintjs/core"; import { IconName, IconNames } from "@blueprintjs/icons"; import { ItemListRenderer, ItemRenderer, Select } from "@blueprintjs/select"; import BaseControl, { ControlProps } from "./BaseControl"; import TooltipComponent from "components/ads/Tooltip"; const IconSelectContainerStyles = createGlobalStyle<{ targetWidth: number | undefined; }>` .bp3-select-popover { width: ${({ targetWidth }) => targetWidth}px; .bp3-input-group { margin: 5px !important; } } `; const StyledButton = styled(Button)` box-shadow: none !important; border: none !important; border-radius: 0; background-color: #ffffff !important; > span.bp3-icon-caret-down { color: rgb(169, 167, 167); } `; const StyledMenu = styled(Menu)` display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(50px, auto); gap: 8px; max-height: 170px !important; padding-left: 5px !important; padding-right: 5px !important; &::-webkit-scrollbar { width: 8px; background-color: #eeeeee; } &::-webkit-scrollbar-thumb { border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); background-color: #939090; } `; const StyledMenuItem = styled(MenuItem)` flex-direction: column; align-items: center; padding: 13px 5px; &:active, &:hover, &.bp3-active { background-color: #eeeeee !important; } > span.bp3-icon { margin-right: 0; color: #939090 !important; } > div { width: 100%; text-align: center; color: #939090 !important; } `; export interface IconSelectControlProps extends ControlProps { propertyValue?: IconName; } export interface IconSelectControlState { popoverTargetWidth: number | undefined; } const NONE = "(none)"; type IconType = IconName | typeof NONE; const ICON_NAMES = Object.keys(IconNames).map( (name: string) => IconNames[name as keyof typeof IconNames], ); ICON_NAMES.push(NONE); const TypedSelect = Select.ofType(); class IconSelectControl extends BaseControl< IconSelectControlProps, IconSelectControlState > { private iconSelectTargetRef: React.RefObject; private timer?: number; constructor(props: IconSelectControlProps) { super(props); this.iconSelectTargetRef = React.createRef(); this.state = { popoverTargetWidth: 0 }; } componentDidMount() { this.timer = setTimeout(() => { const iconSelectTargetElement = this.iconSelectTargetRef.current; console.log( `target width: => `, iconSelectTargetElement?.getBoundingClientRect().width, ); this.setState((prevState: IconSelectControlState) => { return { ...prevState, popoverTargetWidth: iconSelectTargetElement?.getBoundingClientRect() .width, }; }); }, 0); } componentWillUnmount() { if (this.timer) { clearTimeout(this.timer); } } public render() { const { propertyValue: iconName } = this.props; const { popoverTargetWidth } = this.state; return ( <> } onItemSelect={this.handleIconChange} popoverProps={{ minimal: true }} > ); } private renderMenu: ItemListRenderer = ({ items, itemsParentRef, renderItem, }) => { const renderedItems = items.map(renderItem).filter((item) => item != null); return {renderedItems}; }; private renderIconItem: ItemRenderer = ( icon, { handleClick, modifiers }, ) => { if (!modifiers.matchesPredicate) { return null; } return ( ); }; private filterIconName = ( query: string, iconName: IconName | typeof NONE, ) => { if (iconName === NONE || query === "") { return true; } return iconName.toLowerCase().indexOf(query.toLowerCase()) >= 0; }; private handleIconChange = (icon: IconType) => this.updateProperty( this.props.propertyName, icon === NONE ? undefined : icon, ); static getControlType() { return "ICON_SELECT"; } } export default IconSelectControl;