feat: Action Widgets Reskinning - Button, Button Group, Icon Button, Menu Button (#17093)
* feat: Change default button height and fixes in disabled styles * fix: Disabled background color on tertiary button * feat: Hover color logic for buttons * feat: Button group reskinning * feat: Icon Button Reskinning * feat: Menu button reskinning * test: Update getCustomHoverColor tests * feat: Revert default rows for button, button group, and menu button to 4 * fix: remove unused vars
This commit is contained in:
parent
138d4db31c
commit
762df626dc
|
|
@ -20,7 +20,6 @@ import {
|
|||
} from "components/constants";
|
||||
import { ThemeProp } from "components/ads/common";
|
||||
import styled, { createGlobalStyle } from "styled-components";
|
||||
import { Colors } from "constants/Colors";
|
||||
import {
|
||||
getCustomBackgroundColor,
|
||||
getCustomBorderColor,
|
||||
|
|
@ -208,7 +207,6 @@ const StyledButton = styled.button<ThemeProp & ButtonStyleProps>`
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
border: ${
|
||||
getCustomBorderColor(buttonVariant, buttonColor) !== "none"
|
||||
? `1px solid ${getCustomBorderColor(buttonVariant, buttonColor)}`
|
||||
|
|
@ -228,10 +226,13 @@ const StyledButton = styled.button<ThemeProp & ButtonStyleProps>`
|
|||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
border: 1px solid ${Colors.ALTO2} !important;
|
||||
background: ${theme.colors.button.disabled.bgColor} !important;
|
||||
border: ${buttonVariant === ButtonVariantTypes.SECONDARY &&
|
||||
"1px solid var(--wds-color-border-disabled)"} !important;
|
||||
background: ${buttonVariant !== ButtonVariantTypes.TERTIARY &&
|
||||
"var(--wds-color-bg-disabled)"} !important;
|
||||
|
||||
span {
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
color: var(--wds-color-text-disabled) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -548,7 +549,7 @@ class ButtonGroupComponent extends React.Component<
|
|||
{items.map((button) => {
|
||||
const isLoading = button.id === loadedBtnId;
|
||||
const isButtonDisabled =
|
||||
button.isDisabled || isDisabled || !!loadedBtnId;
|
||||
button.isDisabled || isDisabled || !!loadedBtnId || isLoading;
|
||||
if (button.buttonType === "MENU" && !isButtonDisabled) {
|
||||
const { menuItems } = button;
|
||||
|
||||
|
|
@ -600,7 +601,7 @@ class ButtonGroupComponent extends React.Component<
|
|||
placement={button.placement}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Spinner size={20} />
|
||||
<Spinner size={18} />
|
||||
) : (
|
||||
<>
|
||||
{button.iconName && <Icon icon={button.iconName} />}
|
||||
|
|
@ -646,7 +647,7 @@ class ButtonGroupComponent extends React.Component<
|
|||
placement={button.placement}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Spinner size={20} />
|
||||
<Spinner size={18} />
|
||||
) : (
|
||||
<>
|
||||
{button.iconName && <Icon icon={button.iconName} />}
|
||||
|
|
|
|||
|
|
@ -115,14 +115,15 @@ ${({ buttonColor, buttonVariant, theme }) => `
|
|||
|
||||
&:disabled, &.${Classes.DISABLED} {
|
||||
cursor: not-allowed;
|
||||
background-color: ${Colors.GREY_1} !important;
|
||||
color: ${Colors.GREY_9} !important;
|
||||
background-color: ${buttonVariant !== ButtonVariantTypes.TERTIARY &&
|
||||
"var(--wds-color-bg-disabled)"} !important;
|
||||
color: var(--wds-color-text-disabled) !important;
|
||||
box-shadow: none !important;
|
||||
pointer-events: none;
|
||||
border-color: ${Colors.GREY_1} !important;
|
||||
border-color: var(--wds-color-border-disabled) !important;
|
||||
|
||||
> span {
|
||||
color: ${Colors.GREY_9} !important;
|
||||
color: var(--wds-color-text-disabled) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ const IconButtonContainer = styled.div<IconButtonContainerProps>`
|
|||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
${({ renderMode }) =>
|
||||
renderMode === RenderModes.CANVAS &&
|
||||
|
|
@ -155,17 +156,30 @@ export const StyledButton = styled((props) => (
|
|||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
background: ${
|
||||
buttonVariant !== ButtonVariantTypes.TERTIARY
|
||||
? "var(--wds-color-bg-disabled)"
|
||||
: "transparent"
|
||||
} !important;
|
||||
color: var(--wds-color-text-disabled) !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&&:disabled {
|
||||
background-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||
border-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
> span {
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,11 +122,20 @@ const BaseButton = styled(Button)<ThemeProp & BaseStyleProps>`
|
|||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
border-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||
> span {
|
||||
color: ${theme.colors.button.disabled.textColor} !important;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,6 +181,8 @@ const BaseButton = styled(Button)<ThemeProp & BaseStyleProps>`
|
|||
`;
|
||||
|
||||
const BaseMenuItem = styled(MenuItem)<ThemeProp & BaseStyleProps>`
|
||||
font-family: var(--wds-font-family);
|
||||
|
||||
${({ backgroundColor, theme }) =>
|
||||
backgroundColor
|
||||
? `
|
||||
|
|
|
|||
|
|
@ -98,22 +98,22 @@ describe("validate widget utils button style functions", () => {
|
|||
// validate getCustomHoverColor function
|
||||
it("getCustomHoverColor - validate empty or undefined background color or variant", () => {
|
||||
// background color and variant is both are undefined
|
||||
const expected = "#e6e6e6";
|
||||
const expected = "hsl(0, 0%, 95%)";
|
||||
const result = getCustomHoverColor(theme);
|
||||
expect(result).toStrictEqual(expected);
|
||||
|
||||
// variant is undefined
|
||||
const backgroundColor = "#03b365";
|
||||
const expected1 = "#028149";
|
||||
const expected1 = "hsl(153, 97%, 31%)";
|
||||
const result1 = getCustomHoverColor(theme, undefined, backgroundColor);
|
||||
expect(result1).toStrictEqual(expected1);
|
||||
});
|
||||
|
||||
// validate getCustomHoverColor function
|
||||
it("getCustomHoverColor - validate hover color for different variant", () => {
|
||||
const backgroundColor = "#03b365";
|
||||
const backgroundColor = "hsl(153, 97% ,36%)";
|
||||
// variant : PRIMARY
|
||||
const expected1 = "#028149";
|
||||
const expected1 = "hsl(153, 97%, 31%)";
|
||||
const result1 = getCustomHoverColor(
|
||||
theme,
|
||||
ButtonVariantTypes.PRIMARY,
|
||||
|
|
@ -123,12 +123,12 @@ describe("validate widget utils button style functions", () => {
|
|||
expect(result1).toStrictEqual(expected1);
|
||||
|
||||
// variant : PRIMARY without background
|
||||
const expected2 = "#e6e6e6";
|
||||
const expected2 = "hsl(0, 0%, 95%)";
|
||||
const result2 = getCustomHoverColor(theme, ButtonVariantTypes.PRIMARY);
|
||||
expect(result2).toStrictEqual(expected2);
|
||||
|
||||
// variant : SECONDARY
|
||||
const expected3 = "#dcfeef";
|
||||
const expected3 = "rgba(3, 181, 101, 0.1)";
|
||||
const result3 = getCustomHoverColor(
|
||||
theme,
|
||||
ButtonVariantTypes.SECONDARY,
|
||||
|
|
@ -138,12 +138,12 @@ describe("validate widget utils button style functions", () => {
|
|||
expect(result3).toStrictEqual(expected3);
|
||||
|
||||
// variant : SECONDARY without background
|
||||
const expected4 = "#ededed";
|
||||
const expected4 = "rgba(255, 255, 255, 0.1)";
|
||||
const result4 = getCustomHoverColor(theme, ButtonVariantTypes.SECONDARY);
|
||||
expect(result4).toStrictEqual(expected4);
|
||||
|
||||
// variant : TERTIARY
|
||||
const expected5 = "#dcfeef";
|
||||
const expected5 = "rgba(3, 181, 101, 0.1)";
|
||||
const result5 = getCustomHoverColor(
|
||||
theme,
|
||||
ButtonVariantTypes.TERTIARY,
|
||||
|
|
@ -152,7 +152,7 @@ describe("validate widget utils button style functions", () => {
|
|||
expect(result5).toStrictEqual(expected5);
|
||||
|
||||
// variant : TERTIARY without background
|
||||
const expected6 = "#ededed";
|
||||
const expected6 = "rgba(255, 255, 255, 0.1)";
|
||||
const result6 = getCustomHoverColor(theme, ButtonVariantTypes.TERTIARY);
|
||||
expect(result6).toStrictEqual(expected6);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -131,21 +131,63 @@ export const getCustomHoverColor = (
|
|||
switch (buttonVariant) {
|
||||
case ButtonVariantTypes.SECONDARY:
|
||||
return backgroundColor
|
||||
? lightenColor(backgroundColor)
|
||||
? calulateHoverColor(backgroundColor, true)
|
||||
: theme.colors.button.primary.secondary.hoverColor;
|
||||
|
||||
case ButtonVariantTypes.TERTIARY:
|
||||
return backgroundColor
|
||||
? lightenColor(backgroundColor)
|
||||
? calulateHoverColor(backgroundColor, true)
|
||||
: theme.colors.button.primary.tertiary.hoverColor;
|
||||
|
||||
default:
|
||||
return backgroundColor
|
||||
? darkenColor(backgroundColor, 10)
|
||||
? calulateHoverColor(backgroundColor, false)
|
||||
: theme.colors.button.primary.primary.hoverColor;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate Hover Color using the logic
|
||||
* https://www.notion.so/appsmith/Widget-hover-colors-165e54b304ca4e83a355e4e14d7aa3cb
|
||||
*
|
||||
* In case of transparent backgrounds (secondary or tertiary button varients)
|
||||
* 1. Find out the button color
|
||||
* 2. Calculate hover color by setting the button color to 10% transparency
|
||||
* 3. Add the calculated color to the background of the button
|
||||
*
|
||||
* In case of non transparent backgrounds (primary button varient), using the HSL color modal,
|
||||
* 1. If lightness > 35, decrease the lightness by 5 on hover
|
||||
* 2. If lightness <= 35, increase the lightness by 5 on hover
|
||||
*
|
||||
* @param backgroundColor A color string
|
||||
* @param hasTransparentBackground Boolean to represent if the button has transparent background
|
||||
*
|
||||
* @returns An RGB string (in case of transparent backgrounds) or a HSL string (in case of solid backgrounds).
|
||||
*/
|
||||
export const calulateHoverColor = (
|
||||
backgroundColor: string,
|
||||
hasTransparentBackground?: boolean,
|
||||
) => {
|
||||
// For transparent backgrounds
|
||||
if (hasTransparentBackground) {
|
||||
return tinycolor(backgroundColor)
|
||||
.setAlpha(0.1)
|
||||
.toRgbString();
|
||||
}
|
||||
|
||||
// For non-transparent backgrounds, using the HSL color modal
|
||||
const backgroundColorHsl = tinycolor(backgroundColor).toHsl();
|
||||
|
||||
// Check the lightness and modify accordingly
|
||||
if (backgroundColorHsl.l > 0.35) {
|
||||
backgroundColorHsl.l -= 0.05;
|
||||
} else {
|
||||
backgroundColorHsl.l += 0.05;
|
||||
}
|
||||
|
||||
return tinycolor(backgroundColorHsl).toHslString();
|
||||
};
|
||||
|
||||
export const getCustomBackgroundColor = (
|
||||
buttonVariant?: ButtonVariant,
|
||||
backgroundColor?: string,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user