Merge branch 'release' of https://github.com/appsmithorg/appsmith into release
This commit is contained in:
commit
c42fb00861
5
app/client/.storybook/addons.js
Normal file
5
app/client/.storybook/addons.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import "@storybook/addon-knobs/register";
|
||||||
|
import "@storybook/addon-notes/register";
|
||||||
|
import "@storybook/addon-contexts/register";
|
||||||
|
import "storybook-addon-designs/register";
|
||||||
|
import '@storybook/addon-backgrounds/register';
|
||||||
13
app/client/.storybook/config.js
Normal file
13
app/client/.storybook/config.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { configure, addDecorator, addParameters } from "@storybook/react";
|
||||||
|
import { withContexts } from "@storybook/addon-contexts/react";
|
||||||
|
import { contexts } from "./configs/contexts";
|
||||||
|
import { } from '@storybook/react'; // <- or your storybook framework
|
||||||
|
|
||||||
|
addDecorator(withContexts(contexts));
|
||||||
|
addParameters({
|
||||||
|
backgrounds: [
|
||||||
|
{ name: 'dark', value: '#090707', default: true },
|
||||||
|
{ name: 'light', value: '#fff' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
configure(require.context("../src", true, /\.stories\.tsx$/), module);
|
||||||
10
app/client/.storybook/configs/contexts.js
Normal file
10
app/client/.storybook/configs/contexts.js
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { ThemeProvider, theme } from "../../src/constants/DefaultTheme";
|
||||||
|
|
||||||
|
export const contexts = [
|
||||||
|
{
|
||||||
|
icon: "box",
|
||||||
|
title: "Themes",
|
||||||
|
components: [ThemeProvider],
|
||||||
|
params: [{ name: "default", props: { theme: theme } }],
|
||||||
|
},
|
||||||
|
];
|
||||||
18
app/client/.storybook/presets.js
Normal file
18
app/client/.storybook/presets.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
const path = require("path");
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
name: "@storybook/preset-create-react-app",
|
||||||
|
options: {
|
||||||
|
tsDocgenLoaderOptions: {
|
||||||
|
tsconfigPath: path.resolve(__dirname, "../tsconfig.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "@storybook/addon-docs/preset",
|
||||||
|
options: {
|
||||||
|
configureJSX: true,
|
||||||
|
sourceLoaderOptions: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
@ -105,6 +105,7 @@
|
||||||
"reselect": "^4.0.0",
|
"reselect": "^4.0.0",
|
||||||
"shallowequal": "^1.1.0",
|
"shallowequal": "^1.1.0",
|
||||||
"styled-components": "^4.1.3",
|
"styled-components": "^4.1.3",
|
||||||
|
"styled-system": "^5.1.5",
|
||||||
"tern": "^0.21.0",
|
"tern": "^0.21.0",
|
||||||
"tinycolor2": "^1.4.1",
|
"tinycolor2": "^1.4.1",
|
||||||
"toposort": "^2.0.2",
|
"toposort": "^2.0.2",
|
||||||
|
|
@ -125,7 +126,9 @@
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"start-prod": "REACT_APP_ENVIRONMENT=PRODUCTION craco start",
|
"start-prod": "REACT_APP_ENVIRONMENT=PRODUCTION craco start",
|
||||||
"cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open",
|
"cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open",
|
||||||
"test:unit": "$(npm bin)/jest -b --colors"
|
"test:unit": "$(npm bin)/jest -b --colors",
|
||||||
|
"storybook": "start-storybook -p 9009 -s public",
|
||||||
|
"build-storybook": "build-storybook -s public"
|
||||||
},
|
},
|
||||||
"resolution": {
|
"resolution": {
|
||||||
"jest": "24.8.0"
|
"jest": "24.8.0"
|
||||||
|
|
@ -141,12 +144,23 @@
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.7.4",
|
"@babel/core": "^7.7.4",
|
||||||
|
"@storybook/addon-actions": "^5.3.19",
|
||||||
|
"@storybook/addon-backgrounds": "^5.3.19",
|
||||||
|
"@storybook/addon-contexts": "^5.3.19",
|
||||||
|
"@storybook/addon-docs": "^5.3.19",
|
||||||
|
"@storybook/addon-knobs": "^5.3.19",
|
||||||
|
"@storybook/addon-links": "^5.3.19",
|
||||||
|
"@storybook/addon-notes": "^5.3.19",
|
||||||
|
"@storybook/addons": "^5.3.19",
|
||||||
|
"@storybook/preset-create-react-app": "^3.1.4",
|
||||||
|
"@storybook/react": "^5.3.19",
|
||||||
"@types/codemirror": "^0.0.96",
|
"@types/codemirror": "^0.0.96",
|
||||||
"@types/jest": "^24.0.22",
|
"@types/jest": "^24.0.22",
|
||||||
"@types/react-beautiful-dnd": "^11.0.4",
|
"@types/react-beautiful-dnd": "^11.0.4",
|
||||||
"@types/react-select": "^3.0.5",
|
"@types/react-select": "^3.0.5",
|
||||||
"@types/react-tabs": "^2.3.1",
|
"@types/react-tabs": "^2.3.1",
|
||||||
"@types/redux-form": "^8.1.9",
|
"@types/redux-form": "^8.1.9",
|
||||||
|
"@types/styled-system": "^5.1.9",
|
||||||
"@types/tern": "0.22.0",
|
"@types/tern": "0.22.0",
|
||||||
"@types/toposort": "^2.0.3",
|
"@types/toposort": "^2.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||||
|
|
@ -174,6 +188,7 @@
|
||||||
"redux-devtools": "^3.5.0",
|
"redux-devtools": "^3.5.0",
|
||||||
"redux-devtools-extension": "^2.13.8",
|
"redux-devtools-extension": "^2.13.8",
|
||||||
"source-map-explorer": "^2.4.2",
|
"source-map-explorer": "^2.4.2",
|
||||||
|
"storybook-addon-designs": "^5.4.0",
|
||||||
"ts-jest": "^24.3.0",
|
"ts-jest": "^24.3.0",
|
||||||
"webpack-merge": "^4.2.2",
|
"webpack-merge": "^4.2.2",
|
||||||
"workbox-webpack-plugin": "^5.1.2"
|
"workbox-webpack-plugin": "^5.1.2"
|
||||||
|
|
|
||||||
3
app/client/src/assets/icons/ads/delete.svg
Normal file
3
app/client/src/assets/icons/ads/delete.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 3.33333H17V4.66667H3V3.33333H6.5L7.5003 2H12.4997L13.5 3.33333ZM15.0167 18H4.98333L4.4 6H15.6L15.0167 18Z" fill="#9F9F9F"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 282 B |
3
app/client/src/assets/icons/ads/user.svg
Normal file
3
app/client/src/assets/icons/ads/user.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5483 6.04545C13.5483 8.00355 11.9186 9.59091 9.90829 9.59091C7.89798 9.59091 6.26829 8.00355 6.26829 6.04545C6.26829 4.08735 7.89798 2.5 9.90829 2.5C11.9186 2.5 13.5483 4.08735 13.5483 6.04545ZM6.37988 10.7402C4.51323 10.7402 3 12.2535 3 14.1201C3 15.9868 4.51323 17.5 6.37988 17.5H13.6201C15.4868 17.5 17 15.9868 17 14.1201C17 12.2535 15.4868 10.7402 13.6201 10.7402H6.37988Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 549 B |
380
app/client/src/components/ads/Button.tsx
Normal file
380
app/client/src/components/ads/Button.tsx
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
import React from "react";
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { IconName, Icon } from "./Icon";
|
||||||
|
import Spinner from "./Spinner";
|
||||||
|
import {
|
||||||
|
mediumButton,
|
||||||
|
smallButton,
|
||||||
|
largeButton,
|
||||||
|
Theme,
|
||||||
|
} from "../../constants/DefaultTheme";
|
||||||
|
|
||||||
|
export type ThemeProp = {
|
||||||
|
theme: Theme;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum Category {
|
||||||
|
primary = "primary",
|
||||||
|
secondary = "secondary",
|
||||||
|
tertiary = "tertiary",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Variant {
|
||||||
|
success = "success",
|
||||||
|
info = "info",
|
||||||
|
warning = "warning",
|
||||||
|
danger = "danger",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Size {
|
||||||
|
small = "small",
|
||||||
|
medium = "medium",
|
||||||
|
large = "large",
|
||||||
|
}
|
||||||
|
|
||||||
|
type stateStyleType = {
|
||||||
|
bgColorPrimary: string;
|
||||||
|
borderColorPrimary: string;
|
||||||
|
txtColorPrimary: string;
|
||||||
|
bgColorSecondary: string;
|
||||||
|
borderColorSecondary: string;
|
||||||
|
txtColorSecondary: string;
|
||||||
|
bgColorTertiary: string;
|
||||||
|
borderColorTertiary: string;
|
||||||
|
txtColorTertiary: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BtnColorType = {
|
||||||
|
bgColor: string;
|
||||||
|
txtColor: string;
|
||||||
|
border: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BtnFontType = {
|
||||||
|
buttonFont: any;
|
||||||
|
padding: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ButtonProps = CommonComponentProps & {
|
||||||
|
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||||
|
text?: string;
|
||||||
|
category?: Category;
|
||||||
|
variant?: Variant;
|
||||||
|
icon?: IconName;
|
||||||
|
size?: Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
function hexToRgb(
|
||||||
|
hex: string,
|
||||||
|
): {
|
||||||
|
r: number;
|
||||||
|
g: number;
|
||||||
|
b: number;
|
||||||
|
} {
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result
|
||||||
|
? {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16),
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
r: -1,
|
||||||
|
g: -1,
|
||||||
|
b: -1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// const darken = (color: Color, intensity: number) => {
|
||||||
|
// return new tinycolor(color).darken(intensity).toString();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const lighten = (color: Color, intensity: number) => {
|
||||||
|
// return new tinycolor(color).lighten(intensity).toString();
|
||||||
|
// };
|
||||||
|
|
||||||
|
const hexToRgba = (color: string, alpha: number) => {
|
||||||
|
const value = hexToRgb(color);
|
||||||
|
return `rgba(${value.r}, ${value.g}, ${value.b}, ${alpha});`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stateStyles = (
|
||||||
|
props: ThemeProp & ButtonProps,
|
||||||
|
state: string,
|
||||||
|
): stateStyleType => {
|
||||||
|
let bgColorPrimary,
|
||||||
|
borderColorPrimary,
|
||||||
|
txtColorPrimary,
|
||||||
|
bgColorSecondary,
|
||||||
|
borderColorSecondary,
|
||||||
|
txtColorSecondary,
|
||||||
|
bgColorTertiary,
|
||||||
|
borderColorTertiary,
|
||||||
|
txtColorTertiary;
|
||||||
|
|
||||||
|
if (props.isLoading || props.isDisabled) {
|
||||||
|
switch (props.category) {
|
||||||
|
case Category.primary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorPrimary = props.theme.colors[props.variant].darkest;
|
||||||
|
borderColorPrimary = props.theme.colors[props.variant].darkest;
|
||||||
|
}
|
||||||
|
txtColorPrimary = props.theme.colors.blackShades[6];
|
||||||
|
break;
|
||||||
|
case Category.secondary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorSecondary = props.theme.colors[props.variant].darkest;
|
||||||
|
borderColorSecondary = props.theme.colors[props.variant].darker;
|
||||||
|
}
|
||||||
|
txtColorSecondary = props.theme.colors.blackShades[6];
|
||||||
|
break;
|
||||||
|
case Category.tertiary:
|
||||||
|
bgColorTertiary = props.theme.colors.tertiary.darker;
|
||||||
|
borderColorTertiary = props.theme.colors.tertiary.dark;
|
||||||
|
txtColorTertiary = props.theme.colors.blackShades[6];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (state === "main") {
|
||||||
|
switch (props.category) {
|
||||||
|
case Category.primary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorPrimary = props.theme.colors[props.variant].main;
|
||||||
|
borderColorPrimary = props.theme.colors[props.variant].main;
|
||||||
|
}
|
||||||
|
txtColorPrimary = props.theme.colors.blackShades[9];
|
||||||
|
break;
|
||||||
|
case Category.secondary:
|
||||||
|
if (props.variant) {
|
||||||
|
borderColorSecondary = props.theme.colors[props.variant].main;
|
||||||
|
txtColorSecondary = props.theme.colors[props.variant].main;
|
||||||
|
}
|
||||||
|
bgColorSecondary = "transparent";
|
||||||
|
break;
|
||||||
|
case Category.tertiary:
|
||||||
|
bgColorTertiary = "transparent";
|
||||||
|
borderColorTertiary = props.theme.colors.tertiary.main;
|
||||||
|
txtColorTertiary = props.theme.colors.tertiary.main;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (state === "hover") {
|
||||||
|
switch (props.category) {
|
||||||
|
case Category.primary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorPrimary = props.theme.colors[props.variant].dark;
|
||||||
|
borderColorPrimary = props.theme.colors[props.variant].dark;
|
||||||
|
}
|
||||||
|
txtColorPrimary = props.theme.colors.blackShades[9];
|
||||||
|
break;
|
||||||
|
case Category.secondary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorSecondary = hexToRgba(
|
||||||
|
props.theme.colors[props.variant].main,
|
||||||
|
0.1,
|
||||||
|
);
|
||||||
|
txtColorSecondary = props.theme.colors[props.variant].main;
|
||||||
|
borderColorSecondary = props.theme.colors[props.variant].main;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Category.tertiary:
|
||||||
|
bgColorTertiary = hexToRgba(props.theme.colors.tertiary.main, 0.1);
|
||||||
|
borderColorTertiary = props.theme.colors.tertiary.main;
|
||||||
|
txtColorTertiary = props.theme.colors.tertiary.main;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (state === "active") {
|
||||||
|
switch (props.category) {
|
||||||
|
case Category.primary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorPrimary = props.theme.colors[props.variant].dark;
|
||||||
|
borderColorPrimary = props.theme.colors[props.variant].main;
|
||||||
|
}
|
||||||
|
txtColorPrimary = props.theme.colors.blackShades[9];
|
||||||
|
break;
|
||||||
|
case Category.secondary:
|
||||||
|
if (props.variant) {
|
||||||
|
bgColorSecondary = hexToRgba(
|
||||||
|
props.theme.colors[props.variant].main,
|
||||||
|
0.1,
|
||||||
|
);
|
||||||
|
txtColorSecondary = props.theme.colors[props.variant].light;
|
||||||
|
borderColorSecondary = props.theme.colors[props.variant].light;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Category.tertiary:
|
||||||
|
bgColorTertiary = hexToRgba(props.theme.colors.tertiary.main, 0.1);
|
||||||
|
borderColorTertiary = props.theme.colors.tertiary.light;
|
||||||
|
txtColorTertiary = props.theme.colors.tertiary.light;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bgColorPrimary,
|
||||||
|
borderColorPrimary,
|
||||||
|
txtColorPrimary,
|
||||||
|
bgColorSecondary,
|
||||||
|
borderColorSecondary,
|
||||||
|
txtColorSecondary,
|
||||||
|
bgColorTertiary,
|
||||||
|
borderColorTertiary,
|
||||||
|
txtColorTertiary,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const btnColorStyles = (
|
||||||
|
props: ThemeProp & ButtonProps,
|
||||||
|
state: string,
|
||||||
|
): BtnColorType => {
|
||||||
|
let bgColor = "",
|
||||||
|
txtColor = "",
|
||||||
|
border = "";
|
||||||
|
switch (props.category) {
|
||||||
|
case Category.primary:
|
||||||
|
bgColor = stateStyles(props, state).bgColorPrimary;
|
||||||
|
txtColor = stateStyles(props, state).txtColorPrimary;
|
||||||
|
border = `2px solid ${stateStyles(props, state).borderColorPrimary}`;
|
||||||
|
break;
|
||||||
|
case Category.secondary:
|
||||||
|
bgColor = stateStyles(props, state).bgColorSecondary;
|
||||||
|
txtColor = stateStyles(props, state).txtColorSecondary;
|
||||||
|
border = `2px solid ${stateStyles(props, state).borderColorSecondary}`;
|
||||||
|
break;
|
||||||
|
case Category.tertiary:
|
||||||
|
bgColor = stateStyles(props, state).bgColorTertiary;
|
||||||
|
txtColor = stateStyles(props, state).txtColorTertiary;
|
||||||
|
border = `2px solid ${stateStyles(props, state).borderColorTertiary}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return { bgColor, txtColor, border };
|
||||||
|
};
|
||||||
|
|
||||||
|
const btnFontStyles = (props: ThemeProp & ButtonProps): BtnFontType => {
|
||||||
|
let buttonFont,
|
||||||
|
padding = "";
|
||||||
|
switch (props.size) {
|
||||||
|
case Size.small:
|
||||||
|
buttonFont = smallButton;
|
||||||
|
padding =
|
||||||
|
!props.text && props.icon
|
||||||
|
? `${props.theme.spaces[1]}px ${props.theme.spaces[1]}px`
|
||||||
|
: `${props.theme.spaces[1]}px ${props.theme.spaces[6]}px ${props.theme
|
||||||
|
.spaces[1] - 1}px`;
|
||||||
|
break;
|
||||||
|
case Size.medium:
|
||||||
|
buttonFont = mediumButton;
|
||||||
|
padding =
|
||||||
|
!props.text && props.icon
|
||||||
|
? `${props.theme.spaces[2]}px ${props.theme.spaces[2]}px`
|
||||||
|
: `${props.theme.spaces[3] - 1}px ${props.theme.spaces[7]}px`;
|
||||||
|
break;
|
||||||
|
case Size.large:
|
||||||
|
buttonFont = largeButton;
|
||||||
|
padding =
|
||||||
|
!props.text && props.icon
|
||||||
|
? `${props.theme.spaces[5] - 1}px ${props.theme.spaces[5] - 1}px`
|
||||||
|
: `${props.theme.spaces[5] - 1}px ${props.theme.spaces[12] - 4}px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return { buttonFont, padding };
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledButton = styled("button")<ThemeProp & ButtonProps>`
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: ${props => btnColorStyles(props, "main").bgColor};
|
||||||
|
color: ${props => btnColorStyles(props, "main").txtColor};
|
||||||
|
border: ${props => btnColorStyles(props, "main").border};
|
||||||
|
border-radius: ${props => props.theme.radii[0]};
|
||||||
|
font-family: ${props => props.theme.fonts[3]};
|
||||||
|
${props => btnFontStyles(props).buttonFont};
|
||||||
|
padding: ${props => btnFontStyles(props).padding};
|
||||||
|
.ads-icon {
|
||||||
|
margin-right: ${props =>
|
||||||
|
props.text && props.icon ? `${props.theme.spaces[4]}px` : `0`}
|
||||||
|
path {
|
||||||
|
fill: ${props => btnColorStyles(props, "main").txtColor};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: ${props => btnColorStyles(props, "hover").bgColor};
|
||||||
|
color: ${props => btnColorStyles(props, "hover").txtColor};
|
||||||
|
border: ${props => btnColorStyles(props, "hover").border};
|
||||||
|
cursor: ${props =>
|
||||||
|
props.isLoading || props.isDisabled ? `not-allowed` : `pointer`};
|
||||||
|
.ads-icon {
|
||||||
|
margin-right: ${props =>
|
||||||
|
props.text && props.icon ? `${props.theme.spaces[4]}px` : `0`}
|
||||||
|
path {
|
||||||
|
fill: ${props => btnColorStyles(props, "hover").txtColor};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font-style: normal;
|
||||||
|
&:active {
|
||||||
|
background-color: ${props => btnColorStyles(props, "active").bgColor};
|
||||||
|
color: ${props => btnColorStyles(props, "active").txtColor};
|
||||||
|
border: ${props => btnColorStyles(props, "active").border};
|
||||||
|
cursor: ${props =>
|
||||||
|
props.isLoading || props.isDisabled ? `not-allowed` : `pointer`};
|
||||||
|
.ads-icon {
|
||||||
|
path {
|
||||||
|
fill: ${props => btnColorStyles(props, "active").txtColor};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
.new-spinner {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
Button.defaultProps = {
|
||||||
|
category: Category.primary,
|
||||||
|
variant: Variant.success,
|
||||||
|
size: Size.small,
|
||||||
|
isLoading: false,
|
||||||
|
isDisabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VisibilityWrapper = styled.div`
|
||||||
|
visibility: hidden;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function Button(props: ButtonProps) {
|
||||||
|
const IconLoadingState = (
|
||||||
|
<Icon name={props.icon} size={props.size} invisible={true} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const TextLoadingState = <VisibilityWrapper>{props.text}</VisibilityWrapper>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledButton
|
||||||
|
data-cy={props.cypressSelector}
|
||||||
|
{...props}
|
||||||
|
onClick={(e: React.MouseEvent<HTMLElement>) =>
|
||||||
|
props.onClick && props.onClick(e)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.icon ? (
|
||||||
|
props.isLoading ? (
|
||||||
|
IconLoadingState
|
||||||
|
) : (
|
||||||
|
<Icon name={props.icon} size={props.size} />
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{props.text ? (props.isLoading ? TextLoadingState : props.text) : null}
|
||||||
|
|
||||||
|
{props.isLoading ? <Spinner size={props.size} /> : null}
|
||||||
|
</StyledButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Button;
|
||||||
10
app/client/src/components/ads/Callout.tsx
Normal file
10
app/client/src/components/ads/Callout.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
import { Variant } from "./Button";
|
||||||
|
|
||||||
|
type CalloutProps = CommonComponentProps & {
|
||||||
|
variant?: Variant; //default info
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Callout(props: CalloutProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
14
app/client/src/components/ads/Checkbox.tsx
Normal file
14
app/client/src/components/ads/Checkbox.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type CheckboxProps = CommonComponentProps & {
|
||||||
|
label: string;
|
||||||
|
isChecked: boolean;
|
||||||
|
onCheckChange: (isChecked: boolean) => void;
|
||||||
|
isLoading: boolean;
|
||||||
|
align: "left" | "right";
|
||||||
|
cypressSelector?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Checkbox(props: CheckboxProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
9
app/client/src/components/ads/ColorSelector.tsx
Normal file
9
app/client/src/components/ads/ColorSelector.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type ColorSelectorProps = CommonComponentProps & {
|
||||||
|
onSelect: (hex: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ColorSelector(props: ColorSelectorProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
36
app/client/src/components/ads/Dropdown.tsx
Normal file
36
app/client/src/components/ads/Dropdown.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
import { IconName } from "./Icon";
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type DropdownOption = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
id?: string;
|
||||||
|
icon: IconName; // Create an icon library
|
||||||
|
onSelect?: (option: DropdownOption) => void;
|
||||||
|
children?: DropdownOption[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum DropdownDisplayType {
|
||||||
|
TAGS = "TAGS",
|
||||||
|
CHECKBOXES = "CHECKBOXES",
|
||||||
|
}
|
||||||
|
|
||||||
|
type DropdownProps = CommonComponentProps & {
|
||||||
|
options: DropdownOption[];
|
||||||
|
selectHandler: (selectedValue: string) => void;
|
||||||
|
selected?: DropdownOption;
|
||||||
|
multiselectDisplayType?: DropdownDisplayType;
|
||||||
|
checked?: boolean;
|
||||||
|
multi?: boolean;
|
||||||
|
autocomplete?: boolean;
|
||||||
|
addItem?: {
|
||||||
|
displayText: string;
|
||||||
|
addItemHandler: (name: string) => void;
|
||||||
|
};
|
||||||
|
toggle?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Button(props: DropdownProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
26
app/client/src/components/ads/EditableInput.tsx
Normal file
26
app/client/src/components/ads/EditableInput.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
export enum EditInteractionKind {
|
||||||
|
SINGLE,
|
||||||
|
DOUBLE,
|
||||||
|
}
|
||||||
|
|
||||||
|
type EditableTextProps = CommonComponentProps & {
|
||||||
|
type: "text" | "password" | "email" | "phone" | "date";
|
||||||
|
defaultValue: string;
|
||||||
|
onTextChanged: (value: string) => void;
|
||||||
|
placeholder: string;
|
||||||
|
cypressSelector?: string;
|
||||||
|
valueTransform?: (value: string) => string;
|
||||||
|
isEditingDefault?: boolean;
|
||||||
|
forceDefault?: boolean;
|
||||||
|
updating?: boolean;
|
||||||
|
isInvalid?: (value: string) => string | boolean;
|
||||||
|
editInteractionKind: EditInteractionKind;
|
||||||
|
hideEditIcon?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check EditableText Component
|
||||||
|
export default function(props: EditableTextProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
49
app/client/src/components/ads/Icon.tsx
Normal file
49
app/client/src/components/ads/Icon.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from "react";
|
||||||
|
import { ReactComponent as DeleteIcon } from "assets/icons/ads/delete.svg";
|
||||||
|
import { ReactComponent as UserIcon } from "assets/icons/ads/user.svg";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { Size } from "./Button";
|
||||||
|
import { sizeHandler } from "./Spinner";
|
||||||
|
|
||||||
|
export type IconName = "delete" | "user" | undefined;
|
||||||
|
|
||||||
|
const IconWrapper = styled.div<IconProps>`
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
display: inline-block;
|
||||||
|
width: ${props => sizeHandler(props)}px;
|
||||||
|
height: ${props => sizeHandler(props)}px;
|
||||||
|
svg {
|
||||||
|
width: ${props => sizeHandler(props)}px;
|
||||||
|
height: ${props => sizeHandler(props)}px;
|
||||||
|
}
|
||||||
|
visibility: ${props => (props.invisible ? "hidden" : "visible")};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export type IconProps = {
|
||||||
|
size?: Size;
|
||||||
|
name?: IconName;
|
||||||
|
invisible?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Icon = (props: IconProps) => {
|
||||||
|
let returnIcon;
|
||||||
|
switch (props.name) {
|
||||||
|
case "delete":
|
||||||
|
returnIcon = (
|
||||||
|
<IconWrapper className="ads-icon" {...props}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconWrapper>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
returnIcon = (
|
||||||
|
<IconWrapper className="ads-icon" {...props}>
|
||||||
|
<UserIcon />
|
||||||
|
</IconWrapper>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return returnIcon;
|
||||||
|
};
|
||||||
10
app/client/src/components/ads/IconSelector.tsx
Normal file
10
app/client/src/components/ads/IconSelector.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
import { IconName } from "./Icon";
|
||||||
|
|
||||||
|
type IconSelectorProps = CommonComponentProps & {
|
||||||
|
onSelect: (icon: IconName) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function IconSelector(props: IconSelectorProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
4
app/client/src/components/ads/LighteningMenu.tsx
Normal file
4
app/client/src/components/ads/LighteningMenu.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// TODO
|
||||||
|
export default function TreeView(props: any) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
12
app/client/src/components/ads/Radio.tsx
Normal file
12
app/client/src/components/ads/Radio.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type RadioProps = CommonComponentProps & {
|
||||||
|
align?: "horizontal" | "vertical" | "column" | "row";
|
||||||
|
columns?: number;
|
||||||
|
rows?: number;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Radio(props: RadioProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
69
app/client/src/components/ads/Spinner.tsx
Normal file
69
app/client/src/components/ads/Spinner.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import React from "react";
|
||||||
|
import styled, { keyframes } from "styled-components";
|
||||||
|
import { Size, ThemeProp } from "./Button";
|
||||||
|
|
||||||
|
export const sizeHandler = (props: ThemeProp & SpinnerProp) => {
|
||||||
|
let iconSize = 0;
|
||||||
|
switch (props.size) {
|
||||||
|
case Size.small:
|
||||||
|
iconSize = props.theme.iconSizes.small;
|
||||||
|
break;
|
||||||
|
case Size.medium:
|
||||||
|
iconSize = props.theme.iconSizes.medium;
|
||||||
|
break;
|
||||||
|
case Size.large:
|
||||||
|
iconSize = props.theme.iconSizes.large;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return iconSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rotate = keyframes`
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const dash = keyframes`
|
||||||
|
0% {
|
||||||
|
stroke-dasharray: 1, 150;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
stroke-dasharray: 90, 150;
|
||||||
|
stroke-dashoffset: -35;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dasharray: 90, 150;
|
||||||
|
stroke-dashoffset: -124;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SvgContainer = styled("svg")<SpinnerProp>`
|
||||||
|
animation: ${rotate} 2s linear infinite;
|
||||||
|
width: ${props => sizeHandler(props)}px;
|
||||||
|
height: ${props => sizeHandler(props)}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SvgCircle = styled("circle")`
|
||||||
|
stroke: white;
|
||||||
|
stroke-linecap: round;
|
||||||
|
animation: ${dash} 1.5s ease-in-out infinite;
|
||||||
|
stroke-width: ${props => props.theme.spaces[1]}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export type SpinnerProp = {
|
||||||
|
size?: Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
Spinner.defaultProp = {
|
||||||
|
size: "small",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Spinner(props: SpinnerProp) {
|
||||||
|
return (
|
||||||
|
<SvgContainer viewBox="0 0 50 50" className="new-spinner" size={props.size}>
|
||||||
|
<SvgCircle cx="25" cy="25" r="20" fill="none"></SvgCircle>
|
||||||
|
</SvgContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
3
app/client/src/components/ads/Tabs.tsx
Normal file
3
app/client/src/components/ads/Tabs.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
// Create a wrapper around react-tabs
|
||||||
11
app/client/src/components/ads/Tag.tsx
Normal file
11
app/client/src/components/ads/Tag.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type TagProps = CommonComponentProps & {
|
||||||
|
onClick: (text: string) => void;
|
||||||
|
text: boolean;
|
||||||
|
variant?: "success" | "info" | "warning" | "danger"; //default info
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Tag(props: TagProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
11
app/client/src/components/ads/Text.tsx
Normal file
11
app/client/src/components/ads/Text.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export type TextProps = {
|
||||||
|
type: "p1" | "p2" | "p3" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||||
|
underline: boolean;
|
||||||
|
italic: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Text(props: TextProps) {
|
||||||
|
return <span></span>;
|
||||||
|
}
|
||||||
15
app/client/src/components/ads/TextInput.tsx
Normal file
15
app/client/src/components/ads/TextInput.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type TextProps = CommonComponentProps & {
|
||||||
|
placeholder?: string;
|
||||||
|
value: string;
|
||||||
|
hasError: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
validator: (value: string) => { isValid: boolean; message: string };
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
cypressSelector?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Text(props: TextProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
20
app/client/src/components/ads/Toast.tsx
Normal file
20
app/client/src/components/ads/Toast.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type ToastProps = CommonComponentProps & {
|
||||||
|
text: string;
|
||||||
|
duration: number;
|
||||||
|
variant?: "success" | "info" | "warning" | "danger"; //default info
|
||||||
|
keepOnHover?: boolean;
|
||||||
|
onComplete?: Function;
|
||||||
|
position:
|
||||||
|
| "top-right"
|
||||||
|
| "top-center"
|
||||||
|
| "top-left"
|
||||||
|
| "bottom-right"
|
||||||
|
| "bottom-center"
|
||||||
|
| "bottom-left";
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Toast(props: ToastProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
10
app/client/src/components/ads/Toggle.tsx
Normal file
10
app/client/src/components/ads/Toggle.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { CommonComponentProps } from "./common";
|
||||||
|
|
||||||
|
type ToggleProps = CommonComponentProps & {
|
||||||
|
onToggle: (value: boolean) => void;
|
||||||
|
value: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Toggle(props: ToggleProps) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
4
app/client/src/components/ads/Tree.tsx
Normal file
4
app/client/src/components/ads/Tree.tsx
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
//TODO
|
||||||
|
export default function Tree(props: any) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
5
app/client/src/components/ads/common.tsx
Normal file
5
app/client/src/components/ads/common.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface CommonComponentProps {
|
||||||
|
isLoading?: boolean; //default false
|
||||||
|
cypressSelector?: string;
|
||||||
|
isDisabled?: boolean; //default false
|
||||||
|
}
|
||||||
|
|
@ -28,12 +28,12 @@ const TabsWrapper = styled.div<{ shouldOverflow?: boolean }>`
|
||||||
}
|
}
|
||||||
.react-tabs__tab:focus {
|
.react-tabs__tab:focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-color: ${props => props.theme.colors.primary};
|
border-color: ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
.react-tabs__tab--selected {
|
.react-tabs__tab--selected {
|
||||||
color: ${props => props.theme.colors.primary};
|
color: ${props => props.theme.colors.primaryOld};
|
||||||
border-color: #d0d7dd;
|
border-color: #d0d7dd;
|
||||||
border-top: ${props => props.theme.colors.primary} 5px solid;
|
border-top: ${props => props.theme.colors.primaryOld} 5px solid;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ const DropdownStyles = createGlobalStyle`
|
||||||
top: -2px;
|
top: -2px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
|
@ -135,9 +135,9 @@ const DropdownStyles = createGlobalStyle`
|
||||||
}&
|
}&
|
||||||
}
|
}
|
||||||
.${Classes.CONTROL} input:checked ~ .${Classes.CONTROL_INDICATOR} {
|
.${Classes.CONTROL} input:checked ~ .${Classes.CONTROL_INDICATOR} {
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
color: ${props => props.theme.colors.textOnDarkBG};
|
color: ${props => props.theme.colors.textOnDarkBG};
|
||||||
border-color: ${props => props.theme.colors.primary};
|
border-color: ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const ResponseMetaInfo = styled.div`
|
||||||
|
|
||||||
const StatusCodeText = styled(BaseText)<{ code: string }>`
|
const StatusCodeText = styled(BaseText)<{ code: string }>`
|
||||||
color: ${props =>
|
color: ${props =>
|
||||||
props.code.match(/2\d\d/) ? props.theme.colors.primary : Colors.RED};
|
props.code.match(/2\d\d/) ? props.theme.colors.primaryOld : Colors.RED};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// const TableWrapper = styled.div`
|
// const TableWrapper = styled.div`
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const Dropdown = Select.ofType<ContextDropdownOption>();
|
||||||
|
|
||||||
const StyledMenuItem = styled(MenuItem)`
|
const StyledMenuItem = styled(MenuItem)`
|
||||||
&&&&.bp3-menu-item:hover {
|
&&&&.bp3-menu-item:hover {
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
color: ${props => props.theme.colors.textOnDarkBG};
|
color: ${props => props.theme.colors.textOnDarkBG};
|
||||||
}
|
}
|
||||||
&&&.bp3-menu-item.bp3-intent-danger:hover {
|
&&&.bp3-menu-item.bp3-intent-danger:hover {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ const ItemContainer = styled.div`
|
||||||
background-color: ${props => props.theme.colors.paneBG};
|
background-color: ${props => props.theme.colors.paneBG};
|
||||||
color: ${props => props.theme.colors.textOnDarkBG};
|
color: ${props => props.theme.colors.textOnDarkBG};
|
||||||
${IconContainer} {
|
${IconContainer} {
|
||||||
background-color: ${props => props.theme.colors.primary};
|
background-color: ${props => props.theme.colors.primaryOld};
|
||||||
svg path {
|
svg path {
|
||||||
fill: ${props => props.theme.colors.textOnDarkBG};
|
fill: ${props => props.theme.colors.textOnDarkBG};
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ class NavBarItem extends React.Component<Props> {
|
||||||
animate
|
animate
|
||||||
width={9}
|
width={9}
|
||||||
height={9}
|
height={9}
|
||||||
color={theme.colors.primary}
|
color={theme.colors.primaryOld}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DetailsContainer>
|
</DetailsContainer>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const customSelectStyles = {
|
||||||
backgroundColor: isDisabled
|
backgroundColor: isDisabled
|
||||||
? undefined
|
? undefined
|
||||||
: isSelected
|
: isSelected
|
||||||
? theme.colors.primary
|
? theme.colors.primaryOld
|
||||||
: isFocused
|
: isFocused
|
||||||
? theme.colors.hover
|
? theme.colors.hover
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
@ -32,7 +32,7 @@ const customSelectStyles = {
|
||||||
...styles[":active"],
|
...styles[":active"],
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
!isDisabled &&
|
!isDisabled &&
|
||||||
(isSelected ? theme.colors.primary : theme.colors.hover),
|
(isSelected ? theme.colors.primaryOld : theme.colors.hover),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export const JSToggleButton = styled.span<{ active: boolean }>`
|
||||||
rect {
|
rect {
|
||||||
fill: ${props =>
|
fill: ${props =>
|
||||||
props.active
|
props.active
|
||||||
? props.theme.colors.primary
|
? props.theme.colors.primaryOld
|
||||||
: props.theme.colors.paneIcon};
|
: props.theme.colors.paneIcon};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ export const StyledDropDownContainer = styled.div`
|
||||||
top: -2px;
|
top: -2px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -199,7 +199,7 @@ export const StyledMenuItem = styled(MenuItem)`
|
||||||
top: -2px;
|
top: -2px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -221,7 +221,7 @@ export const StyledMultiSelectDropDown = styled(MultiSelectDropDown)`
|
||||||
export const StyledSwitch = styled(Switch)`
|
export const StyledSwitch = styled(Switch)`
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
&&&&& input:checked ~ span {
|
&&&&& input:checked ~ span {
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
@ -269,7 +269,7 @@ export const StyledTimeZonePicker = styled(TimezonePicker)`
|
||||||
|
|
||||||
export const StyledPropertyPaneButton = styled(Button)`
|
export const StyledPropertyPaneButton = styled(Button)`
|
||||||
&&&& {
|
&&&& {
|
||||||
background-color: ${props => props.theme.colors.info};
|
background-color: ${props => props.theme.colors.infoOld};
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
.bp3-icon {
|
.bp3-icon {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export const JSToggleButton = styled.span<{ active: boolean }>`
|
||||||
rect {
|
rect {
|
||||||
fill: ${props =>
|
fill: ${props =>
|
||||||
props.active
|
props.active
|
||||||
? props.theme.colors.primary
|
? props.theme.colors.primaryOld
|
||||||
: props.theme.colors.paneIcon};
|
: props.theme.colors.paneIcon};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +107,7 @@ export const StyledDropDownContainer = styled.div`
|
||||||
top: -2px;
|
top: -2px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -261,7 +261,7 @@ export const StyledMultiSelectDropDown = styled(MultiSelectDropDown)`
|
||||||
|
|
||||||
export const StyledSwitch = styled(Switch)`
|
export const StyledSwitch = styled(Switch)`
|
||||||
&&&&& input:checked ~ span {
|
&&&&& input:checked ~ span {
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
@ -299,7 +299,7 @@ export const StyledDatePicker = styled(DateInput)`
|
||||||
|
|
||||||
export const StyledPropertyPaneButton = styled(Button)`
|
export const StyledPropertyPaneButton = styled(Button)`
|
||||||
&&&& {
|
&&&& {
|
||||||
background-color: ${props => props.theme.colors.info};
|
background-color: ${props => props.theme.colors.infoOld};
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
.bp3-icon {
|
.bp3-icon {
|
||||||
|
|
|
||||||
30
app/client/src/components/stories/Button.stories.tsx
Normal file
30
app/client/src/components/stories/Button.stories.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React from "react";
|
||||||
|
import Button, { Size, Category, Variant } from "components/ads/Button";
|
||||||
|
import { withKnobs, select, boolean, text } from "@storybook/addon-knobs";
|
||||||
|
import { withDesign } from "storybook-addon-designs";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Button",
|
||||||
|
component: Button,
|
||||||
|
decorators: [withKnobs, withDesign],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const withDynamicProps = () => (
|
||||||
|
<Button
|
||||||
|
size={select("size", [Size.small, Size.medium, Size.large], Size.large)}
|
||||||
|
category={select(
|
||||||
|
"category",
|
||||||
|
[Category.primary, Category.secondary, Category.tertiary],
|
||||||
|
Category.primary,
|
||||||
|
)}
|
||||||
|
variant={select(
|
||||||
|
"variant",
|
||||||
|
[Variant.info, Variant.success, Variant.danger, Variant.warning],
|
||||||
|
Variant.info,
|
||||||
|
)}
|
||||||
|
icon={select("iconName", ["delete", "user"], undefined)}
|
||||||
|
isLoading={boolean("Loading", false)}
|
||||||
|
isDisabled={boolean("Disabled", false)}
|
||||||
|
text={text("text", "Get")}
|
||||||
|
></Button>
|
||||||
|
);
|
||||||
|
|
@ -46,9 +46,9 @@ export const BlueprintControlTransform = css`
|
||||||
&& {
|
&& {
|
||||||
.${Classes.CONTROL} {
|
.${Classes.CONTROL} {
|
||||||
& input:checked ~ .${Classes.CONTROL_INDICATOR} {
|
& input:checked ~ .${Classes.CONTROL_INDICATOR} {
|
||||||
background: ${props => props.theme.colors.primary};
|
background: ${props => props.theme.colors.primaryOld};
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border: 2px solid ${props => props.theme.colors.primary};
|
border: 2px solid ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
& input:not(:disabled):active ~ .${Classes.CONTROL_INDICATOR} {
|
& input:not(:disabled):active ~ .${Classes.CONTROL_INDICATOR} {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
@ -238,13 +238,18 @@ type PropertyPaneTheme = {
|
||||||
dividerColor: Color;
|
dividerColor: Color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type NestedObjectOrArray<T> =
|
||||||
|
| Record<string, T | T[] | Record<string, T | T[]>>
|
||||||
|
| T
|
||||||
|
| T[];
|
||||||
export type Theme = {
|
export type Theme = {
|
||||||
radii: Array<number>;
|
radii: Array<number>;
|
||||||
fontSizes: Array<number>;
|
fontSizes: Array<number>;
|
||||||
drawerWidth: string;
|
drawerWidth: string;
|
||||||
spaces: Array<number>;
|
spaces: Array<number>;
|
||||||
fontWeights: Array<number>;
|
fontWeights: Array<number>;
|
||||||
colors: Record<string, Color>;
|
colors: any;
|
||||||
|
typography: any;
|
||||||
lineHeights: Array<number>;
|
lineHeights: Array<number>;
|
||||||
fonts: Array<FontFamily>;
|
fonts: Array<FontFamily>;
|
||||||
borders: ThemeBorder[];
|
borders: ThemeBorder[];
|
||||||
|
|
@ -341,6 +346,13 @@ export type Theme = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
iconSizes: iconSizeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
type iconSizeType = {
|
||||||
|
small: number;
|
||||||
|
medium: number;
|
||||||
|
large: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getColorWithOpacity = (color: Color, opacity: number) => {
|
export const getColorWithOpacity = (color: Color, opacity: number) => {
|
||||||
|
|
@ -364,11 +376,104 @@ export const labelStyle = css`
|
||||||
font-weight: ${props => props.theme.fontWeights[3]};
|
font-weight: ${props => props.theme.fontWeights[3]};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// export const adsTheme: any = {
|
||||||
|
// space: [0, 3, 14, 7, 16, 11, 26, 10, 4, 26, 30, 36, 4, 6, 11],
|
||||||
|
// };
|
||||||
|
// 3, 7, 11, 26
|
||||||
|
|
||||||
|
export const smallButton = css`
|
||||||
|
font-size: ${props => props.theme.typography.btnSmall.fontSize}px;
|
||||||
|
font-weight: ${props => props.theme.typography.btnSmall.fontWeight};
|
||||||
|
line-height: ${props => props.theme.typography.btnSmall.lineHeight}px;
|
||||||
|
letter-spacing: ${props => props.theme.typography.btnSmall.letterSpacing}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const mediumButton = css`
|
||||||
|
font-size: ${props => props.theme.typography.btnMedium.fontSize}px;
|
||||||
|
font-weight: ${props => props.theme.typography.btnMedium.fontWeight};
|
||||||
|
line-height: ${props => props.theme.typography.btnMedium.lineHeight}px;
|
||||||
|
letter-spacing: ${props => props.theme.typography.btnMedium.letterSpacing}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const largeButton = css`
|
||||||
|
font-size: ${props => props.theme.typography.btnLarge.fontSize}px;
|
||||||
|
font-weight: ${props => props.theme.typography.btnLarge.fontWeight};
|
||||||
|
line-height: ${props => props.theme.typography.btnLarge.lineHeight}px;
|
||||||
|
letter-spacing: ${props => props.theme.typography.btnLarge.letterSpacing}px;
|
||||||
|
`;
|
||||||
|
|
||||||
export const theme: Theme = {
|
export const theme: Theme = {
|
||||||
radii: [0, 4, 8, 10, 20, 50],
|
radii: [0, 4, 8, 10, 20, 50],
|
||||||
fontSizes: [0, 10, 12, 14, 16, 18, 24, 28, 32, 48, 64],
|
fontSizes: [0, 10, 12, 14, 16, 18, 24, 28, 32, 48, 64],
|
||||||
spaces: [0, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 30, 36],
|
spaces: [0, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 30, 36],
|
||||||
fontWeights: [0, 400, 500, 700],
|
fontWeights: [0, 400, 500, 700],
|
||||||
|
typography: {
|
||||||
|
h1: {
|
||||||
|
fontSize: 20,
|
||||||
|
lineHeight: 27,
|
||||||
|
},
|
||||||
|
h2: {
|
||||||
|
fontSize: 18,
|
||||||
|
lineHeight: 25,
|
||||||
|
},
|
||||||
|
h3: {
|
||||||
|
fontSize: 17,
|
||||||
|
lineHeight: 22,
|
||||||
|
},
|
||||||
|
h4: {
|
||||||
|
fontSize: 16,
|
||||||
|
lineHeight: 21,
|
||||||
|
letterSpacing: -0.24,
|
||||||
|
},
|
||||||
|
h5: {
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: 19,
|
||||||
|
letterSpacing: -0.24,
|
||||||
|
},
|
||||||
|
h6: {
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: 14,
|
||||||
|
letterSpacing: 0.8,
|
||||||
|
},
|
||||||
|
p1: {
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: 19,
|
||||||
|
letterSpacing: -0.24,
|
||||||
|
},
|
||||||
|
p2: {
|
||||||
|
fontSize: 13,
|
||||||
|
lineHeight: 17,
|
||||||
|
letterSpacing: -0.24,
|
||||||
|
},
|
||||||
|
p3: {
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: 16,
|
||||||
|
letterSpacing: -0.221538,
|
||||||
|
},
|
||||||
|
btnLarge: {
|
||||||
|
fontSize: 13,
|
||||||
|
lineHeight: 15,
|
||||||
|
letterSpacing: 0.6,
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
btnMedium: {
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: 14,
|
||||||
|
letterSpacing: 0.6,
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
btnSmall: {
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 13,
|
||||||
|
letterSpacing: 0.4,
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
iconSizes: {
|
||||||
|
small: 12,
|
||||||
|
medium: 14,
|
||||||
|
large: 15,
|
||||||
|
},
|
||||||
propertyPane: {
|
propertyPane: {
|
||||||
width: 270,
|
width: 270,
|
||||||
height: 600,
|
height: 600,
|
||||||
|
|
@ -380,15 +485,60 @@ export const theme: Theme = {
|
||||||
},
|
},
|
||||||
drawerWidth: "80%",
|
drawerWidth: "80%",
|
||||||
colors: {
|
colors: {
|
||||||
primary: Colors.GREEN,
|
blackShades: [
|
||||||
|
"#090707",
|
||||||
|
"#1A191C",
|
||||||
|
"#232324",
|
||||||
|
"#2B2B2B",
|
||||||
|
"#404040",
|
||||||
|
"#6D6D6D",
|
||||||
|
"#9F9F9F",
|
||||||
|
"#D4D4D4",
|
||||||
|
"#E9E9E9",
|
||||||
|
"#FFFFFF",
|
||||||
|
],
|
||||||
|
tertiary: {
|
||||||
|
main: "#D4D4D4",
|
||||||
|
light: "#FFFFFF",
|
||||||
|
dark: "#2B2B2B",
|
||||||
|
darker: "#202021",
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
main: "#CB4810",
|
||||||
|
dark: "#8B2E05",
|
||||||
|
darker: "#A03C12",
|
||||||
|
darkest: "#2B2B2B",
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
main: "#218358",
|
||||||
|
light: "#30CF89",
|
||||||
|
dark: "#0F4B30",
|
||||||
|
darker: "#17211E",
|
||||||
|
darkest: "#293835",
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
main: "#EABB0C",
|
||||||
|
light: "#FFD32E",
|
||||||
|
dark: "#886B00",
|
||||||
|
darker: "#2C271A",
|
||||||
|
darkest: "#2F2A1B",
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
main: "#E22C2C",
|
||||||
|
light: "#FF4D4D",
|
||||||
|
dark: "#830C0C",
|
||||||
|
darker: "#2B1A1D",
|
||||||
|
darkest: "#462F32",
|
||||||
|
},
|
||||||
|
primaryOld: Colors.GREEN,
|
||||||
primaryDarker: Colors.JUNGLE_GREEN,
|
primaryDarker: Colors.JUNGLE_GREEN,
|
||||||
primaryDarkest: Colors.JUNGLE_GREEN_DARKER,
|
primaryDarkest: Colors.JUNGLE_GREEN_DARKER,
|
||||||
secondary: Colors.GEYSER_LIGHT,
|
secondary: Colors.GEYSER_LIGHT,
|
||||||
secondaryDarker: Colors.CONCRETE,
|
secondaryDarker: Colors.CONCRETE,
|
||||||
secondaryDarkest: Colors.MERCURY,
|
secondaryDarkest: Colors.MERCURY,
|
||||||
error: Colors.RED,
|
error: Colors.RED,
|
||||||
|
infoOld: Colors.SLATE_GRAY,
|
||||||
errorMessage: Colors.ERROR_RED,
|
errorMessage: Colors.ERROR_RED,
|
||||||
info: Colors.SLATE_GRAY,
|
|
||||||
hover: Colors.POLAR,
|
hover: Colors.POLAR,
|
||||||
inputActiveBorder: Colors.HIT_GRAY,
|
inputActiveBorder: Colors.HIT_GRAY,
|
||||||
inputInactiveBG: Colors.AQUA_HAZE,
|
inputInactiveBG: Colors.AQUA_HAZE,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
export const DMSans = "DM Sans";
|
export const DMSans = "DM Sans";
|
||||||
export const AppsmithWidget = "widget-icons";
|
export const AppsmithWidget = "widget-icons";
|
||||||
export const FiraCode = '"Fira code", "Fira Mono", monospace';
|
export const FiraCode = '"Fira code", "Fira Mono", monospace';
|
||||||
|
export const HomePageRedesign =
|
||||||
|
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"';
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class AppViewerPageContainer extends Component<AppViewerPageContainerProps> {
|
||||||
<Icon
|
<Icon
|
||||||
iconSize={theme.fontSizes[9]}
|
iconSize={theme.fontSizes[9]}
|
||||||
icon="page-layout"
|
icon="page-layout"
|
||||||
color={theme.colors.primary}
|
color={theme.colors.primaryOld}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
title="This page seems to be blank"
|
title="This page seems to be blank"
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ class ResultPagination extends React.Component<Props> {
|
||||||
let activePage = undefined;
|
let activePage = undefined;
|
||||||
if (currentPage === page) {
|
if (currentPage === page) {
|
||||||
activePage = {
|
activePage = {
|
||||||
borderColor: theme.colors.primary,
|
borderColor: theme.colors.primaryOld,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ const PageName = styled.h5<{ isMain: boolean }>`
|
||||||
border-right: 4px solid;
|
border-right: 4px solid;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
border-color: ${props =>
|
border-color: ${props =>
|
||||||
props.isMain ? props.theme.colors.primary : "transparent"};
|
props.isMain ? props.theme.colors.primaryOld : "transparent"};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PageDropContainer = styled.div`
|
const PageDropContainer = styled.div`
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ const PageListItemWrapper = styled.div<{ active: boolean }>`
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
& div > svg > path:first-of-type {
|
& div > svg > path:first-of-type {
|
||||||
fill: ${props => props.theme.colors.primary};
|
fill: ${props => props.theme.colors.primaryOld};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& .more {
|
& .more {
|
||||||
|
|
|
||||||
4708
app/client/yarn.lock
4708
app/client/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user