Commit fe2e253f358f08f97cb9e1a5ec7df01f3c9bc3e1
1 parent
8e89ea2d
Exists in
master
feat: 按钮支持主题与自定义颜色
Showing
7 changed files
with
462 additions
and
108 deletions
Show diff stats
examples/styles/variables.scss
| @@ -20,8 +20,6 @@ $background: #fff; | @@ -20,8 +20,6 @@ $background: #fff; | ||
| 20 | 20 | ||
| 21 | // NEW STYLE | 21 | // NEW STYLE |
| 22 | 22 | ||
| 23 | -// $color-primary: #F39800; | ||
| 24 | - | ||
| 25 | $color-primary: #FDD108; | 23 | $color-primary: #FDD108; |
| 26 | 24 | ||
| 27 | $color-zy-yellow: #FDD108; | 25 | $color-zy-yellow: #FDD108; |
| @@ -33,6 +31,7 @@ $color-wx: #07c160; | @@ -33,6 +31,7 @@ $color-wx: #07c160; | ||
| 33 | $color-blue: #2F86F6; | 31 | $color-blue: #2F86F6; |
| 34 | $color-green: #28AA91; | 32 | $color-green: #28AA91; |
| 35 | $color-red: #FF5257; | 33 | $color-red: #FF5257; |
| 34 | +$color-yellow: #ffd752; | ||
| 36 | $color-blue-dark: #5878B4; | 35 | $color-blue-dark: #5878B4; |
| 37 | $color-ink: #2D2D2D; | 36 | $color-ink: #2D2D2D; |
| 38 | $color-grey: #8C8C8C; | 37 | $color-grey: #8C8C8C; |
| @@ -61,13 +60,13 @@ $color-disabled: #ccc; | @@ -61,13 +60,13 @@ $color-disabled: #ccc; | ||
| 61 | $bg-active: #f3f3f3; | 60 | $bg-active: #f3f3f3; |
| 62 | $bg-disabled: #f5f5f5; | 61 | $bg-disabled: #f5f5f5; |
| 63 | 62 | ||
| 64 | -$font-lg: 1.3125rem; | ||
| 65 | -$font-md: 0.9375rem; | ||
| 66 | -$font-sm: 0.6875rem; | 63 | +$font-lg: 1.25rem; |
| 64 | +$font-md: 1rem; | ||
| 65 | +$font-sm: 0.65rem; | ||
| 67 | 66 | ||
| 68 | -$h-gap-lg: 0.625rem; | ||
| 69 | -$h-gap-md: 0.468rem; | ||
| 70 | -$h-gap-sm: 0.3125rem; | ||
| 71 | -$v-gap-lg: 1.4rem; | ||
| 72 | -$v-gap-md: 0.9375rem; | ||
| 73 | -$v-gap-sm: 0.625rem; | ||
| 74 | \ No newline at end of file | 67 | \ No newline at end of file |
| 68 | +$h-gap-lg: 0.65rem; | ||
| 69 | +$h-gap-md: 0.45rem; | ||
| 70 | +$h-gap-sm: 0.3rem; | ||
| 71 | +$v-gap-lg: 1.5rem; | ||
| 72 | +$v-gap-md: 1rem; | ||
| 73 | +$v-gap-sm: 0.65rem; | ||
| 75 | \ No newline at end of file | 74 | \ No newline at end of file |
examples/views/docs/component/button.md
| @@ -11,10 +11,121 @@ | @@ -11,10 +11,121 @@ | ||
| 11 | ```html | 11 | ```html |
| 12 | <template> | 12 | <template> |
| 13 | <div> | 13 | <div> |
| 14 | - <zui-button disabled>Default</zui-button> | 14 | + <zui-button>Default</zui-button> |
| 15 | <zui-button type="primary">Primary</zui-button> | 15 | <zui-button type="primary">Primary</zui-button> |
| 16 | <zui-button type="secondary">Secondary</zui-button> | 16 | <zui-button type="secondary">Secondary</zui-button> |
| 17 | - <zui-button type="link">链接</zui-button> | 17 | + <zui-button type="plain">Plain</zui-button> |
| 18 | + <zui-button type="link">Link</zui-button> | ||
| 19 | + </div> | ||
| 20 | +</template> | ||
| 21 | +``` | ||
| 22 | + | ||
| 23 | +::: | ||
| 24 | + | ||
| 25 | +## 按钮主题 | ||
| 26 | + | ||
| 27 | +配置`theme`属性改变按钮主题 | ||
| 28 | + | ||
| 29 | +::: snippet 支持`red`、`green`、`blue` | ||
| 30 | + | ||
| 31 | +```html | ||
| 32 | +<template> | ||
| 33 | + <div> | ||
| 34 | + <div style="padding-top: 10px;"> | ||
| 35 | + <zui-button theme="red">Default</zui-button> | ||
| 36 | + <zui-button type="primary" theme="red">Primary</zui-button> | ||
| 37 | + <zui-button type="secondary" theme="red">Secondary</zui-button> | ||
| 38 | + <zui-button type="plain" theme="red">Plain</zui-button> | ||
| 39 | + <zui-button type="ghost" theme="red">Ghost</zui-button> | ||
| 40 | + <zui-button type="link" theme="red">Link</zui-button> | ||
| 41 | + </div> | ||
| 42 | + <div style="padding-top: 10px;"> | ||
| 43 | + <zui-button theme="green">Default</zui-button> | ||
| 44 | + <zui-button type="primary" theme="green">Primary</zui-button> | ||
| 45 | + <zui-button type="secondary" theme="green">Secondary</zui-button> | ||
| 46 | + <zui-button type="plain" theme="green">Plain</zui-button> | ||
| 47 | + <zui-button type="ghost" theme="green">Ghost</zui-button> | ||
| 48 | + <zui-button type="link" theme="green">Link</zui-button> | ||
| 49 | + </div> | ||
| 50 | + <div style="padding-top: 10px;"> | ||
| 51 | + <zui-button theme="blue">Default</zui-button> | ||
| 52 | + <zui-button type="primary" theme="blue">Primary</zui-button> | ||
| 53 | + <zui-button type="secondary" theme="blue">Secondary</zui-button> | ||
| 54 | + <zui-button type="plain" theme="blue">Plain</zui-button> | ||
| 55 | + <zui-button type="ghost" theme="blue">Ghost</zui-button> | ||
| 56 | + <zui-button type="link" theme="blue">Link</zui-button> | ||
| 57 | + </div> | ||
| 58 | + </div> | ||
| 59 | +</template> | ||
| 60 | +``` | ||
| 61 | + | ||
| 62 | +::: | ||
| 63 | + | ||
| 64 | +## 按钮颜色 | ||
| 65 | + | ||
| 66 | +配置`color`属性改变按钮颜色 | ||
| 67 | + | ||
| 68 | +::: snippet 支持任意颜色 | ||
| 69 | + | ||
| 70 | +```html | ||
| 71 | +<template> | ||
| 72 | + <div> | ||
| 73 | + <div style="padding-top: 10px;"> | ||
| 74 | + <zui-button color="#074137">Default</zui-button> | ||
| 75 | + <zui-button type="primary" color="#074137">Primary</zui-button> | ||
| 76 | + <zui-button type="secondary" color="#074137">Secondary</zui-button> | ||
| 77 | + <zui-button type="plain" color="#074137">Plain</zui-button> | ||
| 78 | + <zui-button type="ghost" color="#074137">Ghost</zui-button> | ||
| 79 | + <zui-button type="link" color="#074137">Link</zui-button> | ||
| 80 | + </div> | ||
| 81 | + <div style="padding-top: 10px;"> | ||
| 82 | + <zui-button color="#FDD108">Default</zui-button> | ||
| 83 | + <zui-button type="primary" color="#FDD108">Primary</zui-button> | ||
| 84 | + <zui-button type="secondary" color="#FDD108">Secondary</zui-button> | ||
| 85 | + <zui-button type="plain" color="#FDD108">Plain</zui-button> | ||
| 86 | + <zui-button type="ghost" color="#FDD108">Ghost</zui-button> | ||
| 87 | + <zui-button type="link" color="#FDD108">Link</zui-button> | ||
| 88 | + </div> | ||
| 89 | + <div style="padding-top: 10px;"> | ||
| 90 | + <zui-button color="#F39800">Default</zui-button> | ||
| 91 | + <zui-button type="primary" color="#F39800">Primary</zui-button> | ||
| 92 | + <zui-button type="secondary" color="#F39800">Secondary</zui-button> | ||
| 93 | + <zui-button type="plain" color="#F39800">Plain</zui-button> | ||
| 94 | + <zui-button type="ghost" color="#F39800">Ghost</zui-button> | ||
| 95 | + <zui-button type="link" color="#F39800">Link</zui-button> | ||
| 96 | + </div> | ||
| 97 | + <div style="padding-top: 10px;"> | ||
| 98 | + <zui-button color="#FF5257">Default</zui-button> | ||
| 99 | + <zui-button type="primary" color="#FF5257">Primary</zui-button> | ||
| 100 | + <zui-button type="secondary" color="#FF5257">Secondary</zui-button> | ||
| 101 | + <zui-button type="plain" color="#FF5257">Plain</zui-button> | ||
| 102 | + <zui-button type="ghost" color="#FF5257">Ghost</zui-button> | ||
| 103 | + <zui-button type="link" color="#FF5257">Link</zui-button> | ||
| 104 | + </div> | ||
| 105 | + <div style="padding-top: 10px;"> | ||
| 106 | + <zui-button color="rgb(40, 170, 145)">Default</zui-button> | ||
| 107 | + <zui-button type="primary" color="rgb(40, 170, 145)">Primary</zui-button> | ||
| 108 | + <zui-button type="secondary" color="rgb(40, 170, 145)">Secondary</zui-button> | ||
| 109 | + <zui-button type="plain" color="rgb(40, 170, 145)">Plain</zui-button> | ||
| 110 | + <zui-button type="ghost" color="rgb(40, 170, 145)">Ghost</zui-button> | ||
| 111 | + <zui-button type="link" color="rgb(40, 170, 145)">Link</zui-button> | ||
| 112 | + </div> | ||
| 113 | + <div style="padding-top: 10px;"> | ||
| 114 | + <zui-button color="#2F86F6">Default</zui-button> | ||
| 115 | + <zui-button type="primary" color="#2F86F6">Primary</zui-button> | ||
| 116 | + <zui-button type="secondary" color="#2F86F6">Secondary</zui-button> | ||
| 117 | + <zui-button type="plain" color="#2F86F6">Plain</zui-button> | ||
| 118 | + <zui-button type="ghost" color="#2F86F6">Ghost</zui-button> | ||
| 119 | + <zui-button type="link" color="#2F86F6">Link</zui-button> | ||
| 120 | + </div> | ||
| 121 | + <div style="padding-top: 10px;"> | ||
| 122 | + <zui-button color="#000">Default</zui-button> | ||
| 123 | + <zui-button type="primary" color="#000">Primary</zui-button> | ||
| 124 | + <zui-button type="secondary" color="#000">Secondary</zui-button> | ||
| 125 | + <zui-button type="plain" color="#000">Plain</zui-button> | ||
| 126 | + <zui-button type="ghost" color="#000">Ghost</zui-button> | ||
| 127 | + <zui-button type="link" color="#000">Link</zui-button> | ||
| 128 | + </div> | ||
| 18 | </div> | 129 | </div> |
| 19 | </template> | 130 | </template> |
| 20 | ``` | 131 | ``` |
package.json
| @@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
| 12 | }, | 12 | }, |
| 13 | "dependencies": { | 13 | "dependencies": { |
| 14 | "axios": "^0.19.2", | 14 | "axios": "^0.19.2", |
| 15 | + "color": "^3.1.2", | ||
| 15 | "core-js": "^3.6.5", | 16 | "core-js": "^3.6.5", |
| 16 | "element-theme-chalk": "^2.13.2", | 17 | "element-theme-chalk": "^2.13.2", |
| 17 | "element-ui": "^2.13.2", | 18 | "element-ui": "^2.13.2", |
packages/button/index.scss
| @@ -6,32 +6,25 @@ | @@ -6,32 +6,25 @@ | ||
| 6 | font-weight: normal; | 6 | font-weight: normal; |
| 7 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; | 7 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; |
| 8 | cursor: pointer; | 8 | cursor: pointer; |
| 9 | - transition: all 70ms ease 20ms; | ||
| 10 | - border-radius: 0.3125rem; | 9 | + transition: all 70ms ease; |
| 10 | + border-radius: 0.35rem; | ||
| 11 | position: relative; | 11 | position: relative; |
| 12 | display: inline-block; | 12 | display: inline-block; |
| 13 | text-align: center; | 13 | text-align: center; |
| 14 | border: none; | 14 | border: none; |
| 15 | outline: none; | 15 | outline: none; |
| 16 | - line-height: 1.5; | ||
| 17 | - &::after { | ||
| 18 | - line-height: 1.5; | ||
| 19 | - padding: 0; | ||
| 20 | - margin: 0; | ||
| 21 | - border: none; | ||
| 22 | - content: ""; | ||
| 23 | - pointer-events: none; /* 防止点击触发 */ | ||
| 24 | - box-sizing: border-box; | ||
| 25 | - position: absolute; | ||
| 26 | - width: 200%; | ||
| 27 | - height: 200%; | ||
| 28 | - left: 0; | ||
| 29 | - top: 0; | ||
| 30 | - border: 1px solid $color-border; | ||
| 31 | - border-radius: 0.625rem; | ||
| 32 | - transform: scale(0.5); | ||
| 33 | - transform-origin: 0 0; | ||
| 34 | - } | 16 | + line-height: 1.5; |
| 17 | + box-sizing: border-box; | ||
| 18 | + border: 1px solid transparent; | ||
| 19 | + &.red { | ||
| 20 | + color: $color-red; | ||
| 21 | + } | ||
| 22 | + &.blue { | ||
| 23 | + color: $color-blue; | ||
| 24 | + } | ||
| 25 | + &.green { | ||
| 26 | + color: $color-green; | ||
| 27 | + } | ||
| 35 | &.block { | 28 | &.block { |
| 36 | display: block; | 29 | display: block; |
| 37 | width: 100%; | 30 | width: 100%; |
| @@ -48,99 +41,153 @@ | @@ -48,99 +41,153 @@ | ||
| 48 | padding: $h-gap-lg $v-gap-lg; | 41 | padding: $h-gap-lg $v-gap-lg; |
| 49 | font-size: $font-lg; | 42 | font-size: $font-lg; |
| 50 | } | 43 | } |
| 51 | - &:active { | 44 | + &.default { |
| 45 | + border-color: $color-border; | ||
| 46 | + } | ||
| 47 | + &.button-hover { | ||
| 52 | background-color: $bg-active; | 48 | background-color: $bg-active; |
| 53 | - &, &::after { | ||
| 54 | - border-color: $bg-active; | 49 | + } |
| 50 | + @mixin fill-mixin($color) { | ||
| 51 | + &.button-hover { | ||
| 52 | + background-color: $color; | ||
| 55 | } | 53 | } |
| 56 | } | 54 | } |
| 57 | &.primary { | 55 | &.primary { |
| 58 | background-color: $color-primary; | 56 | background-color: $color-primary; |
| 59 | color: #FFF; | 57 | color: #FFF; |
| 60 | - &:active { | ||
| 61 | - background-color: darken($color-primary, 3%); | ||
| 62 | - &, &::after { | ||
| 63 | - border-color: darken($color-primary, 3%); | ||
| 64 | - } | 58 | + @include fill-mixin(lighten($color-primary, 10%)); |
| 59 | + &.red { | ||
| 60 | + background-color: $color-red; | ||
| 61 | + @include fill-mixin(lighten($color-red, 10%)); | ||
| 62 | + } | ||
| 63 | + &.green { | ||
| 64 | + background-color: $color-green; | ||
| 65 | + @include fill-mixin(lighten($color-green, 10%)); | ||
| 65 | } | 66 | } |
| 66 | - &, &::after { | ||
| 67 | - border-color: $color-primary; | 67 | + &.blue { |
| 68 | + background-color: $color-blue; | ||
| 69 | + @include fill-mixin(lighten($color-blue, 10%)); | ||
| 68 | } | 70 | } |
| 69 | } | 71 | } |
| 70 | &.secondary { | 72 | &.secondary { |
| 71 | - background-color: lighten($color-primary, 40%); | ||
| 72 | color: $color-primary; | 73 | color: $color-primary; |
| 73 | - &:active { | ||
| 74 | - background-color: lighten($color-primary, 30%); | ||
| 75 | - color: darken($color-primary, 3%); | ||
| 76 | - &, &::after { | ||
| 77 | - border-color: lighten($color-primary, 30%); | 74 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); |
| 75 | + @include fill-mixin(hsl(hue($color-primary), saturation($color-primary), 90%)); | ||
| 76 | + &.red { | ||
| 77 | + color: $color-red; | ||
| 78 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | ||
| 79 | + @include fill-mixin(hsl(hue($color-red), saturation($color-red), 90%)); | ||
| 80 | + } | ||
| 81 | + &.green { | ||
| 82 | + color: $color-green; | ||
| 83 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | ||
| 84 | + @include fill-mixin(hsl(hue($color-green), saturation($color-green), 90%)); | ||
| 85 | + } | ||
| 86 | + &.blue { | ||
| 87 | + color: $color-blue; | ||
| 88 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | ||
| 89 | + @include fill-mixin(hsl(hue($color-blue), saturation($color-blue), 90%)); | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + &.plain { | ||
| 93 | + color: $color-primary; | ||
| 94 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | ||
| 95 | + border-color: $color-primary; | ||
| 96 | + &:not(.custom).button-hover { | ||
| 97 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | ||
| 98 | + } | ||
| 99 | + &.red { | ||
| 100 | + color: $color-red; | ||
| 101 | + border-color: $color-red; | ||
| 102 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | ||
| 103 | + &:not(.custom).button-hover { | ||
| 104 | + background-color: hsl(hue($color-red), saturation($color-red), 90%); | ||
| 78 | } | 105 | } |
| 79 | } | 106 | } |
| 80 | - &, &::after { | ||
| 81 | - border-color: lighten($color-primary, 40%); | ||
| 82 | - } | ||
| 83 | - } | ||
| 84 | - &.plain { | ||
| 85 | - &.primary { | ||
| 86 | - color: $color-primary; | ||
| 87 | - background-color: transparent; | ||
| 88 | - &:active { | ||
| 89 | - background-color: rgba($color-primary, 0.1); | ||
| 90 | - } | ||
| 91 | - } | ||
| 92 | - &.disabled { | ||
| 93 | - background-color: rgba($bg-disabled, 0.1); | ||
| 94 | - color: $color-disabled; | ||
| 95 | - cursor: not-allowed; | ||
| 96 | - &:active { | ||
| 97 | - color: $color-disabled; | ||
| 98 | - background-color: rgba($bg-disabled, 0.1); | ||
| 99 | - &, &::after { | ||
| 100 | - border-color: $bg-disabled; | ||
| 101 | - } | ||
| 102 | - } | ||
| 103 | - &, &::after { | ||
| 104 | - border-color: $bg-disabled; | ||
| 105 | - } | ||
| 106 | - } | ||
| 107 | - } | 107 | + &.green { |
| 108 | + color: $color-green; | ||
| 109 | + border-color: $color-green; | ||
| 110 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | ||
| 111 | + &:not(.custom).button-hover { | ||
| 112 | + background-color: hsl(hue($color-green), saturation($color-green), 90%); | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | + &.blue { | ||
| 116 | + color: $color-blue; | ||
| 117 | + border-color: $color-blue; | ||
| 118 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | ||
| 119 | + &:not(.custom).button-hover { | ||
| 120 | + background-color: hsl(hue($color-blue), saturation($color-blue), 90%); | ||
| 121 | + } | ||
| 122 | + } | ||
| 123 | + } | ||
| 124 | + &.ghost { | ||
| 125 | + color: $color-primary; | ||
| 126 | + background-color: transparent; | ||
| 127 | + border-color: $color-primary; | ||
| 128 | + &:not(.custom).button-hover { | ||
| 129 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | ||
| 130 | + } | ||
| 131 | + &.red { | ||
| 132 | + color: $color-red; | ||
| 133 | + border-color: $color-red; | ||
| 134 | + &:not(.custom).button-hover { | ||
| 135 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + &.green { | ||
| 139 | + color: $color-green; | ||
| 140 | + border-color: $color-green; | ||
| 141 | + &:not(.custom).button-hover { | ||
| 142 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + &.blue { | ||
| 146 | + color: $color-blue; | ||
| 147 | + border-color: $color-blue; | ||
| 148 | + &:not(.custom).button-hover { | ||
| 149 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + } | ||
| 108 | &.link { | 153 | &.link { |
| 109 | - padding: $h-gap-sm $v-gap-sm; | ||
| 110 | - background: inherit; | ||
| 111 | - border: inherit; | 154 | + background-color: transparent; |
| 155 | + border-color: transparent; | ||
| 112 | color: $color-primary; | 156 | color: $color-primary; |
| 113 | - &:active { | ||
| 114 | - color: darken($color-primary, 5%); | 157 | + &.button-hover { |
| 158 | + color: lighten($color-primary, 10%); | ||
| 159 | + } | ||
| 160 | + &.red { | ||
| 161 | + color: $color-red; | ||
| 162 | + &.button-hover { | ||
| 163 | + color: lighten($color-red, 10%); | ||
| 164 | + } | ||
| 165 | + } | ||
| 166 | + &.green { | ||
| 167 | + color: $color-green; | ||
| 168 | + &.button-hover { | ||
| 169 | + color: lighten($color-green, 10%); | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | + &.blue { | ||
| 173 | + color: $color-blue; | ||
| 174 | + &.button-hover { | ||
| 175 | + color: lighten($color-blue, 10%); | ||
| 176 | + } | ||
| 115 | } | 177 | } |
| 116 | - &::after { | ||
| 117 | - display: none; | ||
| 118 | - } | ||
| 119 | } | 178 | } |
| 120 | &.disabled { | 179 | &.disabled { |
| 121 | background-color: $bg-disabled; | 180 | background-color: $bg-disabled; |
| 122 | color: $color-disabled; | 181 | color: $color-disabled; |
| 123 | cursor: not-allowed; | 182 | cursor: not-allowed; |
| 124 | - &:active { | 183 | + &.button-hover { |
| 125 | background-color: $bg-disabled; | 184 | background-color: $bg-disabled; |
| 126 | - &, &::after { | ||
| 127 | - border-color: $bg-disabled; | ||
| 128 | - } | ||
| 129 | - } | ||
| 130 | - &, &::after { | ||
| 131 | - border-color: $bg-disabled; | ||
| 132 | } | 185 | } |
| 133 | } | 186 | } |
| 134 | &.round { | 187 | &.round { |
| 135 | border-radius: 1.5rem; | 188 | border-radius: 1.5rem; |
| 136 | - &::after { | ||
| 137 | - border-radius: 3rem; | ||
| 138 | - } | ||
| 139 | } | 189 | } |
| 140 | &.square { | 190 | &.square { |
| 141 | border-radius: 0; | 191 | border-radius: 0; |
| 142 | - &::after { | ||
| 143 | - border-radius: 0; | ||
| 144 | - } | ||
| 145 | } | 192 | } |
| 146 | } | 193 | } |
| 147 | \ No newline at end of file | 194 | \ No newline at end of file |
packages/button/index.vue
| 1 | <template> | 1 | <template> |
| 2 | - <button class="zui-button" :class="classRender" @click="onClick"> | 2 | + <button class="zui-button" :class="classRender" :style="styleRender" v-on="bindEvents"> |
| 3 | <slot></slot> | 3 | <slot></slot> |
| 4 | </button> | 4 | </button> |
| 5 | </template> | 5 | </template> |
| 6 | 6 | ||
| 7 | <script> | 7 | <script> |
| 8 | +import color from 'color'; | ||
| 9 | + | ||
| 8 | export default { | 10 | export default { |
| 9 | name: 'Button', | 11 | name: 'Button', |
| 10 | props: { | 12 | props: { |
| @@ -23,26 +25,100 @@ export default { | @@ -23,26 +25,100 @@ export default { | ||
| 23 | round: Boolean, | 25 | round: Boolean, |
| 24 | square: Boolean, | 26 | square: Boolean, |
| 25 | disabled: Boolean, | 27 | disabled: Boolean, |
| 26 | - plain: Boolean, | 28 | + theme: String, |
| 29 | + color: String, | ||
| 30 | + hoverClass: { | ||
| 31 | + type: String, | ||
| 32 | + default: 'button-hover', | ||
| 33 | + }, | ||
| 34 | + hoverStartTime: { | ||
| 35 | + type: Number, | ||
| 36 | + default: 0, | ||
| 37 | + }, | ||
| 38 | + hoverStayTime: { | ||
| 39 | + type: Number, | ||
| 40 | + default: 70, | ||
| 41 | + }, | ||
| 42 | + }, | ||
| 43 | + data() { | ||
| 44 | + return { | ||
| 45 | + active: false, | ||
| 46 | + }; | ||
| 27 | }, | 47 | }, |
| 28 | computed: { | 48 | computed: { |
| 29 | classRender() { | 49 | classRender() { |
| 30 | return { | 50 | return { |
| 31 | [this.size]: true, | 51 | [this.size]: true, |
| 32 | [this.type]: true, | 52 | [this.type]: true, |
| 53 | + [this.theme]: !!this.theme, | ||
| 54 | + [this.hoverClass]: this.active, | ||
| 33 | disabled: this.disabled, | 55 | disabled: this.disabled, |
| 34 | block: this.block, | 56 | block: this.block, |
| 35 | round: this.round, | 57 | round: this.round, |
| 36 | square: this.square, | 58 | square: this.square, |
| 37 | - plain: this.plain, | 59 | + custom: !!this.color, |
| 38 | }; | 60 | }; |
| 39 | }, | 61 | }, |
| 40 | - }, | ||
| 41 | - methods: { | ||
| 42 | - onClick() { | ||
| 43 | - if (!this.disabled) { | ||
| 44 | - this.$emit('click'); | 62 | + styleRender() { |
| 63 | + if (this.color) { | ||
| 64 | + if (this.type === 'primary') { | ||
| 65 | + return { | ||
| 66 | + backgroundColor: this.active ? color(this.color).lighten(0.2) : this.color, | ||
| 67 | + borderColor: this.active ? color(this.color).lighten(0.2) : this.color, | ||
| 68 | + }; | ||
| 69 | + } else if (this.type === 'secondary') { | ||
| 70 | + return { | ||
| 71 | + backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), | ||
| 72 | + color: this.color, | ||
| 73 | + }; | ||
| 74 | + } else if (this.type === 'plain') { | ||
| 75 | + return { | ||
| 76 | + borderColor: this.color, | ||
| 77 | + color: this.color, | ||
| 78 | + backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), | ||
| 79 | + }; | ||
| 80 | + } else if (this.type === 'ghost') { | ||
| 81 | + return { | ||
| 82 | + borderColor: this.color, | ||
| 83 | + color: this.color, | ||
| 84 | + backgroundColor: this.active ? color(this.color).lightness(95) : undefined, | ||
| 85 | + }; | ||
| 86 | + } else { | ||
| 87 | + return { | ||
| 88 | + color: this.active ? color(this.color).lighten(0.2) : this.color, | ||
| 89 | + }; | ||
| 90 | + } | ||
| 45 | } | 91 | } |
| 92 | + return {}; | ||
| 93 | + }, | ||
| 94 | + bindEvents() { | ||
| 95 | + const events = this.$listeners || {}; | ||
| 96 | + const activeEvents = ['mousedown', 'touchstart']; | ||
| 97 | + const deactiveEvents = ['mouseup', 'mousemove', 'touchend', 'touchmove']; | ||
| 98 | + let safeEvents = { ...events }; | ||
| 99 | + activeEvents.forEach(key => { | ||
| 100 | + safeEvents[key] = e => { | ||
| 101 | + const originEvent = events[key]; | ||
| 102 | + originEvent && originEvent(e); | ||
| 103 | + if (this.hoverStartTime) { | ||
| 104 | + setTimeout(() => { | ||
| 105 | + this.active = true; | ||
| 106 | + }, this.hoverStartTime); | ||
| 107 | + } else { | ||
| 108 | + this.active = true; | ||
| 109 | + } | ||
| 110 | + }; | ||
| 111 | + }); | ||
| 112 | + deactiveEvents.forEach(key => { | ||
| 113 | + safeEvents[key] = e => { | ||
| 114 | + const originEvent = events[key]; | ||
| 115 | + originEvent && originEvent(e); | ||
| 116 | + setTimeout(() => { | ||
| 117 | + this.active = false; | ||
| 118 | + }, this.hoverStayTime); | ||
| 119 | + }; | ||
| 120 | + }); | ||
| 121 | + return safeEvents; | ||
| 46 | }, | 122 | }, |
| 47 | }, | 123 | }, |
| 48 | }; | 124 | }; |
| @@ -0,0 +1,120 @@ | @@ -0,0 +1,120 @@ | ||
| 1 | +export const RGB = ({ r, g, b }) => { | ||
| 2 | + return `rgb(${r}, ${g}, ${b})`; | ||
| 3 | +}; | ||
| 4 | + | ||
| 5 | +// 将rgb颜色转成hex | ||
| 6 | +export const RGBToHex = (color = '') => { | ||
| 7 | + const rgb = color.split(','); | ||
| 8 | + const r = parseInt(rgb[0].split('(')[1]); | ||
| 9 | + const g = parseInt(rgb[1]); | ||
| 10 | + const b = parseInt(rgb[2].split(')')[0]); | ||
| 11 | + const hex = '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); | ||
| 12 | + return hex; | ||
| 13 | +}; | ||
| 14 | + | ||
| 15 | +// 将hex颜色转成rgb | ||
| 16 | +export const HexToRGBA = (hex = '', opacity) => { | ||
| 17 | + const red = parseInt(`0x${hex.slice(1, 3)}`); | ||
| 18 | + const green = parseInt(`0x${hex.slice(3, 5)}`); | ||
| 19 | + const blue = parseInt(`0x${hex.slice(5, 7)}`); | ||
| 20 | + const RGBA = `rgba(${red},${green},${blue},${opacity})`; | ||
| 21 | + return { red, green, blue, rgba: RGBA }; | ||
| 22 | +}; | ||
| 23 | + | ||
| 24 | +const RGB_MAX = 255; | ||
| 25 | +const HUE_MAX = 360; | ||
| 26 | +const SV_MAX = 100; | ||
| 27 | + | ||
| 28 | +export const HexToHSL = hex => { | ||
| 29 | + const { red, green, blue } = HexToRGBA(hex); | ||
| 30 | + return RGBToHSL(red, green, blue); | ||
| 31 | +}; | ||
| 32 | + | ||
| 33 | +export const HSLToRGB = function (h, s, l) { | ||
| 34 | + function _hue2Rgb(p, q, t) { | ||
| 35 | + if (t < 0) t += 1; | ||
| 36 | + if (t > 1) t -= 1; | ||
| 37 | + if (t < 1 / 6) return p + (q - p) * 6 * t; | ||
| 38 | + if (t < 1 / 2) return q; | ||
| 39 | + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; | ||
| 40 | + return p; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + function _normalizeAngle(degrees) { | ||
| 44 | + return ((degrees % 360) + 360) % 360; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + if (typeof h === 'object') { | ||
| 48 | + const args = h; | ||
| 49 | + h = args.h; | ||
| 50 | + s = args.s; | ||
| 51 | + l = args.l; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + var r, g, b; | ||
| 55 | + | ||
| 56 | + h = _normalizeAngle(h); | ||
| 57 | + h = h === HUE_MAX ? 1 : (h % HUE_MAX) / parseFloat(HUE_MAX); | ||
| 58 | + s = s === SV_MAX ? 1 : (s % SV_MAX) / parseFloat(SV_MAX); | ||
| 59 | + l = l === SV_MAX ? 1 : (l % SV_MAX) / parseFloat(SV_MAX); | ||
| 60 | + | ||
| 61 | + if (s === 0) { | ||
| 62 | + r = g = b = l; // achromatic | ||
| 63 | + } else { | ||
| 64 | + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; | ||
| 65 | + var p = 2 * l - q; | ||
| 66 | + r = _hue2Rgb(p, q, h + 1 / 3); | ||
| 67 | + g = _hue2Rgb(p, q, h); | ||
| 68 | + b = _hue2Rgb(p, q, h - 1 / 3); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + return { | ||
| 72 | + r: Math.round(r * RGB_MAX), | ||
| 73 | + g: Math.round(g * RGB_MAX), | ||
| 74 | + b: Math.round(b * RGB_MAX), | ||
| 75 | + }; | ||
| 76 | +}; | ||
| 77 | + | ||
| 78 | +export const RGBToHSL = (r, g, b) => { | ||
| 79 | + if (typeof r === 'object') { | ||
| 80 | + const args = r; | ||
| 81 | + r = args.r; | ||
| 82 | + g = args.g; | ||
| 83 | + b = args.b; | ||
| 84 | + } | ||
| 85 | + // It converts [0,255] format, to [0,1] | ||
| 86 | + r = r === RGB_MAX ? 1 : (r % RGB_MAX) / parseFloat(RGB_MAX); | ||
| 87 | + g = g === RGB_MAX ? 1 : (g % RGB_MAX) / parseFloat(RGB_MAX); | ||
| 88 | + b = b === RGB_MAX ? 1 : (b % RGB_MAX) / parseFloat(RGB_MAX); | ||
| 89 | + | ||
| 90 | + var max = Math.max(r, g, b); | ||
| 91 | + var min = Math.min(r, g, b); | ||
| 92 | + var h, | ||
| 93 | + s, | ||
| 94 | + l = (max + min) / 2; | ||
| 95 | + | ||
| 96 | + if (max === min) { | ||
| 97 | + h = s = 0; // achromatic | ||
| 98 | + } else { | ||
| 99 | + var d = max - min; | ||
| 100 | + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); | ||
| 101 | + switch (max) { | ||
| 102 | + case r: | ||
| 103 | + h = (g - b) / d + (g < b ? 6 : 0); | ||
| 104 | + break; | ||
| 105 | + case g: | ||
| 106 | + h = (b - r) / d + 2; | ||
| 107 | + break; | ||
| 108 | + case b: | ||
| 109 | + h = (r - g) / d + 4; | ||
| 110 | + break; | ||
| 111 | + } | ||
| 112 | + h /= 6; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + return { | ||
| 116 | + h: Math.round(h * HUE_MAX), | ||
| 117 | + s: Math.round(s * SV_MAX), | ||
| 118 | + l: Math.round(l * SV_MAX), | ||
| 119 | + }; | ||
| 120 | +}; |
yarn.lock
| @@ -2798,7 +2798,7 @@ color-string@^1.5.2: | @@ -2798,7 +2798,7 @@ color-string@^1.5.2: | ||
| 2798 | color-name "^1.0.0" | 2798 | color-name "^1.0.0" |
| 2799 | simple-swizzle "^0.2.2" | 2799 | simple-swizzle "^0.2.2" |
| 2800 | 2800 | ||
| 2801 | -color@^3.0.0: | 2801 | +color@^3.0.0, color@^3.1.2: |
| 2802 | version "3.1.2" | 2802 | version "3.1.2" |
| 2803 | resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" | 2803 | resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" |
| 2804 | integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA= | 2804 | integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA= |