diff --git a/package.json b/package.json
index 6dc9f22355..00938bd0f2 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"watch:uiw": "lerna exec --scope uiw -- tsbb watch",
"watch:react-menu": "lerna exec --scope @uiw/react-menu -- tsbb watch",
"watch:css:react-menu": "lerna exec --scope @uiw/react-menu -- compile-less -d src -o esm --watch",
- "watch": "lerna exec --scope @uiw/react-date-picker -- tsbb watch",
+ "watch": "lerna exec --scope @uiw/react-button -- tsbb watch",
"//-----------": "//-----------",
"build": "npm run b:uiw && npm run b:css && npm run b:css:dist",
"start": "lerna exec --scope website -- npm run start",
diff --git a/packages/react-button/README.md b/packages/react-button/README.md
index ab7ebeed63..0f0f6b79c7 100644
--- a/packages/react-button/README.md
+++ b/packages/react-button/README.md
@@ -25,7 +25,7 @@ import { Button, Divider, Icon } from 'uiw';
const Demo = ()=>(
-
+
@@ -209,7 +209,7 @@ const Demo = ()=>(
-
+
添加图标
@@ -224,7 +224,7 @@ const Demo = ()=>(
} type="primary">复制
} type="primary">删除
- } type="primary">添加文件
+ } type="primary">添加文件
} type="primary">地图
} type="primary">Linux
} type="primary">Apple
diff --git a/packages/react-button/src/index.tsx b/packages/react-button/src/index.tsx
index 09af328477..a12171867d 100644
--- a/packages/react-button/src/index.tsx
+++ b/packages/react-button/src/index.tsx
@@ -10,6 +10,7 @@ export interface ButtonProps extends IProps, Omit {
loading?: boolean;
block?: boolean;
icon?: React.ReactNode;
+ focus?: boolean;
/**
* 按钮类型
* @mytag {@link link }
@@ -59,7 +60,24 @@ const Button = React.forwardRef((props, ref) =>
.trim();
return (
-
+
{icon}
{children &&
React.Children.map(children, (child: React.ReactNode) => {
diff --git a/packages/react-button/src/style/Variant.ts b/packages/react-button/src/style/Variant.ts
index 5475c1d096..6afcadcd46 100644
--- a/packages/react-button/src/style/Variant.ts
+++ b/packages/react-button/src/style/Variant.ts
@@ -1,14 +1,30 @@
import { getThemeVariantValue } from '@uiw/utils';
-import { css } from 'styled-components';
-
+import { css, ThemedCssFunction } from 'styled-components';
+import { ButtonBaseProps } from '.';
type Options = {
type: string;
- defaultTheme?: Record;
- theme?: Record;
+} & ButtonBaseProps;
+
+/**
+ * @description: 生成公共css
+ * @param {string} style 样式
+ * @param {string} attrName 属性名
+ * @param {boolean} fig 直接生成
+ * @param {string} lastName 生成对象
+ */
+export const getCommonCss = (style: string, attrName: string, fig?: boolean, lastName?: string) => {
+ const com = css`
+ ${attrName && `${attrName}{${style}}`}
+ ${fig && lastName && `${lastName}{${style}}`}
+ ${fig && !lastName && style}
+ `;
+ return com;
};
export const buttonVariant = (options: Options) => {
- const { type } = options;
+ const { type, param } = options;
+ const { basic, focus, active, disabled } = param || {};
+
const color = getThemeVariantValue(options, `color${type}`);
const backgroundColor = getThemeVariantValue(options, `backgroundColor${type}`);
const backgroundColorHover = getThemeVariantValue(options, `backgroundColor${type}Hover`);
@@ -24,49 +40,173 @@ export const buttonVariant = (options: Options) => {
color: ${color};
background-color: ${backgroundColor};
z-index: 1;
- &:focus,
- &.focus {
- outline: 0;
- box-shadow: 0 0 0 2px ${boxShadowColorFocus};
- }
&:hover {
- color: ${color};
background-color: ${backgroundColorHover};
z-index: 2;
}
- &:active,
- &.active {
+ ${getCommonCss(
+ `
+ outline: 0;
+ box-shadow: 0 0 0 2px ${boxShadowColorFocus};
+ `,
+ '&:focus',
+ focus,
+ )}
+ ${getCommonCss(
+ `
color: ${color};
background-color: ${backgroundColorActive};
background-image: none;
- }
+ `,
+ ' &:active',
+ active,
+ )}
&.disabled,
&[disabled] {
background-color: ${backgroundColorDisabled};
z-index: 0;
}
- &.w-btn-basic {
- background-color: transparent !important;
- box-shadow: inset 0 0 0 ${boxShadowColorBasic};
- color: ${backgroundColor};
- &:hover {
- background-color: ${backgroundColorBasicHover} !important;
- }
- &:active,
- &.active {
- color: ${backgroundColor};
- background-color: ${backgroundColorBasicActive} !important;
- background-image: none;
- }
- &.disabled,
- &[disabled] {
+ ${getCommonCss(
+ `
+ background-color: ${backgroundColorDisabled};
+ z-index: 0;
+ `,
+ ' &[disabled]',
+ disabled,
+ )}
+ ${basic &&
+ css`
+ & {
background-color: transparent !important;
- color: ${colorBasicDisabled};
+ box-shadow: inset 0 0 0 ${boxShadowColorBasic};
+ color: ${backgroundColor};
+ &:hover {
+ background-color: ${backgroundColorBasicHover} !important;
+ }
+ ${getCommonCss(
+ `
+ color: ${backgroundColor};
+ background-color: ${backgroundColorBasicActive} !important;
+ background-image: none;
+ `,
+ ' &:active',
+ active,
+ )}
+ ${getCommonCss(
+ `
+ background-color: transparent !important;
+ color: ${colorBasicDisabled};
+ `,
+ '&[disabled]',
+ disabled,
+ )}
}
- }
+ `}
`;
};
+export const buttonTypes = (props: ButtonBaseProps) => {
+ const { type, focus, basic, active, disabled } = props.param || {};
+
+ switch (type) {
+ case 'primary':
+ return buttonVariant({ ...props, type: 'Primary' });
+ case 'success':
+ return buttonVariant({ ...props, type: 'Success' });
+ case 'danger':
+ return buttonVariant({ ...props, type: 'Error' });
+ case 'dark':
+ return buttonVariant({ ...props, type: 'Dark' });
+ case 'light':
+ return css`
+ box-shadow: inset 0 1px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')},
+ inset 1px -1px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')},
+ inset -1px 0px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')};
+ ${buttonVariant({ ...props, type: 'Light' })}
+ ${getCommonCss(
+ `
+ outline: 0;
+ box-shadow: inset 0 1px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')},
+ inset 1px -1px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')},
+ inset -1px 0px 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')},
+ 0 0 0 2px ${getThemeVariantValue(props, 'boxShadowColorLight4')};
+ `,
+ '&:focus',
+ focus,
+ )}
+ ${basic &&
+ css`
+ color: ${getThemeVariantValue(props, 'colorLightBasic')} !important;
+ &:focus {
+ box-shadow: inset 0 0 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')};
+ }
+ ${focus &&
+ css`
+ box-shadow: inset 0 0 0 0 ${getThemeVariantValue(props, 'boxShadowColorLightDefault')};
+ `}
+ &:hover {
+ background-color: ${getThemeVariantValue(props, 'backgroundColorLightBasicHover')} !important;
+ }
+ ${getCommonCss(
+ `
+ color: ${getThemeVariantValue(props, 'colorLightBasic')};
+ background-color: ${getThemeVariantValue(props, 'backgroundColorLightBasicActive')} !important;
+ background-image: none;
+ `,
+ '&:active',
+ active,
+ )}
+ ${getCommonCss(
+ `
+ background-color: transparent !important;
+ color: ${getThemeVariantValue(props, 'colorLightBasicDisabled')};
+ `,
+ '&[disabled]',
+ disabled,
+ )}
+ `}
+ ${getCommonCss(
+ `
+ color: ${getThemeVariantValue(props, 'colorLightBasicDisabled')};
+ z-index: 0;
+ `,
+ '&[disabled]',
+ disabled,
+ )}
+ `;
+ case 'link':
+ return css`
+ ${buttonVariant({ ...props, type: 'Link' })};
+ color: ${getThemeVariantValue(props, 'colorLink')} !important;
+ &:hover:not([disabled]) {
+ color: ${getThemeVariantValue(props, 'colorLinkNotDisabled')};
+ text-decoration: underline;
+ }
+ ${getCommonCss(
+ `
+ color: ${getThemeVariantValue(props, 'colorLinkNotDisabledActive')};
+ box-shadow: none;
+ text-decoration: underline;
+ `,
+ '&:not([disabled]):active',
+ disabled,
+ '&:not([disabled]) ',
+ )}
+ &[disabled] {
+ z-index: 0;
+ }
+ ${disabled &&
+ css`
+ z-index: 0;
+ `}
+ `;
+ case 'warning':
+ return buttonVariant({ ...props, type: 'Warning' });
+ default:
+ return css``;
+ }
+};
+
export const buttonSize = (fontSize: string, iconSize: string, lineHeight: string | number, minHeight: string) => {
return css`
font-size: ${fontSize};
@@ -77,3 +217,24 @@ export const buttonSize = (fontSize: string, iconSize: string, lineHeight: strin
}
`;
};
+const getSize = (props: ButtonBaseProps, type: string) => {
+ const fontSize = getThemeVariantValue(props, `fontSize${type}`);
+ const minHeight = getThemeVariantValue(props, `minHeightButton${type}`);
+ const fontSizeIcon = getThemeVariantValue(props, `fontSizeButtonIcon${type}`);
+ return buttonSize(`${fontSize}`, `${fontSizeIcon}`, fontSize, `${minHeight}`);
+};
+export const buttonSizeCss = (props: ButtonBaseProps) => {
+ const { size } = props.param || {};
+ switch (size) {
+ case 'large':
+ return getSize(props, 'Large');
+ case 'small':
+ return css`
+ padding: 0 6px;
+ min-width: ${getThemeVariantValue(props, 'minHeightButtonSmall')};
+ ${getSize(props, 'Small')}
+ `;
+ default:
+ return css``;
+ }
+};
diff --git a/packages/react-button/src/style/index.ts b/packages/react-button/src/style/index.ts
index 9caef7cc7c..a6ce66096c 100644
--- a/packages/react-button/src/style/index.ts
+++ b/packages/react-button/src/style/index.ts
@@ -1,20 +1,23 @@
-import styled from 'styled-components';
+import styled, { css } from 'styled-components';
import { getThemeVariantValue } from '@uiw/utils';
-import { buttonVariant, buttonSize } from './Variant';
-
-interface ButtonProps {
+import { buttonTypes, buttonSizeCss } from './Variant';
+import { ButtonType, ButtonSize } from '../';
+export interface ButtonBaseProps {
defaultTheme?: Record;
theme?: Record;
+ param?: {
+ size: ButtonSize;
+ type: ButtonType;
+ basic: boolean;
+ loading: boolean;
+ disabled: boolean;
+ active: boolean;
+ block: boolean;
+ focus: boolean;
+ };
}
-const getSize = (props: ButtonProps, type: string) => {
- const fontSize = getThemeVariantValue(props, `fontSize${type}`);
- const minHeight = getThemeVariantValue(props, `minHeightButton${type}`);
- const fontSizeIcon = getThemeVariantValue(props, `fontSizeButtonIcon${type}`);
- return buttonSize(`${fontSize}`, `${fontSizeIcon}`, fontSize, `${minHeight}`);
-};
-
-const Button = styled.button`
+const ButtonBase = styled.button`
user-select: none;
display: inline-flex;
flex-direction: row;
@@ -49,121 +52,49 @@ const Button = styled.button`
&[disabled] {
cursor: not-allowed;
}
- &.w-btn-primary {
- ${(props) => buttonVariant({ ...props, type: 'Primary' })}
- }
- &.w-btn-success {
- ${(props) => buttonVariant({ ...props, type: 'Success' })}
- }
- &.w-btn-warning {
- ${(props) => buttonVariant({ ...props, type: 'Warning' })}
- }
- &.w-btn-danger {
- ${(props) => buttonVariant({ ...props, type: 'Error' })}
- }
- &.w-btn-light {
- box-shadow: inset 0 1px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')},
- inset 1px -1px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')},
- inset -1px 0px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')};
- ${(props) => buttonVariant({ ...props, type: 'Light' })}
- &:focus,
- &.focus {
- outline: 0;
- box-shadow: inset 0 1px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')},
- inset 1px -1px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')},
- inset -1px 0px 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')},
- 0 0 0 2px ${(props) => getThemeVariantValue(props, 'boxShadowColorLight4')};
- }
- &.w-btn-basic {
- color: ${(props) => getThemeVariantValue(props, 'colorLightBasic')};
- &:focus,
- &.focus {
- box-shadow: inset 0 0 0 0 ${(props) => getThemeVariantValue(props, 'boxShadowColorLightDefault')};
- }
- &:hover {
- background-color: ${(props) => getThemeVariantValue(props, 'backgroundColorLightBasicHover')} !important;
- }
- &:active,
- &.active {
- color: ${(props) => getThemeVariantValue(props, 'colorLightBasic')};
- background-color: ${(props) => getThemeVariantValue(props, 'backgroundColorLightBasicActive')} !important;
- background-image: none;
- }
- &.disabled,
- &[disabled] {
- background-color: transparent !important;
- color: ${(props) => getThemeVariantValue(props, 'colorLightBasicDisabled')};
- }
- }
- &.disabled,
- &[disabled] {
- color: ${(props) => getThemeVariantValue(props, 'colorLightBasicDisabled')};
- z-index: 0;
- }
- }
- &.w-btn-dark {
- ${(props) => buttonVariant({ ...props, type: 'Dark' })}
- }
- &.w-btn-link {
- ${(props) => buttonVariant({ ...props, type: 'Link' })}
- color:${(props) => getThemeVariantValue(props, 'colorLink')} !important;
- &:hover:not([disabled]) {
- color: ${(props) => getThemeVariantValue(props, 'colorLinkNotDisabled')};
- text-decoration: underline;
- }
- &:not([disabled]):active,
- &:not([disabled]).active {
- color: ${(props) => getThemeVariantValue(props, 'colorLinkNotDisabledActive')};
- box-shadow: none;
- text-decoration: underline;
- }
- &.disabled,
- &[disabled] {
- z-index: 0;
- }
- }
+ ${buttonTypes}
.w-icon {
font-size: ${(props) => getThemeVariantValue(props, 'fontSizeButtonIcontDefault')};
}
- &.w-btn-size-large {
- ${(props) => getSize(props, 'Large')}
- }
- &.w-btn-size-small {
- padding: 0 6px;
- min-width: ${(props) => getThemeVariantValue(props, 'minHeightButtonSmall')};
- ${(props) => getSize(props, 'Small')}
- }
- & .w-icon:not(:last-child) {
+ ${buttonSizeCss}
+ .w-icon:not(:last-child) {
margin-right: 5px;
}
- &.w-btn-loading.w-btn-light::before {
- border: 1.2px solid ${(props) => getThemeVariantValue(props, 'borderColorLinghtLoadingBefore')};
- }
- &.w-btn-loading {
- &::before {
- content: '';
- display: inline-block;
- width: 1em;
- height: 1em;
- border-radius: 50%;
- border: 1.2px solid ${(props) => getThemeVariantValue(props, 'colorButtonLoadingBefore')};
- color: ${(props) => getThemeVariantValue(props, 'colorButtonLoadingBefore')};
- margin: 0 3px 0 0;
- clip-path: polygon(0% 0%, 100% 0, 100% 30%, 0% 30%);
- animation: rotate 0.5s linear infinite;
- @keyframes rotate {
- from {
- transform: rotateZ(0deg);
- }
- to {
- transform: rotateZ(360deg);
+ ${(props) =>
+ props.param?.loading &&
+ props.param.type === 'light' &&
+ css`
+ &::before {
+ border: 1.2px solid ${(props) => getThemeVariantValue(props, 'borderColorLinghtLoadingBefore')};
+ }
+ `}
+ ${(props) =>
+ props.param?.loading &&
+ css`
+ &::before {
+ content: '';
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ border-radius: 50%;
+ border: 1.2px solid ${(props) => getThemeVariantValue(props, 'colorButtonLoadingBefore')};
+ color: ${(props) => getThemeVariantValue(props, 'colorButtonLoadingBefore')};
+ margin: 0 3px 0 0;
+ clip-path: polygon(0% 0%, 100% 0, 100% 30%, 0% 30%);
+ animation: rotate 0.5s linear infinite;
+ @keyframes rotate {
+ from {
+ transform: rotateZ(0deg);
+ }
+ to {
+ transform: rotateZ(360deg);
+ }
}
}
- }
- }
+ `}
`;
-Button.defaultProps = {
+ButtonBase.defaultProps = {
defaultTheme: {
colorButtonBase: '#fff',
// 大小设置
@@ -275,4 +206,4 @@ Button.defaultProps = {
colorLinkNotDisabledActive: '#002d4d',
},
};
-export default Button;
+export default ButtonBase;