Feat: Style customisation in the button widget (#6052)
Added multiple style props to the button widget: - Button styles - The background colour can change with a hex code - elevation (box-shadow & colour) - There are button variant contained (solid button), outlined (only borders), text (text buttons) - Button can have an end icon or start icon
This commit is contained in:
parent
163192d851
commit
cb4242e7e5
|
|
@ -19,12 +19,20 @@ describe("Button Widget Functionality", function() {
|
||||||
|
|
||||||
it("Button-Style Validation", function() {
|
it("Button-Style Validation", function() {
|
||||||
//Changing the style of the button from the property pane and verify it's color.
|
//Changing the style of the button from the property pane and verify it's color.
|
||||||
|
// Change to Warning button sytle
|
||||||
|
cy.changeButtonStyle(2, "rgb(254, 184, 17)", "rgba(0, 0, 0, 0)");
|
||||||
|
cy.get(publishPage.backToEditor).click({ force: true });
|
||||||
|
cy.openPropertyPane("buttonwidget");
|
||||||
|
// Change to Info button sytle
|
||||||
|
cy.changeButtonStyle(4, "rgb(102, 152, 255)", "rgba(0, 0, 0, 0)");
|
||||||
|
cy.get(publishPage.backToEditor).click({ force: true });
|
||||||
|
cy.openPropertyPane("buttonwidget");
|
||||||
// Change to Secondary button sytle
|
// Change to Secondary button sytle
|
||||||
cy.changeButtonStyle(2, "rgba(0, 0, 0, 0)", "rgba(0, 0, 0, 0)");
|
cy.changeButtonStyle(5, "rgb(133, 130, 130)", "rgba(0, 0, 0, 0)");
|
||||||
cy.get(publishPage.backToEditor).click({ force: true });
|
cy.get(publishPage.backToEditor).click({ force: true });
|
||||||
// Change to Danger button sytle
|
// Change to Danger button sytle
|
||||||
cy.openPropertyPane("buttonwidget");
|
cy.openPropertyPane("buttonwidget");
|
||||||
cy.changeButtonStyle(3, "rgb(179, 3, 56)", "rgb(139, 2, 43)");
|
cy.changeButtonStyle(3, "rgb(242, 43, 43)", "rgb(139, 2, 43)");
|
||||||
cy.get(publishPage.backToEditor).click({ force: true });
|
cy.get(publishPage.backToEditor).click({ force: true });
|
||||||
// Change to Primary button sytle
|
// Change to Primary button sytle
|
||||||
cy.openPropertyPane("buttonwidget");
|
cy.openPropertyPane("buttonwidget");
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@
|
||||||
"styled-components": "^5.2.0",
|
"styled-components": "^5.2.0",
|
||||||
"styled-system": "^5.1.5",
|
"styled-system": "^5.1.5",
|
||||||
"tern": "^0.21.0",
|
"tern": "^0.21.0",
|
||||||
"tinycolor2": "^1.4.1",
|
"tinycolor2": "^1.4.2",
|
||||||
"toposort": "^2.0.2",
|
"toposort": "^2.0.2",
|
||||||
"ts-loader": "^6.0.4",
|
"ts-loader": "^6.0.4",
|
||||||
"tslib": "^2.1.0",
|
"tslib": "^2.1.0",
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,8 @@ class FilePickerComponent extends React.Component<
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<BaseButton
|
<BaseButton
|
||||||
accent="primary"
|
buttonStyle="PRIMARY"
|
||||||
disabled={this.props.isDisabled}
|
disabled={this.props.isDisabled}
|
||||||
filled
|
|
||||||
loading={this.props.isLoading}
|
loading={this.props.isLoading}
|
||||||
onClick={this.openModal}
|
onClick={this.openModal}
|
||||||
text={label}
|
text={label}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@ import { IconName } from "@blueprintjs/icons";
|
||||||
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
|
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
|
||||||
import { ThemeProp } from "components/ads/common";
|
import { ThemeProp } from "components/ads/common";
|
||||||
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
||||||
|
import {
|
||||||
|
ButtonBorderRadius,
|
||||||
|
ButtonBorderRadiusTypes,
|
||||||
|
} from "components/propertyControls/BorderRadiusOptionsControl";
|
||||||
|
import {
|
||||||
|
ButtonBoxShadow,
|
||||||
|
ButtonBoxShadowTypes,
|
||||||
|
} from "components/propertyControls/BoxShadowOptionsControl";
|
||||||
|
|
||||||
const IconButtonContainer = styled.div`
|
const IconButtonContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -176,23 +184,6 @@ export enum ButtonVariantTypes {
|
||||||
}
|
}
|
||||||
export type ButtonVariant = keyof typeof ButtonVariantTypes;
|
export type ButtonVariant = keyof typeof ButtonVariantTypes;
|
||||||
|
|
||||||
export enum ButtonBorderRadiusTypes {
|
|
||||||
SHARP = "SHARP",
|
|
||||||
ROUNDED = "ROUNDED",
|
|
||||||
CIRCLE = "CIRCLE",
|
|
||||||
}
|
|
||||||
export type ButtonBorderRadius = keyof typeof ButtonBorderRadiusTypes;
|
|
||||||
|
|
||||||
export enum ButtonBoxShadowTypes {
|
|
||||||
NONE = "NONE",
|
|
||||||
VARIANT1 = "VARIANT1",
|
|
||||||
VARIANT2 = "VARIANT2",
|
|
||||||
VARIANT3 = "VARIANT3",
|
|
||||||
VARIANT4 = "VARIANT4",
|
|
||||||
VARIANT5 = "VARIANT5",
|
|
||||||
}
|
|
||||||
export type ButtonBoxShadow = keyof typeof ButtonBoxShadowTypes;
|
|
||||||
|
|
||||||
export interface IconButtonComponentProps extends ComponentProps {
|
export interface IconButtonComponentProps extends ComponentProps {
|
||||||
iconName?: IconName;
|
iconName?: IconName;
|
||||||
buttonStyle: ButtonStyle;
|
buttonStyle: ButtonStyle;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState } from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import tinycolor from "tinycolor2";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IButtonProps,
|
IButtonProps,
|
||||||
MaybeElement,
|
MaybeElement,
|
||||||
Button,
|
Button,
|
||||||
IconName,
|
Alignment,
|
||||||
Position,
|
Position,
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
|
import { IconName } from "@blueprintjs/icons";
|
||||||
|
|
||||||
import Tooltip from "components/ads/Tooltip";
|
import Tooltip from "components/ads/Tooltip";
|
||||||
import styled, { css } from "styled-components";
|
import { Theme } from "constants/DefaultTheme";
|
||||||
import { ButtonStyle } from "widgets/ButtonWidget";
|
|
||||||
import { Theme, darkenHover, darkenActive } from "constants/DefaultTheme";
|
|
||||||
import _ from "lodash";
|
|
||||||
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
|
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
|
||||||
import { useScript, ScriptStatus } from "utils/hooks/useScript";
|
import { useScript, ScriptStatus } from "utils/hooks/useScript";
|
||||||
import {
|
import {
|
||||||
|
|
@ -18,38 +20,126 @@ import {
|
||||||
GOOGLE_RECAPTCHA_DOMAIN_ERROR,
|
GOOGLE_RECAPTCHA_DOMAIN_ERROR,
|
||||||
createMessage,
|
createMessage,
|
||||||
} from "constants/messages";
|
} from "constants/messages";
|
||||||
import { Variant } from "components/ads/common";
|
import { ThemeProp, Variant } from "components/ads/common";
|
||||||
import { Toaster } from "components/ads/Toast";
|
import { Toaster } from "components/ads/Toast";
|
||||||
import ReCAPTCHA from "react-google-recaptcha";
|
import ReCAPTCHA from "react-google-recaptcha";
|
||||||
|
import {
|
||||||
|
ButtonBoxShadow,
|
||||||
|
ButtonBoxShadowTypes,
|
||||||
|
} from "components/propertyControls/BoxShadowOptionsControl";
|
||||||
|
import {
|
||||||
|
ButtonBorderRadius,
|
||||||
|
ButtonBorderRadiusTypes,
|
||||||
|
} from "components/propertyControls/BorderRadiusOptionsControl";
|
||||||
|
|
||||||
const getButtonColorStyles = (props: { theme: Theme } & ButtonStyleProps) => {
|
export enum ButtonStyleTypes {
|
||||||
if (props.filled) {
|
PRIMARY = "PRIMARY",
|
||||||
return props.accent === "grey"
|
WARNING = "WARNING",
|
||||||
? props.theme.colors.textOnGreyBG
|
DANGER = "DANGER",
|
||||||
: props.theme.colors.textOnDarkBG;
|
INFO = "INFO",
|
||||||
|
SECONDARY = "SECONDARY",
|
||||||
|
CUSTOM = "CUSTOM",
|
||||||
}
|
}
|
||||||
if (props.accent) {
|
export type ButtonStyle = keyof typeof ButtonStyleTypes;
|
||||||
if (props.accent === "secondary") {
|
|
||||||
return props.theme.colors[AccentColorMap["primary"]];
|
export enum ButtonVariantTypes {
|
||||||
|
SOLID = "SOLID",
|
||||||
|
OUTLINE = "OUTLINE",
|
||||||
|
GHOST = "GHOST",
|
||||||
}
|
}
|
||||||
return props.theme.colors[AccentColorMap[props.accent]];
|
export type ButtonVariant = keyof typeof ButtonVariantTypes;
|
||||||
|
|
||||||
|
const getCustomTextColor = (
|
||||||
|
theme: Theme,
|
||||||
|
backgroundColor?: string,
|
||||||
|
prevButtonStyle?: ButtonStyle,
|
||||||
|
) => {
|
||||||
|
if (!backgroundColor)
|
||||||
|
return theme.colors.button[
|
||||||
|
(prevButtonStyle || ButtonStyleTypes.PRIMARY).toLowerCase()
|
||||||
|
].solid.textColor;
|
||||||
|
const isDark = tinycolor(backgroundColor).isDark();
|
||||||
|
if (isDark) {
|
||||||
|
return theme.colors.button.custom.solid.light.textColor;
|
||||||
|
}
|
||||||
|
return theme.colors.button.custom.solid.dark.textColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCustomHoverColor = (
|
||||||
|
theme: Theme,
|
||||||
|
prevButtonStyle?: ButtonStyle,
|
||||||
|
buttonVariant?: ButtonVariant,
|
||||||
|
backgroundColor?: string,
|
||||||
|
) => {
|
||||||
|
if (!backgroundColor) {
|
||||||
|
return theme.colors.button[
|
||||||
|
(prevButtonStyle || ButtonStyleTypes.PRIMARY).toLowerCase()
|
||||||
|
][(buttonVariant || ButtonVariantTypes.SOLID).toLowerCase()].hoverColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (buttonVariant) {
|
||||||
|
case ButtonVariantTypes.OUTLINE:
|
||||||
|
return backgroundColor
|
||||||
|
? tinycolor(backgroundColor)
|
||||||
|
.lighten(40)
|
||||||
|
.toString()
|
||||||
|
: theme.colors.button.primary.outline.hoverColor;
|
||||||
|
break;
|
||||||
|
case ButtonVariantTypes.GHOST:
|
||||||
|
return backgroundColor
|
||||||
|
? tinycolor(backgroundColor)
|
||||||
|
.lighten(40)
|
||||||
|
.toString()
|
||||||
|
: theme.colors.button.primary.ghost.hoverColor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return backgroundColor
|
||||||
|
? tinycolor(backgroundColor)
|
||||||
|
.darken(10)
|
||||||
|
.toString()
|
||||||
|
: theme.colors.button.primary.solid.hoverColor;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getButtonFillStyles = (props: { theme: Theme } & ButtonStyleProps) => {
|
const getCustomBackgroundColor = (
|
||||||
if (props.filled) {
|
theme: Theme,
|
||||||
return props.accent === "grey"
|
prevButtonStyle?: ButtonStyle,
|
||||||
? props.theme.colors.dropdownIconDarkBg
|
buttonVariant?: ButtonVariant,
|
||||||
: props.theme.colors.textOnDarkBG;
|
backgroundColor?: string,
|
||||||
}
|
) => {
|
||||||
if (props.accent) {
|
return buttonVariant === ButtonVariantTypes.SOLID
|
||||||
if (props.accent === "secondary") {
|
? backgroundColor
|
||||||
return props.theme.colors[AccentColorMap["primary"]];
|
? backgroundColor
|
||||||
}
|
: theme.colors.button[
|
||||||
return props.theme.colors[AccentColorMap[props.accent]];
|
(prevButtonStyle || ButtonStyleTypes.PRIMARY).toLowerCase()
|
||||||
}
|
].solid.bgColor
|
||||||
|
: "none";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCustomBorderColor = (
|
||||||
|
theme: Theme,
|
||||||
|
prevButtonStyle?: ButtonStyle,
|
||||||
|
buttonVariant?: ButtonVariant,
|
||||||
|
backgroundColor?: string,
|
||||||
|
) => {
|
||||||
|
return buttonVariant === ButtonVariantTypes.OUTLINE
|
||||||
|
? backgroundColor
|
||||||
|
? backgroundColor
|
||||||
|
: theme.colors.button[
|
||||||
|
(prevButtonStyle || ButtonStyleTypes.PRIMARY).toLowerCase()
|
||||||
|
].outline.borderColor
|
||||||
|
: "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
const RecaptchaWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
.grecaptcha-badge {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const ToolTipContent = styled.div`
|
const ToolTipContent = styled.div`
|
||||||
max-width: 350px;
|
max-width: 350px;
|
||||||
`;
|
`;
|
||||||
|
|
@ -64,118 +154,257 @@ const ToolTipWrapper = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ButtonColorStyles = css<ButtonStyleProps>`
|
const ButtonContainer = styled.div`
|
||||||
color: ${getButtonColorStyles};
|
display: flex;
|
||||||
svg {
|
align-items: center;
|
||||||
fill: ${getButtonFillStyles};
|
justify-content: center;
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const RecaptchaWrapper = styled.div`
|
|
||||||
position: relative;
|
|
||||||
.grecaptcha-badge {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const AccentColorMap: Record<ButtonStyleName, string> = {
|
|
||||||
primary: "primaryOld",
|
|
||||||
secondary: "secondaryOld",
|
|
||||||
error: "error",
|
|
||||||
grey: "dropdownGreyBg",
|
|
||||||
};
|
|
||||||
|
|
||||||
const ButtonWrapper = styled((props: ButtonStyleProps & IButtonProps) => (
|
|
||||||
<Button {..._.omit(props, ["accent", "filled", "disabled"])} />
|
|
||||||
))<ButtonStyleProps>`
|
|
||||||
&&&& {
|
|
||||||
${ButtonColorStyles};
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: background-color 0.2s;
|
|
||||||
background-color: ${(props) =>
|
|
||||||
props.filled &&
|
|
||||||
props.accent &&
|
|
||||||
props.theme.colors[AccentColorMap[props.accent]]};
|
|
||||||
border: 1px solid
|
|
||||||
${(props) =>
|
|
||||||
props.accent
|
|
||||||
? props.theme.colors[AccentColorMap[props.accent]]
|
|
||||||
: props.theme.colors.primary};
|
|
||||||
|
|
||||||
border-radius: 0;
|
& > button {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledButton = styled(Button)<ThemeProp & ButtonStyleProps>`
|
||||||
|
height: 100%;
|
||||||
|
background-image: none !important;
|
||||||
font-weight: ${(props) => props.theme.fontWeights[2]};
|
font-weight: ${(props) => props.theme.fontWeights[2]};
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&.bp3-button {
|
|
||||||
padding: 0px 10px;
|
padding: 0px 10px;
|
||||||
|
|
||||||
|
${({ buttonColor, buttonStyle, buttonVariant, prevButtonStyle, theme }) => `
|
||||||
|
&:enabled {
|
||||||
|
background: ${
|
||||||
|
buttonStyle === ButtonStyleTypes.WARNING
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.warning.solid.bgColor
|
||||||
|
: "none"
|
||||||
|
: buttonStyle === ButtonStyleTypes.DANGER
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.danger.solid.bgColor
|
||||||
|
: "none"
|
||||||
|
: buttonStyle === ButtonStyleTypes.INFO
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.info.solid.bgColor
|
||||||
|
: "none"
|
||||||
|
: buttonStyle === ButtonStyleTypes.SECONDARY
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.secondary.solid.bgColor
|
||||||
|
: "none"
|
||||||
|
: buttonStyle === ButtonStyleTypes.CUSTOM
|
||||||
|
? getCustomBackgroundColor(
|
||||||
|
theme,
|
||||||
|
prevButtonStyle,
|
||||||
|
buttonVariant,
|
||||||
|
buttonColor,
|
||||||
|
)
|
||||||
|
: buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.primary.solid.bgColor
|
||||||
|
: "none"
|
||||||
|
} !important;
|
||||||
}
|
}
|
||||||
&& .bp3-button-text {
|
|
||||||
|
&:hover:enabled, &:active:enabled {
|
||||||
|
background: ${
|
||||||
|
buttonStyle === ButtonStyleTypes.WARNING
|
||||||
|
? buttonVariant === ButtonVariantTypes.OUTLINE
|
||||||
|
? theme.colors.button.warning.outline.hoverColor
|
||||||
|
: buttonVariant === ButtonVariantTypes.GHOST
|
||||||
|
? theme.colors.button.warning.ghost.hoverColor
|
||||||
|
: theme.colors.button.warning.solid.hoverColor
|
||||||
|
: buttonStyle === ButtonStyleTypes.DANGER
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.danger.solid.hoverColor
|
||||||
|
: theme.colors.button.danger.outline.hoverColor
|
||||||
|
: buttonStyle === ButtonStyleTypes.INFO
|
||||||
|
? buttonVariant === ButtonVariantTypes.SOLID
|
||||||
|
? theme.colors.button.info.solid.hoverColor
|
||||||
|
: theme.colors.button.info.outline.hoverColor
|
||||||
|
: buttonStyle === ButtonStyleTypes.SECONDARY
|
||||||
|
? buttonVariant === ButtonVariantTypes.OUTLINE
|
||||||
|
? theme.colors.button.secondary.outline.hoverColor
|
||||||
|
: buttonVariant === ButtonVariantTypes.GHOST
|
||||||
|
? theme.colors.button.secondary.ghost.hoverColor
|
||||||
|
: theme.colors.button.secondary.solid.hoverColor
|
||||||
|
: buttonStyle === ButtonStyleTypes.CUSTOM
|
||||||
|
? getCustomHoverColor(
|
||||||
|
theme,
|
||||||
|
prevButtonStyle,
|
||||||
|
buttonVariant,
|
||||||
|
buttonColor,
|
||||||
|
)
|
||||||
|
: buttonVariant === ButtonVariantTypes.OUTLINE
|
||||||
|
? theme.colors.button.primary.outline.hoverColor
|
||||||
|
: buttonVariant === ButtonVariantTypes.GHOST
|
||||||
|
? theme.colors.button.primary.ghost.hoverColor
|
||||||
|
: theme.colors.button.primary.solid.hoverColor
|
||||||
|
} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background-color: ${theme.colors.button.disabled.bgColor} !important;
|
||||||
|
color: ${theme.colors.button.disabled.textColor} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
border: ${
|
||||||
|
buttonVariant === ButtonVariantTypes.OUTLINE
|
||||||
|
? buttonStyle === ButtonStyleTypes.WARNING
|
||||||
|
? `1px solid ${theme.colors.button.warning.outline.borderColor}`
|
||||||
|
: buttonStyle === ButtonStyleTypes.DANGER
|
||||||
|
? `1px solid ${theme.colors.button.danger.outline.borderColor}`
|
||||||
|
: buttonStyle === ButtonStyleTypes.INFO
|
||||||
|
? `1px solid ${theme.colors.button.info.outline.borderColor}`
|
||||||
|
: buttonStyle === ButtonStyleTypes.SECONDARY
|
||||||
|
? `1px solid ${theme.colors.button.secondary.outline.borderColor}`
|
||||||
|
: buttonStyle === ButtonStyleTypes.CUSTOM
|
||||||
|
? `1px solid ${getCustomBorderColor(
|
||||||
|
theme,
|
||||||
|
prevButtonStyle,
|
||||||
|
buttonVariant,
|
||||||
|
buttonColor,
|
||||||
|
)}`
|
||||||
|
: `1px solid ${theme.colors.button.primary.outline.borderColor}`
|
||||||
|
: "none"
|
||||||
|
} !important;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
max-height: 100%;
|
||||||
max-width: 99%;
|
max-width: 99%;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
&&:hover,
|
color: ${
|
||||||
&&:focus {
|
buttonVariant === ButtonVariantTypes.SOLID
|
||||||
${ButtonColorStyles};
|
? buttonStyle === ButtonStyleTypes.CUSTOM
|
||||||
background-color: ${(props) => {
|
? getCustomTextColor(theme, buttonColor, prevButtonStyle)
|
||||||
if (!props.filled) return props.theme.colors.secondaryDarker;
|
: `${theme.colors.button.primary.solid.textColor}`
|
||||||
if (props.accent !== "secondary" && props.accent) {
|
: buttonStyle === ButtonStyleTypes.WARNING
|
||||||
return darkenHover(props.theme.colors[AccentColorMap[props.accent]]);
|
? `${theme.colors.button.warning.outline.textColor}`
|
||||||
}
|
: buttonStyle === ButtonStyleTypes.DANGER
|
||||||
}};
|
? `${theme.colors.button.danger.outline.textColor}`
|
||||||
border-color: ${(props) => {
|
: buttonStyle === ButtonStyleTypes.INFO
|
||||||
if (!props.filled) return;
|
? `${theme.colors.button.info.outline.textColor}`
|
||||||
if (props.accent !== "secondary" && props.accent) {
|
: buttonStyle === ButtonStyleTypes.SECONDARY
|
||||||
return darkenHover(props.theme.colors[AccentColorMap[props.accent]]);
|
? `${theme.colors.button.secondary.outline.textColor}`
|
||||||
}
|
: buttonStyle === ButtonStyleTypes.CUSTOM
|
||||||
}};
|
? getCustomBackgroundColor(
|
||||||
}
|
theme,
|
||||||
&&:active {
|
prevButtonStyle,
|
||||||
${ButtonColorStyles};
|
ButtonVariantTypes.SOLID,
|
||||||
background-color: ${(props) => {
|
buttonColor,
|
||||||
if (!props.filled) return props.theme.colors.secondaryDarkest;
|
)
|
||||||
if (props.accent !== "secondary" && props.accent) {
|
: `${theme.colors.button.primary.outline.textColor}`
|
||||||
return darkenActive(props.theme.colors[AccentColorMap[props.accent]]);
|
} !important;
|
||||||
}
|
|
||||||
}};
|
|
||||||
border-color: ${(props) => {
|
|
||||||
if (!props.filled) return;
|
|
||||||
if (props.accent !== "secondary" && props.accent) {
|
|
||||||
return darkenActive(props.theme.colors[AccentColorMap[props.accent]]);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
&&.bp3-disabled {
|
|
||||||
background-color: #d0d7dd;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
`}
|
||||||
|
|
||||||
|
|
||||||
|
border-radius: ${({ borderRadius }) =>
|
||||||
|
borderRadius === ButtonBorderRadiusTypes.ROUNDED ? "5px" : 0};
|
||||||
|
|
||||||
|
box-shadow: ${({ boxShadow, boxShadowColor, theme }) =>
|
||||||
|
boxShadow === ButtonBoxShadowTypes.VARIANT1
|
||||||
|
? `0px 0px 4px 3px ${boxShadowColor ||
|
||||||
|
theme.colors.button.boxShadow.default.variant1}`
|
||||||
|
: boxShadow === ButtonBoxShadowTypes.VARIANT2
|
||||||
|
? `3px 3px 4px ${boxShadowColor ||
|
||||||
|
theme.colors.button.boxShadow.default.variant2}`
|
||||||
|
: boxShadow === ButtonBoxShadowTypes.VARIANT3
|
||||||
|
? `0px 1px 3px ${boxShadowColor ||
|
||||||
|
theme.colors.button.boxShadow.default.variant3}`
|
||||||
|
: boxShadow === ButtonBoxShadowTypes.VARIANT4
|
||||||
|
? `2px 2px 0px ${boxShadowColor ||
|
||||||
|
theme.colors.button.boxShadow.default.variant4}`
|
||||||
|
: boxShadow === ButtonBoxShadowTypes.VARIANT5
|
||||||
|
? `-2px -2px 0px ${boxShadowColor ||
|
||||||
|
theme.colors.button.boxShadow.default.variant5}`
|
||||||
|
: "none"} !important;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type ButtonStyleName = "primary" | "secondary" | "error" | "grey";
|
|
||||||
|
|
||||||
type ButtonStyleProps = {
|
type ButtonStyleProps = {
|
||||||
accent?: ButtonStyleName;
|
buttonColor?: string;
|
||||||
filled?: boolean;
|
buttonStyle?: ButtonStyle;
|
||||||
|
prevButtonStyle?: ButtonStyle;
|
||||||
|
buttonVariant?: ButtonVariant;
|
||||||
|
boxShadow?: ButtonBoxShadow;
|
||||||
|
boxShadowColor?: string;
|
||||||
|
borderRadius?: ButtonBorderRadius;
|
||||||
|
iconName?: IconName;
|
||||||
|
iconAlign?: Alignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
// To be used in any other part of the app
|
// To be used in any other part of the app
|
||||||
export function BaseButton(props: IButtonProps & ButtonStyleProps) {
|
export function BaseButton(props: IButtonProps & ButtonStyleProps) {
|
||||||
const className = props.disabled
|
const {
|
||||||
? `${props.className} bp3-disabled`
|
borderRadius,
|
||||||
: props.className;
|
boxShadow,
|
||||||
return <ButtonWrapper {...props} className={className} />;
|
boxShadowColor,
|
||||||
|
buttonColor,
|
||||||
|
buttonStyle,
|
||||||
|
buttonVariant,
|
||||||
|
className,
|
||||||
|
disabled,
|
||||||
|
icon,
|
||||||
|
iconAlign,
|
||||||
|
iconName,
|
||||||
|
loading,
|
||||||
|
onClick,
|
||||||
|
prevButtonStyle,
|
||||||
|
rightIcon,
|
||||||
|
text,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (iconAlign === Alignment.RIGHT) {
|
||||||
|
return (
|
||||||
|
<StyledButton
|
||||||
|
alignText={iconName ? Alignment.LEFT : Alignment.CENTER}
|
||||||
|
borderRadius={borderRadius}
|
||||||
|
boxShadow={boxShadow}
|
||||||
|
boxShadowColor={boxShadowColor}
|
||||||
|
buttonColor={buttonColor}
|
||||||
|
buttonStyle={buttonStyle}
|
||||||
|
buttonVariant={buttonVariant}
|
||||||
|
className={className}
|
||||||
|
disabled={disabled}
|
||||||
|
fill
|
||||||
|
icon={icon}
|
||||||
|
loading={loading}
|
||||||
|
onClick={onClick}
|
||||||
|
prevButtonStyle={prevButtonStyle}
|
||||||
|
rightIcon={iconName || rightIcon}
|
||||||
|
text={text}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledButton
|
||||||
|
alignText={iconName ? Alignment.RIGHT : Alignment.CENTER}
|
||||||
|
borderRadius={borderRadius}
|
||||||
|
boxShadow={boxShadow}
|
||||||
|
boxShadowColor={boxShadowColor}
|
||||||
|
buttonColor={buttonColor}
|
||||||
|
buttonStyle={buttonStyle}
|
||||||
|
buttonVariant={buttonVariant}
|
||||||
|
className={className}
|
||||||
|
disabled={disabled}
|
||||||
|
fill
|
||||||
|
icon={iconName || icon}
|
||||||
|
loading={loading}
|
||||||
|
onClick={onClick}
|
||||||
|
prevButtonStyle={prevButtonStyle}
|
||||||
|
rightIcon={rightIcon}
|
||||||
|
text={text}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseButton.defaultProps = {
|
BaseButton.defaultProps = {
|
||||||
accent: "secondary",
|
buttonStyle: "SECONDARY",
|
||||||
|
buttonVariant: "SOLID",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
text: "Button Text",
|
text: "Button Text",
|
||||||
minimal: true,
|
minimal: true,
|
||||||
|
|
@ -194,31 +423,26 @@ interface RecaptchaProps {
|
||||||
recaptchaV2?: boolean;
|
recaptchaV2?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonContainerProps extends ComponentProps {
|
interface ButtonComponentProps extends ComponentProps {
|
||||||
text?: string;
|
text?: string;
|
||||||
icon?: MaybeElement;
|
icon?: IconName | MaybeElement;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||||
disabled?: boolean;
|
isDisabled?: boolean;
|
||||||
buttonStyle?: ButtonStyle;
|
buttonStyle?: ButtonStyle;
|
||||||
|
prevButtonStyle?: ButtonStyle;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
rightIcon?: IconName | MaybeElement;
|
rightIcon?: IconName | MaybeElement;
|
||||||
type: ButtonType;
|
type: ButtonType;
|
||||||
|
buttonColor?: string;
|
||||||
|
buttonVariant?: ButtonVariant;
|
||||||
|
borderRadius?: ButtonBorderRadius;
|
||||||
|
boxShadow?: ButtonBoxShadow;
|
||||||
|
boxShadowColor?: string;
|
||||||
|
iconName?: IconName;
|
||||||
|
iconAlign?: Alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapButtonStyleToStyleName = (buttonStyle?: ButtonStyle) => {
|
|
||||||
switch (buttonStyle) {
|
|
||||||
case "PRIMARY_BUTTON":
|
|
||||||
return "primary";
|
|
||||||
case "SECONDARY_BUTTON":
|
|
||||||
return "secondary";
|
|
||||||
case "DANGER_BUTTON":
|
|
||||||
return "error";
|
|
||||||
default:
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function RecaptchaV2Component(
|
function RecaptchaV2Component(
|
||||||
props: {
|
props: {
|
||||||
children: any;
|
children: any;
|
||||||
|
|
@ -348,9 +572,7 @@ function BtnWrapper(
|
||||||
}
|
}
|
||||||
|
|
||||||
// To be used with the canvas
|
// To be used with the canvas
|
||||||
function ButtonContainer(
|
function ButtonComponent(props: ButtonComponentProps & RecaptchaProps) {
|
||||||
props: ButtonContainerProps & ButtonStyleProps & RecaptchaProps,
|
|
||||||
) {
|
|
||||||
const btnWrapper = (
|
const btnWrapper = (
|
||||||
<BtnWrapper
|
<BtnWrapper
|
||||||
clickWithRecaptcha={props.clickWithRecaptcha}
|
clickWithRecaptcha={props.clickWithRecaptcha}
|
||||||
|
|
@ -359,16 +581,25 @@ function ButtonContainer(
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
recaptchaV2={props.recaptchaV2}
|
recaptchaV2={props.recaptchaV2}
|
||||||
>
|
>
|
||||||
|
<ButtonContainer>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
accent={mapButtonStyleToStyleName(props.buttonStyle)}
|
borderRadius={props.borderRadius}
|
||||||
disabled={props.disabled}
|
boxShadow={props.boxShadow}
|
||||||
filled={props.buttonStyle !== "SECONDARY_BUTTON"}
|
boxShadowColor={props.boxShadowColor}
|
||||||
|
buttonColor={props.buttonColor}
|
||||||
|
buttonStyle={props.buttonStyle}
|
||||||
|
buttonVariant={props.buttonVariant}
|
||||||
|
disabled={props.isDisabled}
|
||||||
icon={props.icon}
|
icon={props.icon}
|
||||||
|
iconAlign={props.iconAlign}
|
||||||
|
iconName={props.iconName}
|
||||||
loading={props.isLoading}
|
loading={props.isLoading}
|
||||||
|
prevButtonStyle={props.prevButtonStyle}
|
||||||
rightIcon={props.rightIcon}
|
rightIcon={props.rightIcon}
|
||||||
text={props.text}
|
text={props.text}
|
||||||
type={props.type}
|
type={props.type}
|
||||||
/>
|
/>
|
||||||
|
</ButtonContainer>
|
||||||
</BtnWrapper>
|
</BtnWrapper>
|
||||||
);
|
);
|
||||||
if (props.tooltip) {
|
if (props.tooltip) {
|
||||||
|
|
@ -388,4 +619,4 @@ function ButtonContainer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ButtonContainer;
|
export default ButtonComponent;
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,7 @@ import {
|
||||||
InputGroup,
|
InputGroup,
|
||||||
IMenuProps,
|
IMenuProps,
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import {
|
import { BaseButton } from "components/designSystems/blueprint/ButtonComponent";
|
||||||
BaseButton,
|
|
||||||
ButtonStyleName,
|
|
||||||
} from "components/designSystems/blueprint/ButtonComponent";
|
|
||||||
import {
|
import {
|
||||||
ItemRenderer,
|
ItemRenderer,
|
||||||
Select,
|
Select,
|
||||||
|
|
@ -85,8 +82,7 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
||||||
|
|
||||||
const displayMode = (
|
const displayMode = (
|
||||||
<BaseButton
|
<BaseButton
|
||||||
accent="primary"
|
buttonStyle="PRIMARY"
|
||||||
filled
|
|
||||||
icon-right="plus"
|
icon-right="plus"
|
||||||
onClick={this.showTextBox}
|
onClick={this.showTextBox}
|
||||||
text={addItem?.displayText}
|
text={addItem?.displayText}
|
||||||
|
|
@ -95,11 +91,7 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
||||||
const editMode = (
|
const editMode = (
|
||||||
<ControlGroup fill>
|
<ControlGroup fill>
|
||||||
<InputGroup inputRef={this.setNewItemTextInput} />
|
<InputGroup inputRef={this.setNewItemTextInput} />
|
||||||
<BaseButton
|
<BaseButton onClick={this.handleAddItem} text={addItem?.displayText} />
|
||||||
filled
|
|
||||||
onClick={this.handleAddItem}
|
|
||||||
text={addItem?.displayText}
|
|
||||||
/>
|
|
||||||
</ControlGroup>
|
</ControlGroup>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
|
|
@ -154,15 +146,7 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const { autocomplete, input, options, selected, width } = this.props;
|
||||||
accent,
|
|
||||||
autocomplete,
|
|
||||||
filled,
|
|
||||||
input,
|
|
||||||
options,
|
|
||||||
selected,
|
|
||||||
width,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDropdown
|
<StyledDropdown
|
||||||
|
|
@ -181,8 +165,8 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
||||||
{this.props.toggle || (
|
{this.props.toggle || (
|
||||||
<StyledButtonWrapper width={width}>
|
<StyledButtonWrapper width={width}>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
accent={accent || "secondary"}
|
buttonStyle="PRIMARY"
|
||||||
filled={!!filled}
|
buttonVariant="OUTLINE"
|
||||||
rightIcon="chevron-down"
|
rightIcon="chevron-down"
|
||||||
text={this.getSelectedDisplayText()}
|
text={this.getSelectedDisplayText()}
|
||||||
/>
|
/>
|
||||||
|
|
@ -207,8 +191,6 @@ export interface DropdownComponentProps {
|
||||||
addItemHandler: (name: string) => void;
|
addItemHandler: (name: string) => void;
|
||||||
};
|
};
|
||||||
toggle?: ReactNode;
|
toggle?: ReactNode;
|
||||||
accent?: ButtonStyleName;
|
|
||||||
filled?: boolean;
|
|
||||||
input?: WrappedFieldInputProps;
|
input?: WrappedFieldInputProps;
|
||||||
width?: string;
|
width?: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Field, BaseFieldProps } from "redux-form";
|
import { Field, BaseFieldProps } from "redux-form";
|
||||||
import DropdownComponent from "components/editorComponents/DropdownComponent";
|
import DropdownComponent from "components/editorComponents/DropdownComponent";
|
||||||
import { ButtonStyleName } from "components/designSystems/blueprint/ButtonComponent";
|
|
||||||
import { DropdownOption } from "widgets/DropdownWidget";
|
import { DropdownOption } from "widgets/DropdownWidget";
|
||||||
|
|
||||||
interface DynamicDropdownFieldOptions {
|
interface DynamicDropdownFieldOptions {
|
||||||
options: DropdownOption[];
|
options: DropdownOption[];
|
||||||
accent?: ButtonStyleName;
|
|
||||||
filled?: boolean;
|
|
||||||
width?: string;
|
width?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,8 +174,6 @@ function KeyValueRow(props: Props & WrappedFieldArrayProps) {
|
||||||
|
|
||||||
<DynamicDropdownFieldWrapper>
|
<DynamicDropdownFieldWrapper>
|
||||||
<DynamicDropdownField
|
<DynamicDropdownField
|
||||||
accent="grey"
|
|
||||||
filled
|
|
||||||
name={`${field}.type`}
|
name={`${field}.type`}
|
||||||
options={MULTI_PART_DROPDOWN_OPTIONS}
|
options={MULTI_PART_DROPDOWN_OPTIONS}
|
||||||
width={DEFAULT_MULTI_PART_DROPDOWN_WIDTH}
|
width={DEFAULT_MULTI_PART_DROPDOWN_WIDTH}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,8 @@ class FieldFileInput extends React.Component<Props, FieldFileInputState> {
|
||||||
<div style={{ flexDirection: "row", display: "flex", width: "50vh" }}>
|
<div style={{ flexDirection: "row", display: "flex", width: "50vh" }}>
|
||||||
<StyledDiv>{value.name}</StyledDiv>
|
<StyledDiv>{value.name}</StyledDiv>
|
||||||
<SelectButton
|
<SelectButton
|
||||||
accent="secondary"
|
buttonStyle="PRIMARY"
|
||||||
|
buttonVariant="OUTLINE"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.openModal();
|
this.openModal();
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@ import { Button, ButtonGroup, IButtonProps } from "@blueprintjs/core";
|
||||||
import BaseControl, { ControlProps } from "./BaseControl";
|
import BaseControl, { ControlProps } from "./BaseControl";
|
||||||
import { ControlIcons } from "icons/ControlIcons";
|
import { ControlIcons } from "icons/ControlIcons";
|
||||||
import { ThemeProp } from "components/ads/common";
|
import { ThemeProp } from "components/ads/common";
|
||||||
import {
|
|
||||||
ButtonBorderRadius,
|
export enum ButtonBorderRadiusTypes {
|
||||||
ButtonBorderRadiusTypes,
|
SHARP = "SHARP",
|
||||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
ROUNDED = "ROUNDED",
|
||||||
|
CIRCLE = "CIRCLE",
|
||||||
|
}
|
||||||
|
export type ButtonBorderRadius = keyof typeof ButtonBorderRadiusTypes;
|
||||||
|
|
||||||
const StyledButtonGroup = styled(ButtonGroup)`
|
const StyledButtonGroup = styled(ButtonGroup)`
|
||||||
height: 33px;
|
height: 33px;
|
||||||
|
|
@ -36,6 +39,7 @@ const StyledButton = styled(Button)<ThemeProp & IButtonProps>`
|
||||||
export interface BorderRadiusOptionsControlProps extends ControlProps {
|
export interface BorderRadiusOptionsControlProps extends ControlProps {
|
||||||
propertyValue: ButtonBorderRadius | undefined;
|
propertyValue: ButtonBorderRadius | undefined;
|
||||||
onChange: (borderRaidus: ButtonBorderRadius) => void;
|
onChange: (borderRaidus: ButtonBorderRadius) => void;
|
||||||
|
options: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class BorderRadiusOptionsControl extends BaseControl<
|
class BorderRadiusOptionsControl extends BaseControl<
|
||||||
|
|
@ -50,11 +54,35 @@ class BorderRadiusOptionsControl extends BaseControl<
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const { propertyValue } = this.props;
|
const { options, propertyValue } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButtonGroup fill>
|
<StyledButtonGroup fill>
|
||||||
|
{options.map((option: ButtonBorderRadius) => {
|
||||||
|
const active =
|
||||||
|
option === ButtonBorderRadiusTypes.SHARP
|
||||||
|
? propertyValue === option || propertyValue === undefined
|
||||||
|
: propertyValue === option;
|
||||||
|
const icon =
|
||||||
|
option === ButtonBorderRadiusTypes.SHARP ? (
|
||||||
|
<ControlIcons.BORDER_RADIUS_SHARP color="#979797" width={15} />
|
||||||
|
) : option === ButtonBorderRadiusTypes.ROUNDED ? (
|
||||||
|
<ControlIcons.BORDER_RADIUS_ROUNDED color="#979797" width={15} />
|
||||||
|
) : (
|
||||||
|
<ControlIcons.BORDER_RADIUS_CIRCLE color="#979797" width={15} />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
|
active={active}
|
||||||
|
icon={icon}
|
||||||
|
key={option}
|
||||||
|
large
|
||||||
|
onClick={() => this.toggleOption(option)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{/* <StyledButton
|
||||||
active={propertyValue === ButtonBorderRadiusTypes.SHARP || undefined}
|
active={propertyValue === ButtonBorderRadiusTypes.SHARP || undefined}
|
||||||
icon={<ControlIcons.BORDER_RADIUS_SHARP color="#979797" width={15} />}
|
icon={<ControlIcons.BORDER_RADIUS_SHARP color="#979797" width={15} />}
|
||||||
large
|
large
|
||||||
|
|
@ -75,7 +103,7 @@ class BorderRadiusOptionsControl extends BaseControl<
|
||||||
}
|
}
|
||||||
large
|
large
|
||||||
onClick={() => this.toggleOption(ButtonBorderRadiusTypes.CIRCLE)}
|
onClick={() => this.toggleOption(ButtonBorderRadiusTypes.CIRCLE)}
|
||||||
/>
|
/> */}
|
||||||
</StyledButtonGroup>
|
</StyledButtonGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ type IconType = IconName | typeof NONE;
|
||||||
const ICON_NAMES = Object.keys(IconNames).map<IconType>(
|
const ICON_NAMES = Object.keys(IconNames).map<IconType>(
|
||||||
(name: string) => IconNames[name as keyof typeof IconNames],
|
(name: string) => IconNames[name as keyof typeof IconNames],
|
||||||
);
|
);
|
||||||
ICON_NAMES.push(NONE);
|
ICON_NAMES.unshift(NONE);
|
||||||
|
|
||||||
const TypedSelect = Select.ofType<IconType>();
|
const TypedSelect = Select.ofType<IconType>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,9 @@ export const Colors = {
|
||||||
BOX_SHADOW_DEFAULT_VARIANT3: "rgba(0, 0, 0, 0.5)",
|
BOX_SHADOW_DEFAULT_VARIANT3: "rgba(0, 0, 0, 0.5)",
|
||||||
BOX_SHADOW_DEFAULT_VARIANT4: "rgba(0, 0, 0, 0.25)",
|
BOX_SHADOW_DEFAULT_VARIANT4: "rgba(0, 0, 0, 0.25)",
|
||||||
BOX_SHADOW_DEFAULT_VARIANT5: "rgba(0, 0, 0, 0.25)",
|
BOX_SHADOW_DEFAULT_VARIANT5: "rgba(0, 0, 0, 0.25)",
|
||||||
|
|
||||||
|
BUTTON_CUSTOM_SOLID_DARK_TEXT_COLOR: "#333",
|
||||||
|
|
||||||
SELECT_DISABLED: "#ced9e080",
|
SELECT_DISABLED: "#ced9e080",
|
||||||
};
|
};
|
||||||
export type Color = typeof Colors[keyof typeof Colors];
|
export type Color = typeof Colors[keyof typeof Colors];
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ import {
|
||||||
} from "utils/DynamicBindingUtils";
|
} from "utils/DynamicBindingUtils";
|
||||||
import { Colors } from "constants/Colors";
|
import { Colors } from "constants/Colors";
|
||||||
import FileDataTypes from "widgets/FileDataTypes";
|
import FileDataTypes from "widgets/FileDataTypes";
|
||||||
|
import { ButtonBorderRadiusTypes } from "components/propertyControls/BorderRadiusOptionsControl";
|
||||||
|
import { ButtonBoxShadowTypes } from "components/propertyControls/BoxShadowOptionsControl";
|
||||||
import {
|
import {
|
||||||
ButtonBorderRadiusTypes,
|
|
||||||
ButtonBoxShadowTypes,
|
|
||||||
ButtonStyleTypes,
|
ButtonStyleTypes,
|
||||||
ButtonVariantTypes,
|
ButtonVariantTypes,
|
||||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||||
|
|
@ -33,7 +33,8 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
||||||
config: {
|
config: {
|
||||||
BUTTON_WIDGET: {
|
BUTTON_WIDGET: {
|
||||||
text: "Submit",
|
text: "Submit",
|
||||||
buttonStyle: "PRIMARY_BUTTON",
|
buttonStyle: "PRIMARY",
|
||||||
|
buttonVariant: "SOLID",
|
||||||
rows: 1 * GRID_DENSITY_MIGRATION_V1,
|
rows: 1 * GRID_DENSITY_MIGRATION_V1,
|
||||||
columns: 2 * GRID_DENSITY_MIGRATION_V1,
|
columns: 2 * GRID_DENSITY_MIGRATION_V1,
|
||||||
widgetName: "Button",
|
widgetName: "Button",
|
||||||
|
|
|
||||||
|
|
@ -163,14 +163,13 @@ function RapidApiEditorForm(props: Props) {
|
||||||
|
|
||||||
<ActionButtons>
|
<ActionButtons>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="error"
|
buttonStyle="DANGER"
|
||||||
loading={isDeleting}
|
loading={isDeleting}
|
||||||
onClick={onDeleteClick}
|
onClick={onDeleteClick}
|
||||||
text="Delete"
|
text="Delete"
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="primary"
|
buttonStyle="PRIMARY"
|
||||||
filled
|
|
||||||
loading={isRunning}
|
loading={isRunning}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onRunClick();
|
onRunClick();
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,9 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
|
||||||
: undefined}
|
: undefined}
|
||||||
<SaveButtonContainer>
|
<SaveButtonContainer>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="error"
|
buttonStyle="DANGER"
|
||||||
|
buttonVariant="SOLID"
|
||||||
|
// accent="error"
|
||||||
className="t--delete-datasource"
|
className="t--delete-datasource"
|
||||||
loading={isDeleting}
|
loading={isDeleting}
|
||||||
onClick={() => handleDelete(datasourceId)}
|
onClick={() => handleDelete(datasourceId)}
|
||||||
|
|
@ -196,7 +198,9 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="secondary"
|
// accent="secondary"
|
||||||
|
buttonStyle="PRIMARY"
|
||||||
|
buttonVariant="OUTLINE"
|
||||||
className="t--test-datasource"
|
className="t--test-datasource"
|
||||||
loading={isTesting}
|
loading={isTesting}
|
||||||
onClick={this.test}
|
onClick={this.test}
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,9 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
|
||||||
return (
|
return (
|
||||||
<SaveButtonContainer>
|
<SaveButtonContainer>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="error"
|
// accent="error"
|
||||||
|
buttonStyle="DANGER"
|
||||||
|
buttonVariant="SOLID"
|
||||||
className="t--delete-datasource"
|
className="t--delete-datasource"
|
||||||
loading={isDeleting}
|
loading={isDeleting}
|
||||||
onClick={() => deleteDatasource(datasourceId)}
|
onClick={() => deleteDatasource(datasourceId)}
|
||||||
|
|
|
||||||
|
|
@ -145,9 +145,8 @@ function DatasourceCard(props: DatasourceCardProps) {
|
||||||
text="Edit Datasource"
|
text="Edit Datasource"
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="primary"
|
buttonStyle="PRIMARY"
|
||||||
className="t--create-api"
|
className="t--create-api"
|
||||||
filled
|
|
||||||
icon={"plus"}
|
icon={"plus"}
|
||||||
onClick={() => props.onCreate(datasource)}
|
onClick={() => props.onCreate(datasource)}
|
||||||
text="New API"
|
text="New API"
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,9 @@ class DatasourceSaaSEditor extends JSONtoForm<Props> {
|
||||||
: null}
|
: null}
|
||||||
<SaveButtonContainer>
|
<SaveButtonContainer>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
accent="error"
|
// accent="error"
|
||||||
|
buttonStyle="DANGER"
|
||||||
|
buttonVariant="SOLID"
|
||||||
className="t--delete-datasource"
|
className="t--delete-datasource"
|
||||||
loading={isDeleting}
|
loading={isDeleting}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,24 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import * as Sentry from "@sentry/react";
|
||||||
|
import { Alignment } from "@blueprintjs/core";
|
||||||
|
import { IconName } from "@blueprintjs/icons";
|
||||||
|
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "constants/WidgetConstants";
|
import { WidgetType } from "constants/WidgetConstants";
|
||||||
import ButtonComponent, {
|
import ButtonComponent, {
|
||||||
|
ButtonStyle,
|
||||||
|
ButtonStyleTypes,
|
||||||
ButtonType,
|
ButtonType,
|
||||||
|
ButtonVariant,
|
||||||
} from "components/designSystems/blueprint/ButtonComponent";
|
} from "components/designSystems/blueprint/ButtonComponent";
|
||||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||||
import { ValidationTypes } from "constants/WidgetValidation";
|
import { ValidationTypes } from "constants/WidgetValidation";
|
||||||
import * as Sentry from "@sentry/react";
|
|
||||||
import withMeta, { WithMeta } from "./MetaHOC";
|
import withMeta, { WithMeta } from "./MetaHOC";
|
||||||
|
import { ButtonBoxShadow } from "components/propertyControls/BoxShadowOptionsControl";
|
||||||
|
import {
|
||||||
|
ButtonBorderRadius,
|
||||||
|
ButtonBorderRadiusTypes,
|
||||||
|
} from "components/propertyControls/BorderRadiusOptionsControl";
|
||||||
|
|
||||||
class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||||
onButtonClickBound: (event: React.MouseEvent<HTMLElement>) => void;
|
onButtonClickBound: (event: React.MouseEvent<HTMLElement>) => void;
|
||||||
|
|
@ -36,39 +47,6 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||||
isTriggerProperty: false,
|
isTriggerProperty: false,
|
||||||
validation: { type: ValidationTypes.TEXT },
|
validation: { type: ValidationTypes.TEXT },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
propertyName: "buttonStyle",
|
|
||||||
label: "Button Style",
|
|
||||||
controlType: "DROP_DOWN",
|
|
||||||
helpText: "Changes the style of the button",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: "Primary Button",
|
|
||||||
value: "PRIMARY_BUTTON",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Secondary Button",
|
|
||||||
value: "SECONDARY_BUTTON",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Danger Button",
|
|
||||||
value: "DANGER_BUTTON",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
isJSConvertible: true,
|
|
||||||
isBindProperty: false,
|
|
||||||
isTriggerProperty: false,
|
|
||||||
validation: {
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
allowedValues: [
|
|
||||||
"PRIMARY_BUTTON",
|
|
||||||
"SECONDARY_BUTTON",
|
|
||||||
"DANGER_BUTTON",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
helpText: "Show helper text with button on hover",
|
helpText: "Show helper text with button on hover",
|
||||||
propertyName: "tooltip",
|
propertyName: "tooltip",
|
||||||
|
|
@ -135,7 +113,221 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
sectionName: "Styles",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
propertyName: "buttonStyle",
|
||||||
|
label: "Button Style",
|
||||||
|
controlType: "DROP_DOWN",
|
||||||
|
helpText: "Changes the style of the button",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Primary",
|
||||||
|
value: "PRIMARY",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Warning",
|
||||||
|
value: "WARNING",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Danger",
|
||||||
|
value: "DANGER",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Info",
|
||||||
|
value: "INFO",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Secondary",
|
||||||
|
value: "SECONDARY",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Custom",
|
||||||
|
value: "CUSTOM",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
updateHook: (
|
||||||
|
props: ButtonWidgetProps,
|
||||||
|
propertyPath: string,
|
||||||
|
propertyValue: string,
|
||||||
|
) => {
|
||||||
|
let propertiesToUpdate = [
|
||||||
|
{ propertyPath, propertyValue },
|
||||||
|
{ propertyPath: "prevButtonStyle", propertyValue },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (propertyValue === "CUSTOM") {
|
||||||
|
propertiesToUpdate = [{ propertyPath, propertyValue }];
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesToUpdate.push({
|
||||||
|
propertyPath: "buttonColor",
|
||||||
|
propertyValue: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
return propertiesToUpdate;
|
||||||
|
},
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
allowedValues: [
|
||||||
|
"PRIMARY",
|
||||||
|
"WARNING",
|
||||||
|
"DANGER",
|
||||||
|
"INFO",
|
||||||
|
"SECONDARY",
|
||||||
|
"CUSTOM",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "buttonColor",
|
||||||
|
helpText:
|
||||||
|
"Sets the custom color preset based on the button variant",
|
||||||
|
label: "Button Color",
|
||||||
|
controlType: "COLOR_PICKER",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
hidden: (props: ButtonWidgetProps) =>
|
||||||
|
props.buttonStyle !== ButtonStyleTypes.CUSTOM,
|
||||||
|
dependencies: ["buttonStyle"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "buttonVariant",
|
||||||
|
label: "Button Variant",
|
||||||
|
controlType: "DROP_DOWN",
|
||||||
|
helpText: "Sets the variant of the icon button",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Solid",
|
||||||
|
value: "SOLID",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Outline",
|
||||||
|
value: "OUTLINE",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Ghost",
|
||||||
|
value: "GHOST",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isJSConvertible: true,
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
allowedVAlues: ["SOLID", "OUTLINE", "GHOST"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "borderRadius",
|
||||||
|
label: "Border Radius",
|
||||||
|
helpText:
|
||||||
|
"Rounds the corners of the icon button's outer border edge",
|
||||||
|
controlType: "BORDER_RADIUS_OPTIONS",
|
||||||
|
options: [
|
||||||
|
ButtonBorderRadiusTypes.SHARP,
|
||||||
|
ButtonBorderRadiusTypes.ROUNDED,
|
||||||
|
],
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
allowedValues: ["CIRCLE", "SHARP", "ROUNDED"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "boxShadow",
|
||||||
|
label: "Box Shadow",
|
||||||
|
helpText:
|
||||||
|
"Enables you to cast a drop shadow from the frame of the widget",
|
||||||
|
controlType: "BOX_SHADOW_OPTIONS",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
allowedValues: [
|
||||||
|
"NONE",
|
||||||
|
"VARIANT1",
|
||||||
|
"VARIANT2",
|
||||||
|
"VARIANT3",
|
||||||
|
"VARIANT4",
|
||||||
|
"VARIANT5",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "boxShadowColor",
|
||||||
|
helpText: "Sets the shadow color of the widget",
|
||||||
|
label: "Shadow Color",
|
||||||
|
controlType: "COLOR_PICKER",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
regex: /^(?![<|{{]).+/,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "iconName",
|
||||||
|
label: "Icon",
|
||||||
|
helpText: "Sets the icon to be used for the button",
|
||||||
|
controlType: "ICON_SELECT",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
updateHook: (
|
||||||
|
props: ButtonWidgetProps,
|
||||||
|
propertyPath: string,
|
||||||
|
propertyValue: string,
|
||||||
|
) => {
|
||||||
|
const propertiesToUpdate = [{ propertyPath, propertyValue }];
|
||||||
|
if (!props.iconAlign) {
|
||||||
|
propertiesToUpdate.push({
|
||||||
|
propertyPath: "iconAlign",
|
||||||
|
propertyValue: Alignment.LEFT,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return propertiesToUpdate;
|
||||||
|
},
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "iconAlign",
|
||||||
|
label: "Icon Alignment",
|
||||||
|
helpText: "Sets the icon alignment of the button",
|
||||||
|
controlType: "ICON_ALIGN",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
allowedValues: ["center", "left", "right"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDefaultPropertiesMap(): Record<string, string> {
|
||||||
|
return {
|
||||||
|
prevButtonStyle: "buttonStyle",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
|
|
@ -188,14 +380,22 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<ButtonComponent
|
<ButtonComponent
|
||||||
|
borderRadius={this.props.borderRadius}
|
||||||
|
boxShadow={this.props.boxShadow}
|
||||||
|
boxShadowColor={this.props.boxShadowColor}
|
||||||
|
buttonColor={this.props.buttonColor}
|
||||||
buttonStyle={this.props.buttonStyle}
|
buttonStyle={this.props.buttonStyle}
|
||||||
|
buttonVariant={this.props.buttonVariant}
|
||||||
clickWithRecaptcha={this.clickWithRecaptchaBound}
|
clickWithRecaptcha={this.clickWithRecaptchaBound}
|
||||||
disabled={this.props.isDisabled}
|
|
||||||
googleRecaptchaKey={this.props.googleRecaptchaKey}
|
googleRecaptchaKey={this.props.googleRecaptchaKey}
|
||||||
handleRecaptchaV2Loading={this.handleRecaptchaV2Loading}
|
handleRecaptchaV2Loading={this.handleRecaptchaV2Loading}
|
||||||
|
iconAlign={this.props.iconAlign}
|
||||||
|
iconName={this.props.iconName}
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
isLoading={this.props.isLoading || this.state.isLoading}
|
isLoading={this.props.isLoading || this.state.isLoading}
|
||||||
key={this.props.widgetId}
|
key={this.props.widgetId}
|
||||||
onClick={!this.props.isDisabled ? this.onButtonClickBound : undefined}
|
onClick={!this.props.isDisabled ? this.onButtonClickBound : undefined}
|
||||||
|
prevButtonStyle={this.props.prevButtonStyle}
|
||||||
recaptchaV2={this.props.recaptchaV2}
|
recaptchaV2={this.props.recaptchaV2}
|
||||||
text={this.props.text}
|
text={this.props.text}
|
||||||
tooltip={this.props.tooltip}
|
tooltip={this.props.tooltip}
|
||||||
|
|
@ -211,21 +411,23 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ButtonStyle =
|
|
||||||
| "PRIMARY_BUTTON"
|
|
||||||
| "SECONDARY_BUTTON"
|
|
||||||
| "SUCCESS_BUTTON"
|
|
||||||
| "DANGER_BUTTON";
|
|
||||||
|
|
||||||
export interface ButtonWidgetProps extends WidgetProps, WithMeta {
|
export interface ButtonWidgetProps extends WidgetProps, WithMeta {
|
||||||
text?: string;
|
text?: string;
|
||||||
buttonStyle?: ButtonStyle;
|
|
||||||
onClick?: string;
|
onClick?: string;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
isVisible?: boolean;
|
isVisible?: boolean;
|
||||||
recaptchaV2?: boolean;
|
recaptchaV2?: boolean;
|
||||||
buttonType?: ButtonType;
|
buttonType?: ButtonType;
|
||||||
googleRecaptchaKey?: string;
|
googleRecaptchaKey?: string;
|
||||||
|
buttonStyle?: ButtonStyle;
|
||||||
|
prevButtonStyle?: ButtonStyle;
|
||||||
|
buttonVariant?: ButtonVariant;
|
||||||
|
buttonColor?: string;
|
||||||
|
borderRadius?: ButtonBorderRadius;
|
||||||
|
boxShadow?: ButtonBoxShadow;
|
||||||
|
boxShadowColor?: string;
|
||||||
|
iconName?: IconName;
|
||||||
|
iconAlign?: Alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonWidgetState extends WidgetState {
|
interface ButtonWidgetState extends WidgetState {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React from "react";
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "constants/WidgetConstants";
|
import { WidgetType } from "constants/WidgetConstants";
|
||||||
import ButtonComponent, {
|
import ButtonComponent, {
|
||||||
|
ButtonStyle,
|
||||||
ButtonType,
|
ButtonType,
|
||||||
} from "components/designSystems/blueprint/ButtonComponent";
|
} from "components/designSystems/blueprint/ButtonComponent";
|
||||||
import {
|
import {
|
||||||
|
|
@ -194,8 +195,8 @@ class FormButtonWidget extends BaseWidget<
|
||||||
<ButtonComponent
|
<ButtonComponent
|
||||||
buttonStyle={this.props.buttonStyle}
|
buttonStyle={this.props.buttonStyle}
|
||||||
clickWithRecaptcha={this.clickWithRecaptchaBound}
|
clickWithRecaptcha={this.clickWithRecaptchaBound}
|
||||||
disabled={disabled}
|
|
||||||
googleRecaptchaKey={this.props.googleRecaptchaKey}
|
googleRecaptchaKey={this.props.googleRecaptchaKey}
|
||||||
|
isDisabled={disabled}
|
||||||
isLoading={this.props.isLoading || this.state.isLoading}
|
isLoading={this.props.isLoading || this.state.isLoading}
|
||||||
key={this.props.widgetId}
|
key={this.props.widgetId}
|
||||||
onClick={!disabled ? this.onButtonClickBound : undefined}
|
onClick={!disabled ? this.onButtonClickBound : undefined}
|
||||||
|
|
@ -213,11 +214,11 @@ class FormButtonWidget extends BaseWidget<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ButtonStyle =
|
// export type ButtonStyle =
|
||||||
| "PRIMARY_BUTTON"
|
// | "PRIMARY_BUTTON"
|
||||||
| "SECONDARY_BUTTON"
|
// | "SECONDARY_BUTTON"
|
||||||
| "SUCCESS_BUTTON"
|
// | "SUCCESS_BUTTON"
|
||||||
| "DANGER_BUTTON";
|
// | "DANGER_BUTTON";
|
||||||
|
|
||||||
export interface FormButtonWidgetProps extends WidgetProps, WithMeta {
|
export interface FormButtonWidgetProps extends WidgetProps, WithMeta {
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,14 @@ import { ValidationTypes } from "constants/WidgetValidation";
|
||||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||||
|
|
||||||
import IconButtonComponent, {
|
import IconButtonComponent, {
|
||||||
ButtonBorderRadius,
|
|
||||||
ButtonBoxShadow,
|
|
||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||||
|
import {
|
||||||
|
ButtonBorderRadius,
|
||||||
|
ButtonBorderRadiusTypes,
|
||||||
|
} from "components/propertyControls/BorderRadiusOptionsControl";
|
||||||
|
import { ButtonBoxShadow } from "components/propertyControls/BoxShadowOptionsControl";
|
||||||
|
|
||||||
export interface IconButtonWidgetProps extends WidgetProps {
|
export interface IconButtonWidgetProps extends WidgetProps {
|
||||||
iconName?: IconName;
|
iconName?: IconName;
|
||||||
|
|
@ -99,6 +102,11 @@ class IconButtonWidget extends BaseWidget<IconButtonWidgetProps, WidgetState> {
|
||||||
helpText:
|
helpText:
|
||||||
"Rounds the corners of the icon button's outer border edge",
|
"Rounds the corners of the icon button's outer border edge",
|
||||||
controlType: "BORDER_RADIUS_OPTIONS",
|
controlType: "BORDER_RADIUS_OPTIONS",
|
||||||
|
options: [
|
||||||
|
ButtonBorderRadiusTypes.SHARP,
|
||||||
|
ButtonBorderRadiusTypes.ROUNDED,
|
||||||
|
ButtonBorderRadiusTypes.CIRCLE,
|
||||||
|
],
|
||||||
isBindProperty: false,
|
isBindProperty: false,
|
||||||
isTriggerProperty: false,
|
isTriggerProperty: false,
|
||||||
validation: {
|
validation: {
|
||||||
|
|
|
||||||
|
|
@ -16890,9 +16890,10 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
|
||||||
|
|
||||||
tinycolor2@^1.4.1:
|
tinycolor2@^1.4.1, tinycolor2@^1.4.2:
|
||||||
version "1.4.2"
|
version "1.4.2"
|
||||||
resolved "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz"
|
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
||||||
|
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
|
||||||
|
|
||||||
tmp@^0.0.33:
|
tmp@^0.0.33:
|
||||||
version "0.0.33"
|
version "0.0.33"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user