Icon Button Widget (#5723)
Introducing the **Floating action button / Icon button**. Now you can use this to show small actions as icons. We have added a bunch of styling customisation to this as well. You can bind an onClick action to this and easily trigger an even. The component also automatically resizes within the widget as you scale it while maintaining the right aspect ratio.
3
app/client/src/assets/icons/control/border-radius-circle.svg
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.390137" width="15" height="15" rx="7.5" fill="#A9A7A7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 171 B |
3
app/client/src/assets/icons/control/border-radius-rounded.svg
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.723389" width="15" height="15" rx="5" fill="#A9A7A7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 169 B |
3
app/client/src/assets/icons/control/border-radius-sharp.svg
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.0566406" width="15" height="15" fill="#A9A7A7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 163 B |
3
app/client/src/assets/icons/control/box-shadow-none.svg
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.538208 8.66256C0.538208 13.1499 4.17687 16.7886 8.66424 16.7886C13.1516 16.7886 16.7903 13.1499 16.7903 8.66256C16.7903 4.17428 13.1516 0.53653 8.66424 0.53653C4.17687 0.53653 0.538208 4.17428 0.538208 8.66256ZM4.89557 3.59734C5.94924 2.81272 7.25031 2.34231 8.66424 2.34231C12.1548 2.34231 14.9845 5.17198 14.9845 8.66256C14.9845 10.0774 14.515 11.3785 13.7295 12.4312L4.89557 3.59734ZM2.34399 8.66256C2.34399 7.2378 2.82162 5.9277 3.61617 4.87132L12.4555 13.7106C11.3982 14.5061 10.0881 14.9828 8.66424 14.9828C5.17366 14.9828 2.34399 12.1531 2.34399 8.66256Z" fill="#CACACA"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 735 B |
17
app/client/src/assets/icons/control/box-shadow-variant1.svg
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
<svg width="46" height="37" viewBox="0 0 46 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="7.328" y="7.82785" width="31.6012" height="21.6694" fill="#03B365"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.328003" y="0.82785" width="45.6012" height="35.6694" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feMorphology radius="3" operator="dilate" in="SourceAlpha" result="effect1_dropShadow"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 924 B |
16
app/client/src/assets/icons/control/box-shadow-variant2.svg
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
<svg width="41" height="31" viewBox="0 0 41 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="1.6322" y="1.82785" width="31.6012" height="21.6694" fill="#03B365"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.632202" y="0.82785" width="39.6012" height="29.6694" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dx="3" dy="3"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 849 B |
16
app/client/src/assets/icons/control/box-shadow-variant3.svg
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
<svg width="38" height="28" viewBox="0 0 38 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="3.63538" y="2.63779" width="30.7335" height="21.0744" fill="#03B365"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.635376" y="0.637787" width="36.7335" height="27.0744" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="1"/>
|
||||
<feGaussianBlur stdDeviation="1.5"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 845 B |
15
app/client/src/assets/icons/control/box-shadow-variant4.svg
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
<svg width="34" height="24" viewBox="0 0 34 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="0.730957" y="0.637787" width="30.7335" height="21.0744" fill="#03B365"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.730957" y="0.637787" width="32.7335" height="23.0744" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dx="2" dy="2"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 818 B |
15
app/client/src/assets/icons/control/box-shadow-variant5.svg
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
<svg width="33" height="24" viewBox="0 0 33 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="2.07031" y="2.63779" width="30.7335" height="21.0744" fill="#03B365"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.0703125" y="0.637787" width="32.7335" height="23.0744" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dx="-2" dy="-2"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 819 B |
3
app/client/src/assets/icons/widget/icon-button.svg
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM13 11V6.5H11V11H6V13H11V18H13V13H17.5V11H13Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 327 B |
|
|
@ -0,0 +1,255 @@
|
|||
import * as React from "react";
|
||||
import { useMemo } from "react";
|
||||
import styled from "styled-components";
|
||||
import { Button } from "@blueprintjs/core";
|
||||
import { IconName } from "@blueprintjs/icons";
|
||||
|
||||
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
|
||||
import { ThemeProp } from "components/ads/common";
|
||||
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
||||
|
||||
const IconButtonContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export interface ButtonStyleProps {
|
||||
borderRadius?: ButtonBorderRadius;
|
||||
boxShadow?: ButtonBoxShadow;
|
||||
boxShadowColor?: string;
|
||||
buttonStyle?: ButtonStyle;
|
||||
buttonVariant?: ButtonVariant;
|
||||
dimension: number;
|
||||
}
|
||||
|
||||
const StyledButton = styled(Button)<ThemeProp & ButtonStyleProps>`
|
||||
background-image: none !important;
|
||||
height: ${({ dimension }) => `${dimension}px`};
|
||||
width: ${({ dimension }) => `${dimension}px`};
|
||||
${({ buttonStyle, buttonVariant, 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"
|
||||
: buttonVariant === ButtonVariantTypes.SOLID
|
||||
? theme.colors.button.primary.solid.bgColor
|
||||
: "none"
|
||||
} !important;
|
||||
}
|
||||
|
||||
&: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
|
||||
: 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}`
|
||||
: `1px solid ${theme.colors.button.primary.outline.borderColor}`
|
||||
: "none"
|
||||
} !important;
|
||||
|
||||
& > span {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
color: ${
|
||||
buttonVariant === ButtonVariantTypes.SOLID
|
||||
? `${theme.colors.button.primary.solid.textColor}`
|
||||
: buttonStyle === ButtonStyleTypes.WARNING
|
||||
? `${theme.colors.button.warning.outline.textColor}`
|
||||
: buttonStyle === ButtonStyleTypes.DANGER
|
||||
? `${theme.colors.button.danger.outline.textColor}`
|
||||
: buttonStyle === ButtonStyleTypes.INFO
|
||||
? `${theme.colors.button.info.outline.textColor}`
|
||||
: buttonStyle === ButtonStyleTypes.SECONDARY
|
||||
? `${theme.colors.button.secondary.outline.textColor}`
|
||||
: `${theme.colors.button.primary.outline.textColor}`
|
||||
} !important;
|
||||
}
|
||||
|
||||
& > span > svg {
|
||||
height: 60%;
|
||||
width: 60%;
|
||||
min-height: 16px;
|
||||
min-width: 16px;
|
||||
}
|
||||
`}
|
||||
|
||||
|
||||
border-radius: ${({ borderRadius }) =>
|
||||
borderRadius === ButtonBorderRadiusTypes.CIRCLE
|
||||
? "50%"
|
||||
: borderRadius === ButtonBorderRadiusTypes.ROUNDED
|
||||
? "10px"
|
||||
: 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 enum ButtonStyleTypes {
|
||||
PRIMARY = "PRIMARY",
|
||||
WARNING = "WARNING",
|
||||
DANGER = "DANGER",
|
||||
INFO = "INFO",
|
||||
SECONDARY = "SECONDARY",
|
||||
}
|
||||
export type ButtonStyle = keyof typeof ButtonStyleTypes;
|
||||
|
||||
export enum ButtonVariantTypes {
|
||||
SOLID = "SOLID",
|
||||
OUTLINE = "OUTLINE",
|
||||
GHOST = "GHOST",
|
||||
}
|
||||
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 {
|
||||
iconName?: IconName;
|
||||
buttonStyle: ButtonStyle;
|
||||
buttonVariant: ButtonVariant;
|
||||
borderRadius: ButtonBorderRadius;
|
||||
boxShadow: ButtonBoxShadow;
|
||||
boxShadowColor: string;
|
||||
isDisabled: boolean;
|
||||
isVisible: boolean;
|
||||
onClick: () => void;
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
function IconButtonComponent(props: IconButtonComponentProps) {
|
||||
const {
|
||||
borderRadius,
|
||||
boxShadow,
|
||||
boxShadowColor,
|
||||
buttonStyle,
|
||||
buttonVariant,
|
||||
height,
|
||||
isDisabled,
|
||||
onClick,
|
||||
width,
|
||||
} = props;
|
||||
|
||||
/**
|
||||
* returns the dimension to be used for widget
|
||||
* whatever is the minimum between width and height,
|
||||
* we will use that for the dimension of the widget
|
||||
*/
|
||||
const dimension = useMemo(() => {
|
||||
console.log({ width, height });
|
||||
if (width > height) {
|
||||
return height - WIDGET_PADDING * 2;
|
||||
}
|
||||
|
||||
return width - WIDGET_PADDING * 2;
|
||||
}, [width, height]);
|
||||
|
||||
return (
|
||||
<IconButtonContainer>
|
||||
<StyledButton
|
||||
borderRadius={borderRadius}
|
||||
boxShadow={boxShadow}
|
||||
boxShadowColor={boxShadowColor}
|
||||
buttonStyle={buttonStyle}
|
||||
buttonVariant={buttonVariant}
|
||||
dimension={dimension}
|
||||
disabled={isDisabled}
|
||||
icon={props.iconName}
|
||||
large
|
||||
onClick={onClick}
|
||||
/>
|
||||
</IconButtonContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default IconButtonComponent;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Button, ButtonGroup, IButtonProps } from "@blueprintjs/core";
|
||||
|
||||
import BaseControl, { ControlProps } from "./BaseControl";
|
||||
import { ControlIcons } from "icons/ControlIcons";
|
||||
import { ThemeProp } from "components/ads/common";
|
||||
import {
|
||||
ButtonBorderRadius,
|
||||
ButtonBorderRadiusTypes,
|
||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||
|
||||
const StyledButtonGroup = styled(ButtonGroup)`
|
||||
height: 33px;
|
||||
`;
|
||||
|
||||
const StyledButton = styled(Button)<ThemeProp & IButtonProps>`
|
||||
border: ${(props) =>
|
||||
props.active ? `1px solid #6A86CE` : `1px solid #A9A7A7`};
|
||||
border-radius: 0;
|
||||
box-shadow: none !important;
|
||||
background-image: none !important;
|
||||
background-color: #ffffff !important;
|
||||
& > div {
|
||||
display: flex;
|
||||
}
|
||||
&.bp3-active {
|
||||
box-shadow: none !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
`;
|
||||
|
||||
export interface BorderRadiusOptionsControlProps extends ControlProps {
|
||||
propertyValue: ButtonBorderRadius | undefined;
|
||||
onChange: (borderRaidus: ButtonBorderRadius) => void;
|
||||
}
|
||||
|
||||
class BorderRadiusOptionsControl extends BaseControl<
|
||||
BorderRadiusOptionsControlProps
|
||||
> {
|
||||
constructor(props: BorderRadiusOptionsControlProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
static getControlType() {
|
||||
return "BORDER_RADIUS_OPTIONS";
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { propertyValue } = this.props;
|
||||
|
||||
return (
|
||||
<StyledButtonGroup fill>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBorderRadiusTypes.SHARP || undefined}
|
||||
icon={<ControlIcons.BORDER_RADIUS_SHARP color="#979797" width={15} />}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBorderRadiusTypes.SHARP)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBorderRadiusTypes.ROUNDED}
|
||||
icon={
|
||||
<ControlIcons.BORDER_RADIUS_ROUNDED color="#979797" width={15} />
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBorderRadiusTypes.ROUNDED)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBorderRadiusTypes.CIRCLE}
|
||||
icon={
|
||||
<ControlIcons.BORDER_RADIUS_CIRCLE color="#979797" width={15} />
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBorderRadiusTypes.CIRCLE)}
|
||||
/>
|
||||
</StyledButtonGroup>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleOption = (option: ButtonBorderRadius) => {
|
||||
this.updateProperty(this.props.propertyName, option);
|
||||
};
|
||||
}
|
||||
|
||||
export default BorderRadiusOptionsControl;
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Button, ButtonGroup, IButtonProps } from "@blueprintjs/core";
|
||||
|
||||
import BaseControl, { ControlProps } from "./BaseControl";
|
||||
import { ControlIcons } from "icons/ControlIcons";
|
||||
import { ThemeProp } from "components/ads/common";
|
||||
import {
|
||||
ButtonBoxShadow,
|
||||
ButtonBoxShadowTypes,
|
||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||
|
||||
const StyledButtonGroup = styled(ButtonGroup)`
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const StyledButton = styled(Button)<ThemeProp & IButtonProps>`
|
||||
margin-right: 0 !important;
|
||||
border: ${(props) =>
|
||||
props.active ? `1px solid #6A86CE` : `1px solid #E0DEDE`};
|
||||
border-radius: 0;
|
||||
box-shadow: none !important;
|
||||
background-image: none;
|
||||
background-color: #ffffff !important;
|
||||
& > div {
|
||||
display: flex;
|
||||
}
|
||||
&.bp3-active {
|
||||
box-shadow: none !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
`;
|
||||
|
||||
export interface BoxShadowOptionsControlProps extends ControlProps {
|
||||
propertyValue: ButtonBoxShadow | undefined;
|
||||
}
|
||||
|
||||
class BoxShadowOptionsControl extends BaseControl<
|
||||
BoxShadowOptionsControlProps
|
||||
> {
|
||||
constructor(props: BoxShadowOptionsControlProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
static getControlType() {
|
||||
return "BOX_SHADOW_OPTIONS";
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { propertyValue } = this.props;
|
||||
|
||||
return (
|
||||
<StyledButtonGroup fill>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.NONE || undefined}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_NONE
|
||||
color="#CACACA"
|
||||
keepColors
|
||||
width={16}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.NONE)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.VARIANT1}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_VARIANT1
|
||||
height={32}
|
||||
keepColors
|
||||
width={40}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.VARIANT1)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.VARIANT2}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_VARIANT2
|
||||
height={28}
|
||||
keepColors
|
||||
width={36}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.VARIANT2)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.VARIANT3}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_VARIANT3
|
||||
height={27}
|
||||
keepColors
|
||||
width={32}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.VARIANT3)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.VARIANT4}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_VARIANT4
|
||||
height={26}
|
||||
keepColors
|
||||
width={34}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.VARIANT4)}
|
||||
/>
|
||||
<StyledButton
|
||||
active={propertyValue === ButtonBoxShadowTypes.VARIANT5}
|
||||
icon={
|
||||
<ControlIcons.BOX_SHADOW_VARIANT5
|
||||
height={26}
|
||||
keepColors
|
||||
width={34}
|
||||
/>
|
||||
}
|
||||
large
|
||||
onClick={() => this.toggleOption(ButtonBoxShadowTypes.VARIANT5)}
|
||||
/>
|
||||
</StyledButtonGroup>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleOption = (option: ButtonBoxShadow) => {
|
||||
this.updateProperty(this.props.propertyName, option);
|
||||
};
|
||||
}
|
||||
|
||||
export default BoxShadowOptionsControl;
|
||||
|
|
@ -24,7 +24,6 @@ const StyledButton = styled(Button)`
|
|||
border: none !important;
|
||||
border-radius: 0;
|
||||
background-color: #ffffff !important;
|
||||
|
||||
> span.bp3-icon-caret-down {
|
||||
color: rgb(169, 167, 167);
|
||||
}
|
||||
|
|
@ -38,7 +37,6 @@ const StyledMenu = styled(Menu)`
|
|||
max-height: 170px !important;
|
||||
padding-left: 5px !important;
|
||||
padding-right: 5px !important;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background-color: #eeeeee;
|
||||
|
|
@ -54,13 +52,11 @@ 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;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ import MultiSwitchControl, {
|
|||
import MenuItemsControl from "./MenuItemsControl";
|
||||
import IconSelectControl from "./IconSelectControl";
|
||||
import IconAlignControl from "./IconAlignControl";
|
||||
import BorderRadiusOptionsControl from "./BorderRadiusOptionsControl";
|
||||
import BoxShadowOptionsControl from "./BoxShadowOptionsControl";
|
||||
|
||||
export const PropertyControls = {
|
||||
InputTextControl,
|
||||
|
|
@ -69,6 +71,8 @@ export const PropertyControls = {
|
|||
MenuItemsControl,
|
||||
IconSelectControl,
|
||||
IconAlignControl,
|
||||
BorderRadiusOptionsControl,
|
||||
BoxShadowOptionsControl,
|
||||
};
|
||||
|
||||
export type PropertyControlPropsType =
|
||||
|
|
|
|||
|
|
@ -87,6 +87,29 @@ export const Colors = {
|
|||
OPAQ_BLUE: "rgba(106, 134, 206, 0.1)",
|
||||
RATE_ACTIVE: "#FFCB45",
|
||||
RATE_INACTIVE: "#F2F2F2",
|
||||
|
||||
ICON_BUTTON_WARNING_SOLID: "#FEB811",
|
||||
ICON_BUTTON_WARNING_SOLID_HOVER: "#EFA903",
|
||||
ICON_BUTTON_WARNING_OUTLINE_HOVER: "#FFFAE9",
|
||||
ICON_BUTTON_WARNING_GHOST_HOVER: "#FBEED0",
|
||||
|
||||
ICON_BUTTON_DANGER_SOLID: "#F22B2B",
|
||||
ICON_BUTTON_DANGER_SOLID_HOVER: "#B90707",
|
||||
ICON_BUTTON_DANGER_NO_SOLID_HOVER: "#FDE4E4",
|
||||
|
||||
ICON_BUTTON_INFO_SOLID: "#6698FF",
|
||||
ICON_BUTTON_INFO_SOLID_HOVER: "#1A65FF",
|
||||
ICON_BUTTON_INFO_NO_SOLID_HOVER: "#CEDCFF",
|
||||
|
||||
ICON_BUTTON_PRIMARY_SOLID_HOVER: "#00693B",
|
||||
ICON_BUTTON_PRIMARY_OUTLINE_HOVER: "#D9FDED",
|
||||
ICON_BUTTON_PRIMARY_GHOST_HOVER: "#CBF4E2",
|
||||
|
||||
BOX_SHADOW_DEFAULT_VARIANT1: "rgba(0, 0, 0, 0.25)",
|
||||
BOX_SHADOW_DEFAULT_VARIANT2: "rgba(0, 0, 0, 0.25)",
|
||||
BOX_SHADOW_DEFAULT_VARIANT3: "rgba(0, 0, 0, 0.5)",
|
||||
BOX_SHADOW_DEFAULT_VARIANT4: "rgba(0, 0, 0, 0.25)",
|
||||
BOX_SHADOW_DEFAULT_VARIANT5: "rgba(0, 0, 0, 0.25)",
|
||||
SELECT_DISABLED: "#ced9e080",
|
||||
};
|
||||
export type Color = typeof Colors[keyof typeof Colors];
|
||||
|
|
|
|||
|
|
@ -571,6 +571,134 @@ type ColorType = {
|
|||
overlayColor: string;
|
||||
button: {
|
||||
disabledText: ShadeColor;
|
||||
boxShadow: {
|
||||
default: {
|
||||
variant1: Color;
|
||||
variant2: Color;
|
||||
variant3: Color;
|
||||
variant4: Color;
|
||||
variant5: Color;
|
||||
};
|
||||
};
|
||||
disabled: {
|
||||
bgColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
/**
|
||||
* PRIMARY style
|
||||
*/
|
||||
primary: {
|
||||
solid: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
outline: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
ghost: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor?: Color;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* WARNING style
|
||||
*/
|
||||
warning: {
|
||||
solid: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
outline: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
ghost: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor?: Color;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* DANGER style
|
||||
*/
|
||||
danger: {
|
||||
solid: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
outline: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
ghost: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor?: Color;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* INFO style
|
||||
*/
|
||||
info: {
|
||||
solid: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
outline: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
ghost: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor?: Color;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* SECONDARY style
|
||||
*/
|
||||
secondary: {
|
||||
solid: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
outline: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor: Color;
|
||||
};
|
||||
ghost: {
|
||||
bgColor?: Color;
|
||||
borderColor?: Color;
|
||||
hoverColor: Color;
|
||||
textColor?: Color;
|
||||
};
|
||||
};
|
||||
};
|
||||
tertiary: buttonVariant;
|
||||
info: buttonVariant;
|
||||
|
|
@ -1296,6 +1424,94 @@ export const dark: ColorType = {
|
|||
},
|
||||
button: {
|
||||
disabledText: darkShades[6],
|
||||
boxShadow: {
|
||||
default: {
|
||||
variant1: Colors.BOX_SHADOW_DEFAULT_VARIANT1,
|
||||
variant2: Colors.BOX_SHADOW_DEFAULT_VARIANT2,
|
||||
variant3: Colors.BOX_SHADOW_DEFAULT_VARIANT3,
|
||||
variant4: Colors.BOX_SHADOW_DEFAULT_VARIANT4,
|
||||
variant5: Colors.BOX_SHADOW_DEFAULT_VARIANT5,
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
bgColor: Colors.DARK_GRAY,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
primary: {
|
||||
solid: {
|
||||
bgColor: Colors.GREEN,
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.GREEN,
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_OUTLINE_HOVER,
|
||||
textColor: Colors.GREEN,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_GHOST_HOVER,
|
||||
},
|
||||
},
|
||||
warning: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_OUTLINE_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_GHOST_HOVER,
|
||||
},
|
||||
},
|
||||
danger: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_NO_SOLID_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_NO_SOLID_HOVER,
|
||||
},
|
||||
},
|
||||
info: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_NO_SOLID_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_NO_SOLID_HOVER,
|
||||
},
|
||||
},
|
||||
secondary: {
|
||||
solid: {
|
||||
bgColor: Colors.GRAY,
|
||||
hoverColor: Colors.CHARCOAL,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.GRAY,
|
||||
hoverColor: Colors.Gallery,
|
||||
textColor: Colors.GRAY,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.MERCURY,
|
||||
},
|
||||
},
|
||||
},
|
||||
tertiary: {
|
||||
main: "#D4D4D4",
|
||||
|
|
@ -1771,6 +1987,94 @@ export const light: ColorType = {
|
|||
},
|
||||
button: {
|
||||
disabledText: lightShades[6],
|
||||
boxShadow: {
|
||||
default: {
|
||||
variant1: Colors.BOX_SHADOW_DEFAULT_VARIANT1,
|
||||
variant2: Colors.BOX_SHADOW_DEFAULT_VARIANT2,
|
||||
variant3: Colors.BOX_SHADOW_DEFAULT_VARIANT3,
|
||||
variant4: Colors.BOX_SHADOW_DEFAULT_VARIANT4,
|
||||
variant5: Colors.BOX_SHADOW_DEFAULT_VARIANT5,
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
bgColor: Colors.DARK_GRAY,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
primary: {
|
||||
solid: {
|
||||
bgColor: Colors.GREEN,
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.GREEN,
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_OUTLINE_HOVER,
|
||||
textColor: Colors.GREEN,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_PRIMARY_GHOST_HOVER,
|
||||
},
|
||||
},
|
||||
warning: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_OUTLINE_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_WARNING_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_WARNING_GHOST_HOVER,
|
||||
},
|
||||
},
|
||||
danger: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_NO_SOLID_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_DANGER_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_DANGER_NO_SOLID_HOVER,
|
||||
},
|
||||
},
|
||||
info: {
|
||||
solid: {
|
||||
bgColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_SOLID_HOVER,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_NO_SOLID_HOVER,
|
||||
textColor: Colors.ICON_BUTTON_INFO_SOLID,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.ICON_BUTTON_INFO_NO_SOLID_HOVER,
|
||||
},
|
||||
},
|
||||
secondary: {
|
||||
solid: {
|
||||
bgColor: Colors.GRAY,
|
||||
hoverColor: Colors.CHARCOAL,
|
||||
textColor: Colors.WHITE,
|
||||
},
|
||||
outline: {
|
||||
borderColor: Colors.GRAY,
|
||||
hoverColor: Colors.Gallery,
|
||||
textColor: Colors.GRAY,
|
||||
},
|
||||
ghost: {
|
||||
hoverColor: Colors.MERCURY,
|
||||
},
|
||||
},
|
||||
},
|
||||
tertiary: {
|
||||
main: "#716E6E",
|
||||
|
|
|
|||
|
|
@ -135,6 +135,10 @@ export const HelpMap = {
|
|||
path: "/widget-reference/menu-button",
|
||||
searchKey: "Menu Button",
|
||||
},
|
||||
ICON_BUTTON_WIDGET: {
|
||||
path: "/widget-reference/icon-button",
|
||||
searchKey: "Icon Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const HelpBaseURL = "https://docs.appsmith.com";
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export enum WidgetTypes {
|
|||
IFRAME_WIDGET = "IFRAME_WIDGET",
|
||||
DIVIDER_WIDGET = "DIVIDER_WIDGET",
|
||||
MENU_BUTTON_WIDGET = "MENU_BUTTON_WIDGET",
|
||||
ICON_BUTTON_WIDGET = "ICON_BUTTON_WIDGET",
|
||||
}
|
||||
|
||||
export type WidgetType = keyof typeof WidgetTypes;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,15 @@ import { ReactComponent as DividerCapAllIcon } from "assets/icons/control/divide
|
|||
import { ReactComponent as TrendingFlat } from "assets/icons/ads/trending-flat.svg";
|
||||
import { ReactComponent as AlignLeftIcon } from "assets/icons/control/align_left.svg";
|
||||
import { ReactComponent as AlignRightIcon } from "assets/icons/control/align_right.svg";
|
||||
import { ReactComponent as BorderRadiusSharpIcon } from "assets/icons/control/border-radius-sharp.svg";
|
||||
import { ReactComponent as BorderRadiusRoundedIcon } from "assets/icons/control/border-radius-rounded.svg";
|
||||
import { ReactComponent as BorderRadiusCircleIcon } from "assets/icons/control/border-radius-circle.svg";
|
||||
import { ReactComponent as BoxShadowNoneIcon } from "assets/icons/control/box-shadow-none.svg";
|
||||
import { ReactComponent as BoxShadowVariant1Icon } from "assets/icons/control/box-shadow-variant1.svg";
|
||||
import { ReactComponent as BoxShadowVariant2Icon } from "assets/icons/control/box-shadow-variant2.svg";
|
||||
import { ReactComponent as BoxShadowVariant3Icon } from "assets/icons/control/box-shadow-variant3.svg";
|
||||
import { ReactComponent as BoxShadowVariant4Icon } from "assets/icons/control/box-shadow-variant4.svg";
|
||||
import { ReactComponent as BoxShadowVariant5Icon } from "assets/icons/control/box-shadow-variant5.svg";
|
||||
import PlayIcon from "assets/icons/control/play-icon.png";
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
|
@ -316,6 +325,51 @@ export const ControlIcons: {
|
|||
<AlignRightIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BORDER_RADIUS_SHARP: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BorderRadiusSharpIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BORDER_RADIUS_ROUNDED: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BorderRadiusRoundedIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BORDER_RADIUS_CIRCLE: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BorderRadiusCircleIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_NONE: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowNoneIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_VARIANT1: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowVariant1Icon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_VARIANT2: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowVariant2Icon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_VARIANT3: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowVariant3Icon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_VARIANT4: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowVariant4Icon />
|
||||
</IconWrapper>
|
||||
),
|
||||
BOX_SHADOW_VARIANT5: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<BoxShadowVariant5Icon />
|
||||
</IconWrapper>
|
||||
),
|
||||
};
|
||||
|
||||
export type ControlIconName = keyof typeof ControlIcons;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import { ReactComponent as RatingIcon } from "assets/icons/widget/rating.svg";
|
|||
import { ReactComponent as EmbedIcon } from "assets/icons/widget/embed.svg";
|
||||
import { ReactComponent as DividerIcon } from "assets/icons/widget/divider.svg";
|
||||
import { ReactComponent as MenuButtonIcon } from "assets/icons/widget/menu-button.svg";
|
||||
import { ReactComponent as IconButtonIcon } from "assets/icons/widget/icon-button.svg";
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
|
|
@ -173,6 +174,11 @@ export const WidgetIcons: {
|
|||
<MenuButtonIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
ICON_BUTTON_WIDGET: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<IconButtonIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
};
|
||||
|
||||
export type WidgetIcon = typeof WidgetIcons[keyof typeof WidgetIcons];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { IconNames } from "@blueprintjs/icons";
|
||||
|
||||
import { WidgetConfigReducerState } from "reducers/entityReducers/widgetConfigReducer";
|
||||
import { WidgetProps } from "widgets/BaseWidget";
|
||||
import moment from "moment-timezone";
|
||||
|
|
@ -9,6 +11,13 @@ import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReduc
|
|||
import { getDynamicBindings } from "utils/DynamicBindingUtils";
|
||||
import { Colors } from "constants/Colors";
|
||||
import FileDataTypes from "widgets/FileDataTypes";
|
||||
import {
|
||||
ButtonBorderRadiusTypes,
|
||||
ButtonBoxShadowTypes,
|
||||
ButtonStyleTypes,
|
||||
ButtonVariantTypes,
|
||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||
|
||||
/*
|
||||
********************************{Grid Density Migration}*********************************
|
||||
*/
|
||||
|
|
@ -1244,6 +1253,19 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
columns: 4 * GRID_DENSITY_MIGRATION_V1,
|
||||
widgetName: "MenuButton",
|
||||
},
|
||||
[WidgetTypes.ICON_BUTTON_WIDGET]: {
|
||||
iconName: IconNames.PLUS,
|
||||
borderRadius: ButtonBorderRadiusTypes.CIRCLE,
|
||||
boxShadow: ButtonBoxShadowTypes.NONE,
|
||||
buttonStyle: ButtonStyleTypes.PRIMARY,
|
||||
buttonVariant: ButtonVariantTypes.SOLID,
|
||||
isDisabled: false,
|
||||
isVisible: true,
|
||||
rows: 1 * GRID_DENSITY_MIGRATION_V1,
|
||||
columns: 1 * GRID_DENSITY_MIGRATION_V1,
|
||||
widgetName: "IconButton",
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
configVersion: 1,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -130,6 +130,11 @@ const WidgetSidebarResponse: WidgetCardProps[] = [
|
|||
widgetCardName: "Menu Button",
|
||||
key: generateReactKey(),
|
||||
},
|
||||
{
|
||||
type: "ICON_BUTTON_WIDGET",
|
||||
widgetCardName: "Icon Button",
|
||||
key: generateReactKey(),
|
||||
},
|
||||
];
|
||||
|
||||
export default WidgetSidebarResponse;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { DividerWidgetProps } from "widgets/DividerWidget";
|
|||
import { RateWidgetProps } from "widgets/RateWidget";
|
||||
import { IframeWidgetProps } from "widgets/IframeWidget";
|
||||
import { MenuButtonWidgetProps } from "widgets/MenuButtonWidget";
|
||||
import { IconButtonWidgetProps } from "widgets/IconButtonWidget";
|
||||
|
||||
const initialState: WidgetConfigReducerState = WidgetConfigResponse;
|
||||
|
||||
|
|
@ -92,6 +93,7 @@ export interface WidgetConfigReducerState {
|
|||
RATE_WIDGET: Partial<RateWidgetProps> & WidgetConfigProps;
|
||||
IFRAME_WIDGET: Partial<IframeWidgetProps> & WidgetConfigProps;
|
||||
MENU_BUTTON_WIDGET: Partial<MenuButtonWidgetProps> & WidgetConfigProps;
|
||||
ICON_BUTTON_WIDGET: Partial<IconButtonWidgetProps> & WidgetConfigProps;
|
||||
};
|
||||
configVersion: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,10 @@ import MenuButtonWidget, {
|
|||
MenuButtonWidgetProps,
|
||||
ProfiledMenuButtonWidget,
|
||||
} from "widgets/MenuButtonWidget";
|
||||
import IconButtonWidget, {
|
||||
IconButtonWidgetProps,
|
||||
ProfiledIconButtonWidget,
|
||||
} from "widgets/IconButtonWidget";
|
||||
|
||||
export default class WidgetBuilderRegistry {
|
||||
static registerWidgetBuilders() {
|
||||
|
|
@ -538,5 +542,18 @@ export default class WidgetBuilderRegistry {
|
|||
MenuButtonWidget.getMetaPropertiesMap(),
|
||||
MenuButtonWidget.getPropertyPaneConfig(),
|
||||
);
|
||||
|
||||
WidgetFactory.registerWidgetBuilder(
|
||||
WidgetTypes.ICON_BUTTON_WIDGET,
|
||||
{
|
||||
buildWidget(widgetData: IconButtonWidgetProps): JSX.Element {
|
||||
return <ProfiledIconButtonWidget {...widgetData} />;
|
||||
},
|
||||
},
|
||||
IconButtonWidget.getDerivedPropertiesMap(),
|
||||
IconButtonWidget.getDefaultPropertiesMap(),
|
||||
IconButtonWidget.getMetaPropertiesMap(),
|
||||
IconButtonWidget.getPropertyPaneConfig(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,6 +287,12 @@ export const entityDefinitions = {
|
|||
isVisible: isVisible,
|
||||
label: "string",
|
||||
},
|
||||
ICON_BUTTON_WIDGET: {
|
||||
"!doc":
|
||||
"Icon button widget is just an icon, along with all other button properties.",
|
||||
"!url": "https://docs.appsmith.com/widget-reference/icon-button",
|
||||
isVisible: isVisible,
|
||||
},
|
||||
};
|
||||
|
||||
export const GLOBAL_DEFS = {
|
||||
|
|
|
|||
236
app/client/src/widgets/IconButtonWidget.tsx
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
import * as React from "react";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { IconName } from "@blueprintjs/icons";
|
||||
|
||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||
import { WidgetType, WidgetTypes } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
|
||||
import IconButtonComponent, {
|
||||
ButtonBorderRadius,
|
||||
ButtonBoxShadow,
|
||||
ButtonStyle,
|
||||
ButtonVariant,
|
||||
} from "components/designSystems/appsmith/IconButtonComponent";
|
||||
|
||||
export interface IconButtonWidgetProps extends WidgetProps {
|
||||
iconName?: IconName;
|
||||
buttonStyle: ButtonStyle;
|
||||
buttonVariant: ButtonVariant;
|
||||
borderRadius: ButtonBorderRadius;
|
||||
boxShadow: ButtonBoxShadow;
|
||||
boxShadowColor: string;
|
||||
isDisabled: boolean;
|
||||
isVisible: boolean;
|
||||
onClick?: string;
|
||||
}
|
||||
|
||||
class IconButtonWidget extends BaseWidget<IconButtonWidgetProps, WidgetState> {
|
||||
static getPropertyPaneConfig() {
|
||||
return [
|
||||
{
|
||||
sectionName: "General",
|
||||
children: [
|
||||
{
|
||||
propertyName: "iconName",
|
||||
label: "Icon",
|
||||
helpText: "Sets the icon to be used for the icon button",
|
||||
controlType: "ICON_SELECT",
|
||||
isBindProperty: false,
|
||||
isTriggerProperty: false,
|
||||
validation: { type: ValidationTypes.TEXT },
|
||||
},
|
||||
{
|
||||
propertyName: "buttonStyle",
|
||||
label: "Button Style",
|
||||
controlType: "DROP_DOWN",
|
||||
helpText: "Sets the style of the icon button",
|
||||
options: [
|
||||
{
|
||||
label: "Primary",
|
||||
value: "PRIMARY",
|
||||
},
|
||||
{
|
||||
label: "Warning",
|
||||
value: "WARNING",
|
||||
},
|
||||
{
|
||||
label: "Danger",
|
||||
value: "DANGER",
|
||||
},
|
||||
{
|
||||
label: "Info",
|
||||
value: "INFO",
|
||||
},
|
||||
{
|
||||
label: "Secondary",
|
||||
value: "SECONDARY",
|
||||
},
|
||||
],
|
||||
isBindProperty: false,
|
||||
isTriggerProperty: false,
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
isBindProperty: false,
|
||||
isTriggerProperty: false,
|
||||
},
|
||||
{
|
||||
propertyName: "borderRadius",
|
||||
label: "Border Radius",
|
||||
helpText:
|
||||
"Rounds the corners of the icon button's outer border edge",
|
||||
controlType: "BORDER_RADIUS_OPTIONS",
|
||||
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,
|
||||
},
|
||||
{
|
||||
propertyName: "isDisabled",
|
||||
helpText: "Disables input to the widget",
|
||||
label: "Disabled",
|
||||
controlType: "SWITCH",
|
||||
isJSConvertible: true,
|
||||
isBindProperty: true,
|
||||
isTriggerProperty: false,
|
||||
validation: { type: ValidationTypes.BOOLEAN },
|
||||
},
|
||||
{
|
||||
propertyName: "isVisible",
|
||||
helpText: "Controls the visibility of the widget",
|
||||
label: "Visible",
|
||||
controlType: "SWITCH",
|
||||
isJSConvertible: true,
|
||||
isBindProperty: true,
|
||||
isTriggerProperty: false,
|
||||
validation: { type: ValidationTypes.BOOLEAN },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
sectionName: "Actions",
|
||||
children: [
|
||||
{
|
||||
helpText: "Triggers an action when the button is clicked",
|
||||
propertyName: "onClick",
|
||||
label: "onClick",
|
||||
controlType: "ACTION_SELECTOR",
|
||||
isJSConvertible: true,
|
||||
isBindProperty: true,
|
||||
isTriggerProperty: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
borderRadius,
|
||||
boxShadow,
|
||||
boxShadowColor,
|
||||
buttonStyle,
|
||||
buttonVariant,
|
||||
iconName,
|
||||
isDisabled,
|
||||
isVisible,
|
||||
widgetId,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<IconButtonComponent
|
||||
borderRadius={borderRadius}
|
||||
boxShadow={boxShadow}
|
||||
boxShadowColor={boxShadowColor}
|
||||
buttonStyle={buttonStyle}
|
||||
buttonVariant={buttonVariant}
|
||||
height={
|
||||
(this.props.bottomRow - this.props.topRow) * this.props.parentRowSpace
|
||||
}
|
||||
iconName={iconName}
|
||||
isDisabled={isDisabled}
|
||||
isVisible={isVisible}
|
||||
onClick={this.handleClick}
|
||||
widgetId={widgetId}
|
||||
width={
|
||||
(this.props.rightColumn - this.props.leftColumn) *
|
||||
this.props.parentColumnSpace
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
getWidgetType(): WidgetType {
|
||||
return WidgetTypes.ICON_BUTTON_WIDGET;
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
const { onClick } = this.props;
|
||||
|
||||
if (onClick) {
|
||||
super.executeAction({
|
||||
triggerPropertyName: "onClick",
|
||||
dynamicString: onClick,
|
||||
event: {
|
||||
type: EventType.ON_CLICK,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default IconButtonWidget;
|
||||
export const ProfiledIconButtonWidget = Sentry.withProfiler(IconButtonWidget);
|
||||