import * as React from "react"; import styled, { createGlobalStyle } from "styled-components"; import { Alignment, Button, Icon, Menu, MenuItem as BlueprintMenuItem, Classes as BlueprintClasses, } from "@blueprintjs/core"; import { Classes, Popover2 } from "@blueprintjs/popover2"; import type { IconName } from "@blueprintjs/icons"; import tinycolor from "tinycolor2"; import { darkenActive, darkenHover } from "constants/DefaultTheme"; import type { ButtonPlacement, ButtonVariant } from "components/constants"; import { ButtonVariantTypes } from "components/constants"; import { getCustomBackgroundColor, getCustomBorderColor, getCustomHoverColor, getComplementaryGrayscaleColor, getCustomJustifyContent, getAlignText, WidgetContainerDiff, lightenColor, } from "widgets/WidgetUtils"; import type { RenderMode } from "constants/WidgetConstants"; import { DragContainer } from "widgets/ButtonWidget/component/DragContainer"; import { THEMEING_TEXT_SIZES } from "constants/ThemeConstants"; import type { MenuButtonComponentProps, MenuItem, PopoverContentProps, } from "../constants"; import type { ThemeProp } from "WidgetProvider/constants"; const PopoverStyles = createGlobalStyle<{ parentWidth: number; menuDropDownWidth: number; id: string; borderRadius: string; }>` .menu-button-popover, .${BlueprintClasses.MINIMAL}.menu-button-popover.${ Classes.POPOVER2 } { background: none; box-shadow: 0 6px 20px 0px rgba(0, 0, 0, 0.15) !important; margin-top: 8px !important; margin-bottom: 8px !important; border-radius: ${({ borderRadius }) => borderRadius >= THEMEING_TEXT_SIZES.lg ? `0.375rem` : borderRadius}; overflow-y: auto; max-height: 384px; } .menu-button-popover .${BlueprintClasses.MENU_ITEM} { padding: 9px 12px; border-radius: 0; } .menu-button-popover-target { height: 100%; } ${({ id, menuDropDownWidth, parentWidth }) => ` .menu-button-width-${id} { max-width: ${ menuDropDownWidth > parentWidth ? `${menuDropDownWidth}px` : `${parentWidth}px` } !important; min-width: ${ parentWidth > menuDropDownWidth ? parentWidth : menuDropDownWidth }px !important; } `} `; export interface BaseStyleProps { backgroundColor?: string; borderRadius?: string; boxShadow?: string; buttonColor?: string; buttonVariant?: ButtonVariant; isCompact?: boolean; textColor?: string; placement?: ButtonPlacement; } const BaseButton = styled(Button)` height: 100%; background-image: none !important; font-weight: ${(props) => props.theme.fontWeights[2]}; outline: none; padding: 0px 10px; overflow: hidden; border: 1.2px solid #ebebeb; border-radius: 0; box-shadow: none !important; ${({ buttonColor, buttonVariant, theme }) => ` background: ${ getCustomBackgroundColor(buttonVariant, buttonColor) !== "none" ? getCustomBackgroundColor(buttonVariant, buttonColor) : buttonVariant === ButtonVariantTypes.PRIMARY ? theme.colors.button.primary.primary.bgColor : "none" } !important; &:hover, &:active, &:focus { background: ${ getCustomHoverColor(theme, buttonVariant, buttonColor) !== "none" ? getCustomHoverColor(theme, buttonVariant, buttonColor) : buttonVariant === ButtonVariantTypes.SECONDARY ? theme.colors.button.primary.secondary.hoverColor : buttonVariant === ButtonVariantTypes.TERTIARY ? theme.colors.button.primary.tertiary.hoverColor : theme.colors.button.primary.primary.hoverColor } !important; } &:disabled { border: ${ buttonVariant === ButtonVariantTypes.SECONDARY ? "1px solid var(--wds-color-border-disabled)" : "none" } !important; background: ${ buttonVariant !== ButtonVariantTypes.TERTIARY ? "var(--wds-color-bg-disabled)" : "transparent" } !important; color: var(--wds-color-text-disabled) !important; span { color: var(--wds-color-text-disabled) !important; } } border: ${ getCustomBorderColor(buttonVariant, buttonColor) !== "none" ? `1px solid ${getCustomBorderColor(buttonVariant, buttonColor)}` : buttonVariant === ButtonVariantTypes.SECONDARY ? `1px solid ${theme.colors.button.primary.secondary.borderColor}` : "none" } !important; & > span { display: inline-block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; line-height: normal; color: ${ buttonVariant === ButtonVariantTypes.PRIMARY ? getComplementaryGrayscaleColor(buttonColor) : getCustomBackgroundColor( ButtonVariantTypes.PRIMARY, buttonColor, ) !== "none" ? getCustomBackgroundColor(ButtonVariantTypes.PRIMARY, buttonColor) : `${theme.colors.button.primary.secondary.textColor}` } !important; } `} border-radius: ${({ borderRadius }) => borderRadius}; box-shadow: ${({ boxShadow }) => boxShadow} !important; ${({ placement }) => placement ? ` justify-content: ${getCustomJustifyContent(placement)}; & > span.bp3-button-text { flex: unset !important; } ` : ""} `; const BaseMenuItem = styled(BlueprintMenuItem)` font-family: var(--wds-font-family); ${({ backgroundColor, theme }) => backgroundColor ? ` background-color: ${backgroundColor} !important; &:hover { background-color: ${darkenHover(backgroundColor)} !important; } &:active { background-color: ${darkenActive(backgroundColor)} !important; } ` : ` background: none !important &:hover { background-color: ${tinycolor( theme.colors.button.primary.primary.textColor, ) .darken() .toString()} !important; } &:active { background-color: ${tinycolor( theme.colors.button.primary.primary.textColor, ) .darken() .toString()} !important; } `} ${({ textColor }) => textColor && ` color: ${textColor} !important; `} ${({ isCompact }) => isCompact && ` padding-top: 3px !important; padding-bottom: 3px !important; font-size: 12px; `} `; const StyledMenu = styled(Menu)<{ backgroundColor?: string; }>` padding: 0; min-width: 0px; overflow: hidden; ${BlueprintClasses.MENU_ITEM}:hover { background-color: ${({ backgroundColor }) => lightenColor(backgroundColor)}; } `; function PopoverContent(props: PopoverContentProps) { const { backgroundColor, getVisibleItems, isCompact, onItemClicked } = props; const visibleItems = getVisibleItems(); if (!visibleItems?.length) { return ; } else { const listItems = visibleItems.map((item: MenuItem, index: number) => { const { backgroundColor, iconAlign, iconColor, iconName, id, isDisabled, label, onClick, textColor, } = item; return ( ) : null } isCompact={isCompact} key={id} labelElement={ iconAlign === Alignment.RIGHT && iconName ? ( ) : null } onClick={() => onItemClicked(onClick, index)} text={label} textColor={textColor} /> ); }); return ( {listItems} ); } } export interface PopoverTargetButtonProps { borderRadius?: string; boxShadow?: string; buttonColor?: string; buttonVariant?: ButtonVariant; iconName?: IconName; iconAlign?: Alignment; shouldFitContent: boolean; isDisabled?: boolean; label?: string; placement?: ButtonPlacement; renderMode?: RenderMode; maxWidth?: number; minWidth?: number; minHeight?: number; } function PopoverTargetButton(props: PopoverTargetButtonProps) { const { borderRadius, boxShadow, buttonColor, buttonVariant, iconAlign, iconName, isDisabled, label, maxWidth, minHeight, minWidth, placement, renderMode, shouldFitContent, } = props; const isRightAlign = iconAlign === Alignment.RIGHT; return ( ); } function MenuButtonComponent(props: MenuButtonComponentProps) { const { borderRadius, boxShadow, configureMenuItems, getVisibleItems, iconAlign, iconName, isCompact, isDisabled, label, maxWidth, menuColor, menuDropDownWidth, menuItems, menuItemsSource, menuVariant, minHeight, minWidth, onItemClicked, placement, renderMode, shouldFitContent, sourceData, widgetId, width, } = props; return ( <> } disabled={isDisabled} fill minimal placement="bottom-end" popoverClassName={`menu-button-popover menu-button-width-${widgetId}`} > ); } export default MenuButtonComponent;