diff --git a/.lesshintrc b/.lesshintrc index 09df84a9dc..8f8d42fa80 100644 --- a/.lesshintrc +++ b/.lesshintrc @@ -16,6 +16,7 @@ "components/style/core/base.less", "components/style/core/iconfont.less", "components/style/core/normalize.less", - "components/style/mixins/compatibility.less" + "components/style/mixins/compatibility.less", + "components/style/color/*" ] } diff --git a/components/alert/style/index.less b/components/alert/style/index.less index 098c69f338..35bddca27d 100644 --- a/components/alert/style/index.less +++ b/components/alert/style/index.less @@ -29,32 +29,32 @@ } &-success { - border: 1px solid tint(@success-color, 80%); - background-color: tint(@success-color, 90%); + border: 1px solid @green-2; + background-color: @green-1; .@{alert-prefix-cls}-icon { color: @success-color; } } &-info { - border: 1px solid tint(@primary-color, 80%); - background-color: tint(@primary-color, 90%); + border: 1px solid @primary-2; + background-color: @primary-1; .@{alert-prefix-cls}-icon { color: @primary-color; } } &-warning { - border: 1px solid tint(@warning-color, 80%); - background-color: tint(@warning-color, 90%); + border: 1px solid @yellow-2; + background-color: @yellow-1; .@{alert-prefix-cls}-icon { color: @warning-color; } } &-error { - border: 1px solid tint(@error-color, 80%); - background-color: tint(@error-color, 90%); + border: 1px solid @red-2; + background-color: @red-1; .@{alert-prefix-cls}-icon { color: @error-color; } diff --git a/components/breadcrumb/style/index.less b/components/breadcrumb/style/index.less index e244bca535..0d8fcf8815 100644 --- a/components/breadcrumb/style/index.less +++ b/components/breadcrumb/style/index.less @@ -10,7 +10,7 @@ color: @text-color; transition: color .3s; &:hover { - color: tint(@primary-color, 20%); + color: @primary-5; } } diff --git a/components/button/style/mixin.less b/components/button/style/mixin.less index 942019e23c..c17cfeff3e 100644 --- a/components/button/style/mixin.less +++ b/components/button/style/mixin.less @@ -21,15 +21,14 @@ .button-variant-primary(@color; @background) { .button-color(@color; @background; @background); - &:hover, &:focus { - .button-color(@color; tint(@background, 20%); tint(@background, 20%)); + .button-color(@color; ~`colorPalette("@{background}", 5)`; ~`colorPalette("@{background}", 5)`); } &:active, &.active { - .button-color(@color; shade(@background, 5%); shade(@background, 5%)); + .button-color(@color; ~`colorPalette("@{background}", 7)`; ~`colorPalette("@{background}", 7)`); } .button-disabled(); @@ -40,12 +39,12 @@ &:hover, &:focus { - .button-color(tint(@primary-color, 20%); @background; tint(@primary-color, 20%)); + .button-color(@primary-5; @background; @primary-5); } &:active, &.active { - .button-color(shade(@primary-color, 5%); @background; shade(@primary-color, 5%)); + .button-color(@primary-7; @background; @primary-7); } .button-disabled(); diff --git a/components/calendar/style/index.less b/components/calendar/style/index.less index f1aaa8230c..e57c99e3df 100644 --- a/components/calendar/style/index.less +++ b/components/calendar/style/index.less @@ -98,7 +98,7 @@ line-height: 22px; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } } @@ -137,7 +137,7 @@ &-last-month-cell &-value, &-next-month-btn-day &-value { - color: #ccc; + color: @disabled-color; } &-month-panel-table { @@ -179,11 +179,11 @@ color: @text-color; height: 116px; padding: 4px 8px; - border-top: 2px solid #eee; + border-top: 2px solid @border-color-split; transition: background 0.3s ease; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } } @@ -208,7 +208,7 @@ &-fullscreen &-month-panel-current-cell &-month, &-fullscreen &-today &-date { border-top-color: @primary-color; - background-color: tint(@primary-color, 90%); + background-color: @primary-1; color: @primary-color; } &-fullscreen &-month-panel-current-cell &-value { @@ -216,7 +216,7 @@ } &-fullscreen &-last-month-cell &-date, &-fullscreen &-next-month-btn-day &-date { - color: #ccc; + color: @disabled-color; } &-fullscreen &-content { diff --git a/components/cascader/style/index.less b/components/cascader/style/index.less index 1762f766dc..41f159b2ef 100644 --- a/components/cascader/style/index.less +++ b/components/cascader/style/index.less @@ -55,7 +55,7 @@ background: #fff; top: 50%; font-size: @font-size-base; - color: #ccc; + color: @disabled-color; width: 12px; height: 12px; margin-top: -6px; @@ -152,11 +152,11 @@ white-space: nowrap; transition: all 0.3s ease; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; } &-disabled { cursor: not-allowed; - color: #ccc; + color: @disabled-color; &:hover { background: transparent; } diff --git a/components/checkbox/style/mixin.less b/components/checkbox/style/mixin.less index 01bbc1e41b..fea8c7e8c8 100644 --- a/components/checkbox/style/mixin.less +++ b/components/checkbox/style/mixin.less @@ -101,7 +101,7 @@ &.@{checkbox-prefix-cls}-checked { .@{checkbox-inner-prefix-cls}:after { animation-name: none; - border-color: #ccc; + border-color: @disabled-color; } } @@ -115,7 +115,7 @@ } & + span { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } diff --git a/components/date-picker/style/Calendar.less b/components/date-picker/style/Calendar.less index faa39976df..fc4d8c9fd5 100644 --- a/components/date-picker/style/Calendar.less +++ b/components/date-picker/style/Calendar.less @@ -184,13 +184,13 @@ } &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } &:active { color: #fff; - background: tint(@primary-color, 20%); + background: @primary-5; } } @@ -202,7 +202,7 @@ &-last-month-cell &-date, &-next-month-btn-day &-date { - color: #ccc; + color: @disabled-color; } &-selected-day &-date { @@ -258,7 +258,7 @@ text-align: center; margin: 0 0 0 8px; &-disabled { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } @@ -280,7 +280,7 @@ .@{calendar-prefix-cls}-clear-btn:after { .iconfont-font("\e62e"); font-size: @font-size-base; - color: #ccc; + color: @disabled-color; display: inline-block; line-height: 1; width: 20px; diff --git a/components/date-picker/style/DecadePanel.less b/components/date-picker/style/DecadePanel.less index 0532fdd714..3d867b7772 100644 --- a/components/date-picker/style/DecadePanel.less +++ b/components/date-picker/style/DecadePanel.less @@ -42,7 +42,7 @@ transition: background 0.3s ease; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } } diff --git a/components/date-picker/style/MonthPanel.less b/components/date-picker/style/MonthPanel.less index 53eff09e61..fda1323560 100644 --- a/components/date-picker/style/MonthPanel.less +++ b/components/date-picker/style/MonthPanel.less @@ -61,7 +61,7 @@ transition: background 0.3s ease; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } } diff --git a/components/date-picker/style/Picker.less b/components/date-picker/style/Picker.less index 020f4b9f46..4f689683c8 100644 --- a/components/date-picker/style/Picker.less +++ b/components/date-picker/style/Picker.less @@ -51,7 +51,7 @@ background: #fff; top: 50%; font-size: @font-size-base; - color: #ccc; + color: @disabled-color; width: 14px; height: 14px; margin-top: -7px; diff --git a/components/date-picker/style/RangePicker.less b/components/date-picker/style/RangePicker.less index ee2b858f40..472479456d 100644 --- a/components/date-picker/style/RangePicker.less +++ b/components/date-picker/style/RangePicker.less @@ -130,7 +130,7 @@ &:before { content: ''; display: block; - background: tint(@primary-color, 90%); + background: @primary-1; border-radius: 0; border: 0; position: absolute; diff --git a/components/date-picker/style/TimePicker.less b/components/date-picker/style/TimePicker.less index b5eca2bd33..bc26f53628 100644 --- a/components/date-picker/style/TimePicker.less +++ b/components/date-picker/style/TimePicker.less @@ -100,7 +100,7 @@ } li:hover { - background: tint(@primary-color, 90%); + background: @primary-1; } li&-option-selected { @@ -152,7 +152,7 @@ margin-right: 60px; &-disabled { - color: #ccc; + color: @disabled-color; } } } diff --git a/components/date-picker/style/YearPanel.less b/components/date-picker/style/YearPanel.less index 86f4255089..dd3d0add6b 100644 --- a/components/date-picker/style/YearPanel.less +++ b/components/date-picker/style/YearPanel.less @@ -42,7 +42,7 @@ transition: background 0.3s ease; &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; cursor: pointer; } } diff --git a/components/dropdown/style/index.less b/components/dropdown/style/index.less index 6be7800bad..3ce7d6c1f1 100644 --- a/components/dropdown/style/index.less +++ b/components/dropdown/style/index.less @@ -68,16 +68,16 @@ } &:hover { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &-disabled { - color: #ccc; + color: @disabled-color; cursor: not-allowed; pointer-events: none; &:hover { - color: #ccc; + color: @disabled-color; background-color: @component-background; cursor: not-allowed; } diff --git a/components/input-number/style/index.less b/components/input-number/style/index.less index a8a5ccbcef..895a95acf5 100644 --- a/components/input-number/style/index.less +++ b/components/input-number/style/index.less @@ -37,7 +37,7 @@ } &:hover &-up-inner, &:hover &-down-inner { - color: tint(@primary-color, 20%); + color: @primary-5; } } diff --git a/components/input/style/mixin.less b/components/input/style/mixin.less index 1c4bd47b66..5737624c2e 100644 --- a/components/input/style/mixin.less +++ b/components/input/style/mixin.less @@ -18,21 +18,21 @@ // input status // == when focus or actived .active(@color: @outline-color) { - border-color: tint(@color, 20%); + border-color: ~`colorPalette("@{color}", 5)`; outline: 0; box-shadow: 0 0 @outline-blur-size @outline-width fade(@color, 20%); } // == when hoverd .hover(@color: @input-hover-border-color) { - border-color: tint(@color, 20%); + border-color: ~`colorPalette("@{color}", 5)`; } .disabled() { background-color: @input-disabled-bg; opacity: 1; cursor: not-allowed; - color: #ccc; + color: @disabled-color; &:hover { .hover(@input-border-color); } diff --git a/components/mention/style/index.less b/components/mention/style/index.less index 9e135e7cf1..4823a92754 100644 --- a/components/mention/style/index.less +++ b/components/mention/style/index.less @@ -54,7 +54,7 @@ overflow-y: auto; font-size: @font-size-base; &-notfound.@{ant-prefix}-mention-dropdown-item { - color: #ccc; + color: @disabled-color; .@{iconfont-css-prefix}-loading { color: @primary-color; @@ -78,15 +78,15 @@ &:hover, &.focus, &-active { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &-disabled { - color: #ccc; + color: @disabled-color; cursor: not-allowed; &:hover { - color: #ccc; + color: @disabled-color; background-color: @component-background; cursor: not-allowed; } diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 85f7b506ba..5b2d1d6c17 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -97,7 +97,7 @@ } &:not(&-horizontal) &-item-selected { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &-horizontal, diff --git a/components/pagination/style/index.less b/components/pagination/style/index.less index 19e8573198..9cf37a2597 100644 --- a/components/pagination/style/index.less +++ b/components/pagination/style/index.less @@ -70,7 +70,7 @@ content: "•••"; display: block; letter-spacing: 2px; - color: #ccc; + color: @disabled-color; text-align: center; } @@ -175,13 +175,13 @@ &:hover { border-color: @border-color-base; a { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } cursor: not-allowed; a { - color: #ccc; + color: @disabled-color; } } diff --git a/components/radio/style/index.less b/components/radio/style/index.less index 624a300f6d..c86b00f31c 100644 --- a/components/radio/style/index.less +++ b/components/radio/style/index.less @@ -103,7 +103,7 @@ } & + span { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } @@ -193,15 +193,15 @@ span.@{radio-prefix-cls} + * { } &:hover { - border-color: tint(@primary-color, 20%); - box-shadow: -1px 0 0 0 tint(@primary-color, 20%); - color: tint(@primary-color, 20%); + border-color: @primary-5; + box-shadow: -1px 0 0 0@primary-5; + color: @primary-5; } &:active { - border-color: shade(@primary-color, 5%); - box-shadow: -1px 0 0 0 shade(@primary-color, 5%); - color: shade(@primary-color, 5%); + border-color: @primary-7; + box-shadow: -1px 0 0 0@primary-7; + color: @primary-7; } } @@ -209,13 +209,13 @@ span.@{radio-prefix-cls} + * { border-color: @border-color-base; background-color: @background-color-base; cursor: not-allowed; - color: #ccc; + color: @disabled-color; &:first-child, &:hover { border-color: @border-color-base; background-color: @background-color-base; - color: #ccc; + color: @disabled-color; } &:first-child { border-left-color: @border-color-base; diff --git a/components/select/style/index.less b/components/select/style/index.less index a6d50b0c19..1c20b66a27 100644 --- a/components/select/style/index.less +++ b/components/select/style/index.less @@ -18,7 +18,7 @@ background: @component-background; top: 50%; font-size: @font-size-base; - color: #ccc; + color: @disabled-color; width: 12px; height: 12px; margin-top: -6px; @@ -107,7 +107,7 @@ } &-disabled { - color: #ccc; + color: @disabled-color; } &-disabled &-selection { @@ -198,10 +198,10 @@ } &-disabled &-selection__choice__remove { - color: #ccc; + color: @disabled-color; cursor: default; &:hover { - color: #ccc; + color: @disabled-color; } } @@ -450,15 +450,15 @@ &:hover, &-active { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &-disabled { - color: #ccc; + color: @disabled-color; cursor: not-allowed; &:hover { - color: #ccc; + color: @disabled-color; background-color: @component-background; cursor: not-allowed; } diff --git a/components/slider/demo/icon-slider.md b/components/slider/demo/icon-slider.md index 01acbdb00c..aed803d06e 100644 --- a/components/slider/demo/icon-slider.md +++ b/components/slider/demo/icon-slider.md @@ -64,7 +64,7 @@ ReactDOM.render( 0.0) { + aB = currentT; + } else { + aA = currentT; + } + } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return currentT; + } + + function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { + for (var i = 0; i < NEWTON_ITERATIONS; ++i) { + var currentSlope = getSlope(aGuessT, mX1, mX2); + if (currentSlope === 0.0) { + return aGuessT; + } + var currentX = calcBezier(aGuessT, mX1, mX2) - aX; + aGuessT -= currentX / currentSlope; + } + return aGuessT; + } + + var BezierEasing = function (mX1, mY1, mX2, mY2) { + if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { + throw new Error('bezier x values must be in [0, 1] range'); + } + + // Precompute samples table + var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); + if (mX1 !== mY1 || mX2 !== mY2) { + for (var i = 0; i < kSplineTableSize; ++i) { + sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); + } + } + + function getTForX (aX) { + var intervalStart = 0.0; + var currentSample = 1; + var lastSample = kSplineTableSize - 1; + + for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { + intervalStart += kSampleStepSize; + } + --currentSample; + + // Interpolate to provide an initial guess for t + var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); + var guessForT = intervalStart + dist * kSampleStepSize; + + var initialSlope = getSlope(guessForT, mX1, mX2); + if (initialSlope >= NEWTON_MIN_SLOPE) { + return newtonRaphsonIterate(aX, guessForT, mX1, mX2); + } else if (initialSlope === 0.0) { + return guessForT; + } else { + return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); + } + } + + return function BezierEasing (x) { + if (mX1 === mY1 && mX2 === mY2) { + return x; // linear + } + // Because JavaScript number are imprecise, we should guarantee the extremes are right. + if (x === 0) { + return 0; + } + if (x === 1) { + return 1; + } + return calcBezier(getTForX(x), mY1, mY2); + }; + }; + + this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18); +})()`; diff --git a/components/style/color/colorPalette.less b/components/style/color/colorPalette.less new file mode 100644 index 0000000000..b98cfc2b1d --- /dev/null +++ b/components/style/color/colorPalette.less @@ -0,0 +1,40 @@ +@import "bezierEasing"; +@import "tinyColor"; + +// We create a very complex algorithm which take the place of original tint/shade color system +// to make sure no one can understand it +// and create an entire color palette magicly by inputing just a single primary color. +// We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin +@functions: ~`(function() { + var warmDark = 0.5; // warm color darken radio + var warmRotate = -26; // warm color rotate degree + var coldDark = 0.55; // cold color darken radio + var coldRotate = 10; // cold color rotate degree + var getShadeColor = function(c) { + var shadeColor = tinycolor(c); + // warm and cold color will darken in different radio, and rotate in different degree + // warmer color + if (shadeColor.toRgb().r > shadeColor.toRgb().b) { + return shadeColor.darken(shadeColor.toHsl().l * warmDark * 100).spin(warmRotate).toHexString(); + } + // colder color + return shadeColor.darken(shadeColor.toHsl().l * coldDark * 100).spin(coldRotate).toHexString(); + } + var primaryEasing = colorEasing(0.6); + this.colorPalette = function(color, index) { + var currentEasing = colorEasing(index * 0.1); + // return light colors after tint + if (index <= 6) { + return tinycolor.mix( + '#ffffff', + color, + currentEasing * 100 / primaryEasing + ).toHexString(); + } + return tinycolor.mix( + getShadeColor(color), + color, + (1 - (currentEasing - primaryEasing) / (1 - primaryEasing)) * 100 + ).toHexString(); + }; +})()`; diff --git a/components/style/color/colors.less b/components/style/color/colors.less new file mode 100644 index 0000000000..a285c3bdee --- /dev/null +++ b/components/style/color/colors.less @@ -0,0 +1,90 @@ +@import 'colorPalette'; + +// color palettes +@blue-1: color(~`colorPalette("@{blue-6}", 1)`); +@blue-2: color(~`colorPalette("@{blue-6}", 2)`); +@blue-3: color(~`colorPalette("@{blue-6}", 3)`); +@blue-4: color(~`colorPalette("@{blue-6}", 4)`); +@blue-5: color(~`colorPalette("@{blue-6}", 5)`); +@blue-6: #108ee9; +@blue-7: color(~`colorPalette("@{blue-6}", 7)`); +@blue-8: color(~`colorPalette("@{blue-6}", 8)`); +@blue-9: color(~`colorPalette("@{blue-6}", 9)`); +@blue-10: color(~`colorPalette("@{blue-6}", 10)`); + +@purple-1: color(~`colorPalette("@{purple-6}", 1)`); +@purple-2: color(~`colorPalette("@{purple-6}", 2)`); +@purple-3: color(~`colorPalette("@{purple-6}", 3)`); +@purple-4: color(~`colorPalette("@{purple-6}", 4)`); +@purple-5: color(~`colorPalette("@{purple-6}", 5)`); +@purple-6: #7265E6; +@purple-7: color(~`colorPalette("@{purple-6}", 7)`); +@purple-8: color(~`colorPalette("@{purple-6}", 8)`); +@purple-9: color(~`colorPalette("@{purple-6}", 9)`); +@purple-10: color(~`colorPalette("@{purple-6}", 10)`); + +@cyan-1: color(~`colorPalette("@{cyan-6}", 1)`); +@cyan-2: color(~`colorPalette("@{cyan-6}", 2)`); +@cyan-3: color(~`colorPalette("@{cyan-6}", 3)`); +@cyan-4: color(~`colorPalette("@{cyan-6}", 4)`); +@cyan-5: color(~`colorPalette("@{cyan-6}", 5)`); +@cyan-6: #00A2AE; +@cyan-7: color(~`colorPalette("@{cyan-6}", 7)`); +@cyan-8: color(~`colorPalette("@{cyan-6}", 8)`); +@cyan-9: color(~`colorPalette("@{cyan-6}", 9)`); +@cyan-10: color(~`colorPalette("@{cyan-6}", 10)`); + +@green-1: color(~`colorPalette("@{green-6}", 1)`); +@green-2: color(~`colorPalette("@{green-6}", 2)`); +@green-3: color(~`colorPalette("@{green-6}", 3)`); +@green-4: color(~`colorPalette("@{green-6}", 4)`); +@green-5: color(~`colorPalette("@{green-6}", 5)`); +@green-6: #00A854; +@green-7: color(~`colorPalette("@{green-6}", 7)`); +@green-8: color(~`colorPalette("@{green-6}", 8)`); +@green-9: color(~`colorPalette("@{green-6}", 9)`); +@green-10: color(~`colorPalette("@{green-6}", 10)`); + +@pink-1: color(~`colorPalette("@{pink-6}", 1)`); +@pink-2: color(~`colorPalette("@{pink-6}", 2)`); +@pink-3: color(~`colorPalette("@{pink-6}", 3)`); +@pink-4: color(~`colorPalette("@{pink-6}", 4)`); +@pink-5: color(~`colorPalette("@{pink-6}", 5)`); +@pink-6: #f5317f; +@pink-7: color(~`colorPalette("@{pink-6}", 7)`); +@pink-8: color(~`colorPalette("@{pink-6}", 8)`); +@pink-9: color(~`colorPalette("@{pink-6}", 9)`); +@pink-10: color(~`colorPalette("@{pink-6}", 10)`); + +@red-1: color(~`colorPalette("@{red-6}", 1)`); +@red-2: color(~`colorPalette("@{red-6}", 2)`); +@red-3: color(~`colorPalette("@{red-6}", 3)`); +@red-4: color(~`colorPalette("@{red-6}", 4)`); +@red-5: color(~`colorPalette("@{red-6}", 5)`); +@red-6: #F04134; +@red-7: color(~`colorPalette("@{red-6}", 7)`); +@red-8: color(~`colorPalette("@{red-6}", 8)`); +@red-9: color(~`colorPalette("@{red-6}", 9)`); +@red-10: color(~`colorPalette("@{red-6}", 10)`); + +@orange-1: color(~`colorPalette("@{orange-6}", 1)`); +@orange-2: color(~`colorPalette("@{orange-6}", 2)`); +@orange-3: color(~`colorPalette("@{orange-6}", 3)`); +@orange-4: color(~`colorPalette("@{orange-6}", 4)`); +@orange-5: color(~`colorPalette("@{orange-6}", 5)`); +@orange-6: #F56A00; +@orange-7: color(~`colorPalette("@{orange-6}", 7)`); +@orange-8: color(~`colorPalette("@{orange-6}", 8)`); +@orange-9: color(~`colorPalette("@{orange-6}", 9)`); +@orange-10: color(~`colorPalette("@{orange-6}", 10)`); + +@yellow-1: color(~`colorPalette("@{yellow-6}", 1)`); +@yellow-2: color(~`colorPalette("@{yellow-6}", 2)`); +@yellow-3: color(~`colorPalette("@{yellow-6}", 3)`); +@yellow-4: color(~`colorPalette("@{yellow-6}", 4)`); +@yellow-5: color(~`colorPalette("@{yellow-6}", 5)`); +@yellow-6: #ffbf00; +@yellow-7: color(~`colorPalette("@{yellow-6}", 7)`); +@yellow-8: color(~`colorPalette("@{yellow-6}", 8)`); +@yellow-9: color(~`colorPalette("@{yellow-6}", 9)`); +@yellow-10: color(~`colorPalette("@{yellow-6}", 10)`); diff --git a/components/style/color/tinyColor.less b/components/style/color/tinyColor.less new file mode 100644 index 0000000000..f6c7ab87f4 --- /dev/null +++ b/components/style/color/tinyColor.less @@ -0,0 +1,1182 @@ +@functions: ~`(function() { +// TinyColor v1.4.1 +// https://github.com/bgrins/TinyColor +// 2016-07-07, Brian Grinstead, MIT License +var trimLeft = /^\s+/, + trimRight = /\s+$/, + tinyCounter = 0, + mathRound = Math.round, + mathMin = Math.min, + mathMax = Math.max, + mathRandom = Math.random; + +function tinycolor (color, opts) { + + color = (color) ? color : ''; + opts = opts || { }; + + // If input is already a tinycolor, return itself + if (color instanceof tinycolor) { + return color; + } + // If we are called as a function, call using new instead + if (!(this instanceof tinycolor)) { + return new tinycolor(color, opts); + } + + var rgb = inputToRGB(color); + this._originalInput = color, + this._r = rgb.r, + this._g = rgb.g, + this._b = rgb.b, + this._a = rgb.a, + this._roundA = mathRound(100*this._a) / 100, + this._format = opts.format || rgb.format; + this._gradientType = opts.gradientType; + + // Don't let the range of [0,255] come back in [0,1]. + // Potentially lose a little bit of precision here, but will fix issues where + // .5 gets interpreted as half of the total, instead of half of 1 + // If it was supposed to be 128, this was already taken care of by inputToRgb + if (this._r < 1) { this._r = mathRound(this._r); } + if (this._g < 1) { this._g = mathRound(this._g); } + if (this._b < 1) { this._b = mathRound(this._b); } + + this._ok = rgb.ok; + this._tc_id = tinyCounter++; +} + +tinycolor.prototype = { + isDark: function() { + return this.getBrightness() < 128; + }, + isLight: function() { + return !this.isDark(); + }, + isValid: function() { + return this._ok; + }, + getOriginalInput: function() { + return this._originalInput; + }, + getFormat: function() { + return this._format; + }, + getAlpha: function() { + return this._a; + }, + getBrightness: function() { + //http://www.w3.org/TR/AERT#color-contrast + var rgb = this.toRgb(); + return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; + }, + getLuminance: function() { + //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + var rgb = this.toRgb(); + var RsRGB, GsRGB, BsRGB, R, G, B; + RsRGB = rgb.r/255; + GsRGB = rgb.g/255; + BsRGB = rgb.b/255; + + if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);} + if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);} + if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);} + return (0.2126 * R) + (0.7152 * G) + (0.0722 * B); + }, + setAlpha: function(value) { + this._a = boundAlpha(value); + this._roundA = mathRound(100*this._a) / 100; + return this; + }, + toHsv: function() { + var hsv = rgbToHsv(this._r, this._g, this._b); + return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; + }, + toHsvString: function() { + var hsv = rgbToHsv(this._r, this._g, this._b); + var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); + return (this._a == 1) ? + "hsv(" + h + ", " + s + "%, " + v + "%)" : + "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")"; + }, + toHsl: function() { + var hsl = rgbToHsl(this._r, this._g, this._b); + return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a }; + }, + toHslString: function() { + var hsl = rgbToHsl(this._r, this._g, this._b); + var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); + return (this._a == 1) ? + "hsl(" + h + ", " + s + "%, " + l + "%)" : + "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")"; + }, + toHex: function(allow3Char) { + return rgbToHex(this._r, this._g, this._b, allow3Char); + }, + toHexString: function(allow3Char) { + return '#' + this.toHex(allow3Char); + }, + toHex8: function(allow4Char) { + return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); + }, + toHex8String: function(allow4Char) { + return '#' + this.toHex8(allow4Char); + }, + toRgb: function() { + return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a }; + }, + toRgbString: function() { + return (this._a == 1) ? + "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : + "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"; + }, + toPercentageRgb: function() { + return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a }; + }, + toPercentageRgbString: function() { + return (this._a == 1) ? + "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : + "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; + }, + toName: function() { + if (this._a === 0) { + return "transparent"; + } + + if (this._a < 1) { + return false; + } + + return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; + }, + toFilter: function(secondColor) { + var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a); + var secondHex8String = hex8String; + var gradientType = this._gradientType ? "GradientType = 1, " : ""; + + if (secondColor) { + var s = tinycolor(secondColor); + secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a); + } + + return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"; + }, + toString: function(format) { + var formatSet = !!format; + format = format || this._format; + + var formattedString = false; + var hasAlpha = this._a < 1 && this._a >= 0; + var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); + + if (needsAlphaFormat) { + // Special case for "transparent", all other non-alpha formats + // will return rgba when there is transparency. + if (format === "name" && this._a === 0) { + return this.toName(); + } + return this.toRgbString(); + } + if (format === "rgb") { + formattedString = this.toRgbString(); + } + if (format === "prgb") { + formattedString = this.toPercentageRgbString(); + } + if (format === "hex" || format === "hex6") { + formattedString = this.toHexString(); + } + if (format === "hex3") { + formattedString = this.toHexString(true); + } + if (format === "hex4") { + formattedString = this.toHex8String(true); + } + if (format === "hex8") { + formattedString = this.toHex8String(); + } + if (format === "name") { + formattedString = this.toName(); + } + if (format === "hsl") { + formattedString = this.toHslString(); + } + if (format === "hsv") { + formattedString = this.toHsvString(); + } + + return formattedString || this.toHexString(); + }, + clone: function() { + return tinycolor(this.toString()); + }, + + _applyModification: function(fn, args) { + var color = fn.apply(null, [this].concat([].slice.call(args))); + this._r = color._r; + this._g = color._g; + this._b = color._b; + this.setAlpha(color._a); + return this; + }, + lighten: function() { + return this._applyModification(lighten, arguments); + }, + brighten: function() { + return this._applyModification(brighten, arguments); + }, + darken: function() { + return this._applyModification(darken, arguments); + }, + desaturate: function() { + return this._applyModification(desaturate, arguments); + }, + saturate: function() { + return this._applyModification(saturate, arguments); + }, + greyscale: function() { + return this._applyModification(greyscale, arguments); + }, + spin: function() { + return this._applyModification(spin, arguments); + }, + + _applyCombination: function(fn, args) { + return fn.apply(null, [this].concat([].slice.call(args))); + }, + analogous: function() { + return this._applyCombination(analogous, arguments); + }, + complement: function() { + return this._applyCombination(complement, arguments); + }, + monochromatic: function() { + return this._applyCombination(monochromatic, arguments); + }, + splitcomplement: function() { + return this._applyCombination(splitcomplement, arguments); + }, + triad: function() { + return this._applyCombination(triad, arguments); + }, + tetrad: function() { + return this._applyCombination(tetrad, arguments); + } +}; + +// If input is an object, force 1 into "1.0" to handle ratios properly +// String input requires "1.0" as input, so 1 will be treated as 1 +tinycolor.fromRatio = function(color, opts) { + if (typeof color == "object") { + var newColor = {}; + for (var i in color) { + if (color.hasOwnProperty(i)) { + if (i === "a") { + newColor[i] = color[i]; + } + else { + newColor[i] = convertToPercentage(color[i]); + } + } + } + color = newColor; + } + + return tinycolor(color, opts); +}; + +// Given a string or object, convert that input to RGB +// Possible string inputs: +// +// "red" +// "#f00" or "f00" +// "#ff0000" or "ff0000" +// "#ff000000" or "ff000000" +// "rgb 255 0 0" or "rgb (255, 0, 0)" +// "rgb 1.0 0 0" or "rgb (1, 0, 0)" +// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" +// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" +// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" +// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" +// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" +// +function inputToRGB(color) { + + var rgb = { r: 0, g: 0, b: 0 }; + var a = 1; + var s = null; + var v = null; + var l = null; + var ok = false; + var format = false; + + if (typeof color == "string") { + color = stringInputToObject(color); + } + + if (typeof color == "object") { + if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { + rgb = rgbToRgb(color.r, color.g, color.b); + ok = true; + format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; + } + else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { + s = convertToPercentage(color.s); + v = convertToPercentage(color.v); + rgb = hsvToRgb(color.h, s, v); + ok = true; + format = "hsv"; + } + else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { + s = convertToPercentage(color.s); + l = convertToPercentage(color.l); + rgb = hslToRgb(color.h, s, l); + ok = true; + format = "hsl"; + } + + if (color.hasOwnProperty("a")) { + a = color.a; + } + } + + a = boundAlpha(a); + + return { + ok: ok, + format: color.format || format, + r: mathMin(255, mathMax(rgb.r, 0)), + g: mathMin(255, mathMax(rgb.g, 0)), + b: mathMin(255, mathMax(rgb.b, 0)), + a: a + }; +} + + +// Conversion Functions +// -------------------- + +// rgbToHsl, rgbToHsv, hslToRgb, hsvToRgb modified from: +// + +// rgbToRgb +// Handle bounds / percentage checking to conform to CSS color spec +// +// *Assumes:* r, g, b in [0, 255] or [0, 1] +// *Returns:* { r, g, b } in [0, 255] +function rgbToRgb(r, g, b){ + return { + r: bound01(r, 255) * 255, + g: bound01(g, 255) * 255, + b: bound01(b, 255) * 255 + }; +} + +// rgbToHsl +// Converts an RGB color value to HSL. +// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] +// *Returns:* { h, s, l } in [0,1] +function rgbToHsl(r, g, b) { + + r = bound01(r, 255); + g = bound01(g, 255); + b = bound01(b, 255); + + var max = mathMax(r, g, b), min = mathMin(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min) { + h = s = 0; // achromatic + } + else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + + h /= 6; + } + + return { h: h, s: s, l: l }; +} + +// hslToRgb +// Converts an HSL color value to RGB. +// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] +// *Returns:* { r, g, b } in the set [0, 255] +function hslToRgb(h, s, l) { + var r, g, b; + + h = bound01(h, 360); + s = bound01(s, 100); + l = bound01(l, 100); + + function hue2rgb(p, q, t) { + if(t < 0) t += 1; + if(t > 1) t -= 1; + if(t < 1/6) return p + (q - p) * 6 * t; + if(t < 1/2) return q; + if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + } + + if(s === 0) { + r = g = b = l; // achromatic + } + else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return { r: r * 255, g: g * 255, b: b * 255 }; +} + +// rgbToHsv +// Converts an RGB color value to HSV +// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] +// *Returns:* { h, s, v } in [0,1] +function rgbToHsv(r, g, b) { + + r = bound01(r, 255); + g = bound01(g, 255); + b = bound01(b, 255); + + var max = mathMax(r, g, b), min = mathMin(r, g, b); + var h, s, v = max; + + var d = max - min; + s = max === 0 ? 0 : d / max; + + if(max == min) { + h = 0; // achromatic + } + else { + switch(max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h, s: s, v: v }; +} + +// hsvToRgb +// Converts an HSV color value to RGB. +// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] +// *Returns:* { r, g, b } in the set [0, 255] + function hsvToRgb(h, s, v) { + + h = bound01(h, 360) * 6; + s = bound01(s, 100); + v = bound01(v, 100); + + var i = Math.floor(h), + f = h - i, + p = v * (1 - s), + q = v * (1 - f * s), + t = v * (1 - (1 - f) * s), + mod = i % 6, + r = [v, q, p, p, t, v][mod], + g = [t, v, v, q, p, p][mod], + b = [p, p, t, v, v, q][mod]; + + return { r: r * 255, g: g * 255, b: b * 255 }; +} + +// rgbToHex +// Converts an RGB color to hex +// Assumes r, g, and b are contained in the set [0, 255] +// Returns a 3 or 6 character hex +function rgbToHex(r, g, b, allow3Char) { + + var hex = [ + pad2(mathRound(r).toString(16)), + pad2(mathRound(g).toString(16)), + pad2(mathRound(b).toString(16)) + ]; + + // Return a 3 character hex if possible + if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { + return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); + } + + return hex.join(""); +} + +// rgbaToHex +// Converts an RGBA color plus alpha transparency to hex +// Assumes r, g, b are contained in the set [0, 255] and +// a in [0, 1]. Returns a 4 or 8 character rgba hex +function rgbaToHex(r, g, b, a, allow4Char) { + + var hex = [ + pad2(mathRound(r).toString(16)), + pad2(mathRound(g).toString(16)), + pad2(mathRound(b).toString(16)), + pad2(convertDecimalToHex(a)) + ]; + + // Return a 4 character hex if possible + if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { + return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); + } + + return hex.join(""); +} + +// rgbaToArgbHex +// Converts an RGBA color to an ARGB Hex8 string +// Rarely used, but required for "toFilter()" +function rgbaToArgbHex(r, g, b, a) { + + var hex = [ + pad2(convertDecimalToHex(a)), + pad2(mathRound(r).toString(16)), + pad2(mathRound(g).toString(16)), + pad2(mathRound(b).toString(16)) + ]; + + return hex.join(""); +} + +// equals +// Can be called with any tinycolor input +tinycolor.equals = function (color1, color2) { + if (!color1 || !color2) { return false; } + return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); +}; + +tinycolor.random = function() { + return tinycolor.fromRatio({ + r: mathRandom(), + g: mathRandom(), + b: mathRandom() + }); +}; + + +// Modification Functions +// ---------------------- +// Thanks to less.js for some of the basics here +// + +function desaturate(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.s -= amount / 100; + hsl.s = clamp01(hsl.s); + return tinycolor(hsl); +} + +function saturate(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.s += amount / 100; + hsl.s = clamp01(hsl.s); + return tinycolor(hsl); +} + +function greyscale(color) { + return tinycolor(color).desaturate(100); +} + +function lighten (color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.l += amount / 100; + hsl.l = clamp01(hsl.l); + return tinycolor(hsl); +} + +function brighten(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var rgb = tinycolor(color).toRgb(); + rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100)))); + rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100)))); + rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100)))); + return tinycolor(rgb); +} + +function darken (color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.l -= amount / 100; + hsl.l = clamp01(hsl.l); + return tinycolor(hsl); +} + +// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. +// Values outside of this range will be wrapped into this range. +function spin(color, amount) { + var hsl = tinycolor(color).toHsl(); + var hue = (hsl.h + amount) % 360; + hsl.h = hue < 0 ? 360 + hue : hue; + return tinycolor(hsl); +} + +// Combination Functions +// --------------------- +// Thanks to jQuery xColor for some of the ideas behind these +// + +function complement(color) { + var hsl = tinycolor(color).toHsl(); + hsl.h = (hsl.h + 180) % 360; + return tinycolor(hsl); +} + +function triad(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) + ]; +} + +function tetrad(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) + ]; +} + +function splitcomplement(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), + tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) + ]; +} + +function analogous(color, results, slices) { + results = results || 6; + slices = slices || 30; + + var hsl = tinycolor(color).toHsl(); + var part = 360 / slices; + var ret = [tinycolor(color)]; + + for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { + hsl.h = (hsl.h + part) % 360; + ret.push(tinycolor(hsl)); + } + return ret; +} + +function monochromatic(color, results) { + results = results || 6; + var hsv = tinycolor(color).toHsv(); + var h = hsv.h, s = hsv.s, v = hsv.v; + var ret = []; + var modification = 1 / results; + + while (results--) { + ret.push(tinycolor({ h: h, s: s, v: v})); + v = (v + modification) % 1; + } + + return ret; +} + +// Utility Functions +// --------------------- + +tinycolor.mix = function(color1, color2, amount) { + amount = (amount === 0) ? 0 : (amount || 50); + + var rgb1 = tinycolor(color1).toRgb(); + var rgb2 = tinycolor(color2).toRgb(); + + var p = amount / 100; + + var rgba = { + r: ((rgb2.r - rgb1.r) * p) + rgb1.r, + g: ((rgb2.g - rgb1.g) * p) + rgb1.g, + b: ((rgb2.b - rgb1.b) * p) + rgb1.b, + a: ((rgb2.a - rgb1.a) * p) + rgb1.a + }; + + return tinycolor(rgba); +}; + + +// Readability Functions +// --------------------- +// false +// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false +tinycolor.isReadable = function(color1, color2, wcag2) { + var readability = tinycolor.readability(color1, color2); + var wcag2Parms, out; + + out = false; + + wcag2Parms = validateWCAG2Parms(wcag2); + switch (wcag2Parms.level + wcag2Parms.size) { + case "AAsmall": + case "AAAlarge": + out = readability >= 4.5; + break; + case "AAlarge": + out = readability >= 3; + break; + case "AAAsmall": + out = readability >= 7; + break; + } + return out; + +}; + +// mostReadable +// Given a base color and a list of possible foreground or background +// colors for that base, returns the most readable color. +// Optionally returns Black or White if the most readable color is unreadable. +// *Example* +// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" +// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" +// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" +// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" +tinycolor.mostReadable = function(baseColor, colorList, args) { + var bestColor = null; + var bestScore = 0; + var readability; + var includeFallbackColors, level, size ; + args = args || {}; + includeFallbackColors = args.includeFallbackColors ; + level = args.level; + size = args.size; + + for (var i= 0; i < colorList.length ; i++) { + readability = tinycolor.readability(baseColor, colorList[i]); + if (readability > bestScore) { + bestScore = readability; + bestColor = tinycolor(colorList[i]); + } + } + + if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) { + return bestColor; + } + else { + args.includeFallbackColors=false; + return tinycolor.mostReadable(baseColor,["#fff", "#000"],args); + } +}; + + +// Big List of Colors +// ------------------ +// +var names = tinycolor.names = { + aliceblue: "f0f8ff", + antiquewhite: "faebd7", + aqua: "0ff", + aquamarine: "7fffd4", + azure: "f0ffff", + beige: "f5f5dc", + bisque: "ffe4c4", + black: "000", + blanchedalmond: "ffebcd", + blue: "00f", + blueviolet: "8a2be2", + brown: "a52a2a", + burlywood: "deb887", + burntsienna: "ea7e5d", + cadetblue: "5f9ea0", + chartreuse: "7fff00", + chocolate: "d2691e", + coral: "ff7f50", + cornflowerblue: "6495ed", + cornsilk: "fff8dc", + crimson: "dc143c", + cyan: "0ff", + darkblue: "00008b", + darkcyan: "008b8b", + darkgoldenrod: "b8860b", + darkgray: "a9a9a9", + darkgreen: "006400", + darkgrey: "a9a9a9", + darkkhaki: "bdb76b", + darkmagenta: "8b008b", + darkolivegreen: "556b2f", + darkorange: "ff8c00", + darkorchid: "9932cc", + darkred: "8b0000", + darksalmon: "e9967a", + darkseagreen: "8fbc8f", + darkslateblue: "483d8b", + darkslategray: "2f4f4f", + darkslategrey: "2f4f4f", + darkturquoise: "00ced1", + darkviolet: "9400d3", + deeppink: "ff1493", + deepskyblue: "00bfff", + dimgray: "696969", + dimgrey: "696969", + dodgerblue: "1e90ff", + firebrick: "b22222", + floralwhite: "fffaf0", + forestgreen: "228b22", + fuchsia: "f0f", + gainsboro: "dcdcdc", + ghostwhite: "f8f8ff", + gold: "ffd700", + goldenrod: "daa520", + gray: "808080", + green: "008000", + greenyellow: "adff2f", + grey: "808080", + honeydew: "f0fff0", + hotpink: "ff69b4", + indianred: "cd5c5c", + indigo: "4b0082", + ivory: "fffff0", + khaki: "f0e68c", + lavender: "e6e6fa", + lavenderblush: "fff0f5", + lawngreen: "7cfc00", + lemonchiffon: "fffacd", + lightblue: "add8e6", + lightcoral: "f08080", + lightcyan: "e0ffff", + lightgoldenrodyellow: "fafad2", + lightgray: "d3d3d3", + lightgreen: "90ee90", + lightgrey: "d3d3d3", + lightpink: "ffb6c1", + lightsalmon: "ffa07a", + lightseagreen: "20b2aa", + lightskyblue: "87cefa", + lightslategray: "789", + lightslategrey: "789", + lightsteelblue: "b0c4de", + lightyellow: "ffffe0", + lime: "0f0", + limegreen: "32cd32", + linen: "faf0e6", + magenta: "f0f", + maroon: "800000", + mediumaquamarine: "66cdaa", + mediumblue: "0000cd", + mediumorchid: "ba55d3", + mediumpurple: "9370db", + mediumseagreen: "3cb371", + mediumslateblue: "7b68ee", + mediumspringgreen: "00fa9a", + mediumturquoise: "48d1cc", + mediumvioletred: "c71585", + midnightblue: "191970", + mintcream: "f5fffa", + mistyrose: "ffe4e1", + moccasin: "ffe4b5", + navajowhite: "ffdead", + navy: "000080", + oldlace: "fdf5e6", + olive: "808000", + olivedrab: "6b8e23", + orange: "ffa500", + orangered: "ff4500", + orchid: "da70d6", + palegoldenrod: "eee8aa", + palegreen: "98fb98", + paleturquoise: "afeeee", + palevioletred: "db7093", + papayawhip: "ffefd5", + peachpuff: "ffdab9", + peru: "cd853f", + pink: "ffc0cb", + plum: "dda0dd", + powderblue: "b0e0e6", + purple: "800080", + rebeccapurple: "663399", + red: "f00", + rosybrown: "bc8f8f", + royalblue: "4169e1", + saddlebrown: "8b4513", + salmon: "fa8072", + sandybrown: "f4a460", + seagreen: "2e8b57", + seashell: "fff5ee", + sienna: "a0522d", + silver: "c0c0c0", + skyblue: "87ceeb", + slateblue: "6a5acd", + slategray: "708090", + slategrey: "708090", + snow: "fffafa", + springgreen: "00ff7f", + steelblue: "4682b4", + tan: "d2b48c", + teal: "008080", + thistle: "d8bfd8", + tomato: "ff6347", + turquoise: "40e0d0", + violet: "ee82ee", + wheat: "f5deb3", + white: "fff", + whitesmoke: "f5f5f5", + yellow: "ff0", + yellowgreen: "9acd32" +}; + +// Make it easy to access colors via hexNames[hex] +var hexNames = tinycolor.hexNames = flip(names); + + +// Utilities +// --------- + +// { 'name1': 'val1' } becomes { 'val1': 'name1' } +function flip(o) { + var flipped = { }; + for (var i in o) { + if (o.hasOwnProperty(i)) { + flipped[o[i]] = i; + } + } + return flipped; +} + +// Return a valid alpha value [0,1] with all invalid values being set to 1 +function boundAlpha(a) { + a = parseFloat(a); + + if (isNaN(a) || a < 0 || a > 1) { + a = 1; + } + + return a; +} + +// Take input from [0, n] and return it as [0, 1] +function bound01(n, max) { + if (isOnePointZero(n)) { n = "100%"; } + + var processPercent = isPercentage(n); + n = mathMin(max, mathMax(0, parseFloat(n))); + + // Automatically convert percentage into number + if (processPercent) { + n = parseInt(n * max, 10) / 100; + } + + // Handle floating point rounding errors + if ((Math.abs(n - max) < 0.000001)) { + return 1; + } + + // Convert into [0, 1] range if it isn't already + return (n % max) / parseFloat(max); +} + +// Force a number between 0 and 1 +function clamp01(val) { + return mathMin(1, mathMax(0, val)); +} + +// Parse a base-16 hex value into a base-10 integer +function parseIntFromHex(val) { + return parseInt(val, 16); +} + +// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 +// +function isOnePointZero(n) { + return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; +} + +// Check to see if string passed in is a percentage +function isPercentage(n) { + return typeof n === "string" && n.indexOf('%') != -1; +} + +// Force a hex value to have 2 characters +function pad2(c) { + return c.length == 1 ? '0' + c : '' + c; +} + +// Replace a decimal with it's percentage value +function convertToPercentage(n) { + if (n <= 1) { + n = (n * 100) + "%"; + } + + return n; +} + +// Converts a decimal to a hex value +function convertDecimalToHex(d) { + return Math.round(parseFloat(d) * 255).toString(16); +} +// Converts a hex value to a decimal +function convertHexToDecimal(h) { + return (parseIntFromHex(h) / 255); +} + +var matchers = (function() { + + // + var CSS_INTEGER = "[-\\+]?\\d+%?"; + + // + var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; + + // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. + var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; + + // Actual matching. + // Parentheses and commas are optional, but not required. + // Whitespace can take the place of commas or opening paren + var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; + var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; + + return { + CSS_UNIT: new RegExp(CSS_UNIT), + rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), + rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), + hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), + hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), + hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), + hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), + hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, + hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, + hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, + hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ + }; +})(); + +// isValidCSSUnit +// Take in a single string / number and check to see if it looks like a CSS unit +// (see matchers above for definition). +function isValidCSSUnit(color) { + return !!matchers.CSS_UNIT.exec(color); +} + +// stringInputToObject +// Permissive string parsing. Take in a number of formats, and output an object +// based on detected format. Returns { r, g, b } or { h, s, l } or { h, s, v} +function stringInputToObject(color) { + + color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase(); + var named = false; + if (names[color]) { + color = names[color]; + named = true; + } + else if (color == 'transparent') { + return { r: 0, g: 0, b: 0, a: 0, format: "name" }; + } + + // Try to match string input using regular expressions. + // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] + // Just return an object and let the conversion functions handle that. + // This way the result will be the same whether the tinycolor is initialized with string or object. + var match; + if ((match = matchers.rgb.exec(color))) { + return { r: match[1], g: match[2], b: match[3] }; + } + if ((match = matchers.rgba.exec(color))) { + return { r: match[1], g: match[2], b: match[3], a: match[4] }; + } + if ((match = matchers.hsl.exec(color))) { + return { h: match[1], s: match[2], l: match[3] }; + } + if ((match = matchers.hsla.exec(color))) { + return { h: match[1], s: match[2], l: match[3], a: match[4] }; + } + if ((match = matchers.hsv.exec(color))) { + return { h: match[1], s: match[2], v: match[3] }; + } + if ((match = matchers.hsva.exec(color))) { + return { h: match[1], s: match[2], v: match[3], a: match[4] }; + } + if ((match = matchers.hex8.exec(color))) { + return { + r: parseIntFromHex(match[1]), + g: parseIntFromHex(match[2]), + b: parseIntFromHex(match[3]), + a: convertHexToDecimal(match[4]), + format: named ? "name" : "hex8" + }; + } + if ((match = matchers.hex6.exec(color))) { + return { + r: parseIntFromHex(match[1]), + g: parseIntFromHex(match[2]), + b: parseIntFromHex(match[3]), + format: named ? "name" : "hex" + }; + } + if ((match = matchers.hex4.exec(color))) { + return { + r: parseIntFromHex(match[1] + '' + match[1]), + g: parseIntFromHex(match[2] + '' + match[2]), + b: parseIntFromHex(match[3] + '' + match[3]), + a: convertHexToDecimal(match[4] + '' + match[4]), + format: named ? "name" : "hex8" + }; + } + if ((match = matchers.hex3.exec(color))) { + return { + r: parseIntFromHex(match[1] + '' + match[1]), + g: parseIntFromHex(match[2] + '' + match[2]), + b: parseIntFromHex(match[3] + '' + match[3]), + format: named ? "name" : "hex" + }; + } + + return false; +} + +function validateWCAG2Parms(parms) { + // return valid WCAG2 parms for isReadable. + // If input parms are invalid, return {"level":"AA", "size":"small"} + var level, size; + parms = parms || {"level":"AA", "size":"small"}; + level = (parms.level || "AA").toUpperCase(); + size = (parms.size || "small").toLowerCase(); + if (level !== "AA" && level !== "AAA") { + level = "AA"; + } + if (size !== "small" && size !== "large") { + size = "small"; + } + return {"level":level, "size":size}; +} + +this.tinycolor = tinycolor; + +})()`; diff --git a/components/style/core/base.less b/components/style/core/base.less index 9e3a4264ed..bf0c4548ad 100644 --- a/components/style/core/base.less +++ b/components/style/core/base.less @@ -76,7 +76,7 @@ a { } &[disabled] { - color: #ccc; + color: @disabled-color; cursor: not-allowed; pointer-events: none; } diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 5b8f28ae83..ca4acc282b 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -1,22 +1,36 @@ +@import "../color/colors"; + // Prefix @ant-prefix : ant; // Color -@primary-color : #108ee9; -@success-color : #87d068; -@error-color : #f50; -@highlight-color : #f50; -@warning-color : #fa0; +@primary-color : @blue-6; +@success-color : @green-6; +@error-color : @red-6; +@highlight-color : @red-6; +@warning-color : @yellow-6; @normal-color : #d9d9d9; +@primary-1: color(~`colorPalette("@{primary-color}", 1)`); // replace tint(@primary-color, 90%) +@primary-2: color(~`colorPalette("@{primary-color}", 2)`); // replace tint(@primary-color, 80%) +@primary-3: color(~`colorPalette("@{primary-color}", 3)`); +@primary-4: color(~`colorPalette("@{primary-color}", 4)`); +@primary-5: color(~`colorPalette("@{primary-color}", 5)`); // replace tint(@primary-color, 20%) +@primary-6: @primary-color; // don't use, use @primary-color +@primary-7: color(~`colorPalette("@{primary-color}", 7)`); // replace shade(@primary-color, 5%) +@primary-8: color(~`colorPalette("@{primary-color}", 8)`); +@primary-9: color(~`colorPalette("@{primary-color}", 9)`); +@primary-10: color(~`colorPalette("@{primary-color}", 10)`); + // ------ Base & Require ------ @body-background : #fff; @component-background : #fff; @font-family : -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif; @code-family : Consolas, Menlo, Courier, monospace; -@text-color : #666; -@heading-color : #404040; -@text-color-secondary : #999; +@text-color : fade(#000, 65%); +@heading-color : fade(#000, 75%); +@text-color-secondary : fade(#000, 43%); +@disabled-color : fade(#000, 25%); @font-size-base : 12px; @font-size-lg : @font-size-base + 2px; @line-height-base : 1.5; @@ -28,9 +42,9 @@ @icon-url : "https://at.alicdn.com/t/font_r5u29ls31bgldi"; // LINK -@link-color : #108ee9; -@link-hover-color : tint(@link-color, 20%); -@link-active-color : shade(@link-color, 5%); +@link-color : @primary-color; +@link-hover-color : @primary-5; +@link-active-color : @primary-7; @link-hover-decoration : none; // Animation @@ -75,7 +89,7 @@ @btn-primary-color : #fff; @btn-primary-bg : @primary-color; -@btn-group-border : shade(@primary-color, 5%); +@btn-group-border : @primary-7; @btn-default-color : @text-color; @btn-default-bg : @background-color-base; @@ -85,7 +99,7 @@ @btn-ghost-bg : transparent; @btn-ghost-border : @border-color-base; -@btn-disable-color : #ccc; +@btn-disable-color : @disabled-color; @btn-disable-bg : @background-color-base; @btn-disable-border : @border-color-base; diff --git a/components/switch/style/index.less b/components/switch/style/index.less index f0dd407c40..1bc8059e4d 100644 --- a/components/switch/style/index.less +++ b/components/switch/style/index.less @@ -14,7 +14,7 @@ vertical-align: middle; border-radius: 20px; border: 1px solid #ccc; - background-color: #ccc; + background-color: @disabled-color; cursor: pointer; transition: all @switch-duration; user-select: none; @@ -122,7 +122,7 @@ } .@{switch-prefix-cls}-inner { - color: #ccc; + color: @disabled-color; } } } diff --git a/components/table/style/index.less b/components/table/style/index.less index 44fcd657f6..9e78834906 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -60,7 +60,7 @@ transition: all .3s ease; &.@{table-prefix-cls}-row-hover, &:hover { - background: tint(@primary-color, 90%); + background: @primary-1; } } @@ -369,7 +369,7 @@ .@{ant-prefix}-dropdown-menu-submenu-title:after { color: @primary-color; font-weight: bold; - text-shadow: 0 0 2px tint(@primary-color, 80%); + text-shadow: 0 0 2px@primary-2; } } } diff --git a/components/tabs/style/index.less b/components/tabs/style/index.less index 9e4373d4be..6433fb10a7 100644 --- a/components/tabs/style/index.less +++ b/components/tabs/style/index.less @@ -92,7 +92,7 @@ cursor: not-allowed; &, &:hover { - color: #ccc; + color: @disabled-color; } } @@ -146,7 +146,7 @@ .@{tab-prefix-cls}-tab-disabled { pointer-events: none; cursor: default; - color: #ccc; + color: @disabled-color; } .@{tab-prefix-cls}-tab { @@ -162,11 +162,11 @@ text-decoration: none; &:hover { - color: tint(@primary-color, 20%); + color: @primary-5; } &:active { - color: shade(@primary-color, 5%); + color: @primary-7; } .@{iconfont-css-prefix} { width: 14px; diff --git a/components/tag/style/index.less b/components/tag/style/index.less index 0014a4a21d..873e61de99 100644 --- a/components/tag/style/index.less +++ b/components/tag/style/index.less @@ -88,11 +88,11 @@ color: #fff; } &:hover { - background-color: tint(@primary-color, 20%); + background-color: @primary-5; } &:active, &-checked { - background-color: shade(@primary-color, 5%); + background-color: @primary-7; } } diff --git a/components/time-picker/style/index.less b/components/time-picker/style/index.less index 28e1adecd3..67781a4c71 100644 --- a/components/time-picker/style/index.less +++ b/components/time-picker/style/index.less @@ -61,7 +61,7 @@ &-clear-btn:after { font-size: @font-size-base; - color: #ccc; + color: @disabled-color; display: inline-block; line-height: 1; width: 20px; @@ -127,7 +127,7 @@ } li:hover { - background: tint(@primary-color, 90%); + background: @primary-1; } li&-option-selected { diff --git a/components/transfer/style/index.less b/components/transfer/style/index.less index 75a56bd2a2..afbe1f3ca0 100644 --- a/components/transfer/style/index.less +++ b/components/transfer/style/index.less @@ -25,7 +25,7 @@ &-search { &-action { - color: #ccc; + color: @disabled-color; position: absolute; top: 4px; right: 4px; @@ -37,7 +37,7 @@ .@{iconfont-css-prefix} { transition: all .3s; font-size: @font-size-base; - color: #ccc; + color: @disabled-color; &:hover { color: @text-color-secondary; } @@ -98,7 +98,7 @@ &-item:not(&-item-disabled):hover { cursor: pointer; - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &-item-disabled { @@ -114,7 +114,7 @@ &-body-not-found { padding-top: 0; - color: #ccc; + color: @disabled-color; text-align: center; display: none; position: absolute; @@ -159,7 +159,7 @@ @keyframes transferHighlightIn { 0% { - background: tint(@primary-color, 80%); + background: @primary-2; } 100% { background: transparent; diff --git a/components/tree-select/style/index.less b/components/tree-select/style/index.less index f3779123e2..a743a2054b 100644 --- a/components/tree-select/style/index.less +++ b/components/tree-select/style/index.less @@ -38,10 +38,10 @@ color: @text-color; transition: all 0.3s ease; &:hover { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &.@{select-tree-prefix-cls}-node-selected { - background-color: tint(@primary-color, 80%); + background-color: @primary-2; } } span { @@ -102,7 +102,7 @@ > span, > a, > a span { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } @@ -137,7 +137,7 @@ } .@{select-prefix-cls}-not-found { cursor: not-allowed; - color: #ccc; + color: @disabled-color; padding: 7px 16px; display: block; } diff --git a/components/tree/style/index.less b/components/tree/style/index.less index f37736d864..33bd20910e 100644 --- a/components/tree/style/index.less +++ b/components/tree/style/index.less @@ -61,10 +61,10 @@ color: @text-color; transition: all 0.3s ease; &:hover { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &.@{tree-prefix-cls}-node-selected { - background-color: tint(@primary-color, 80%); + background-color: @primary-2; } } span { @@ -132,7 +132,7 @@ >span, >a, >a span { - color: #ccc; + color: @disabled-color; cursor: not-allowed; } } diff --git a/components/upload/style/index.less b/components/upload/style/index.less index d0c29847a7..6a3c8b0832 100644 --- a/components/upload/style/index.less +++ b/components/upload/style/index.less @@ -60,7 +60,7 @@ position: relative; &.@{upload-prefix-cls}-drag-hover:not(.@{upload-prefix-cls}-disabled) { - border: 2px dashed tint(@primary-color, 20%); + border: 2px dashed@primary-5; } &.@{upload-prefix-cls}-disabled { @@ -78,14 +78,14 @@ } &:not(.@{upload-prefix-cls}-disabled):hover { - border-color: tint(@primary-color, 20%); + border-color: @primary-5; } p.@{upload-prefix-cls}-drag-icon { .@{iconfont-css-prefix} { font-size: 80px; margin-top: -5px; - color: tint(@primary-color, 20%); + color: @primary-5; } height: 60px; margin-bottom: 24px; @@ -100,7 +100,7 @@ .@{iconfont-css-prefix}-plus { font-size: 30px; transition: all 0.3s ease; - color: #ccc; + color: @disabled-color; &:hover { color: @text-color-secondary; } @@ -144,7 +144,7 @@ } &:hover &-info { - background-color: tint(@primary-color, 90%); + background-color: @primary-1; } &:hover .@{iconfont-css-prefix}-cross { diff --git a/docs/spec/colors.md b/docs/spec/colors.md index e2f91761de..6e584daf4f 100644 --- a/docs/spec/colors.md +++ b/docs/spec/colors.md @@ -14,124 +14,81 @@ title: ## Ant Design Colors -Ant Design 的色板由 9 种基本色彩组成,每种基本色又衍生出九宫格色板,在此基础上还可以通过黑白叠加的方式实现色彩明暗的效果。 +Ant Design 的色板由 8 种基本色彩组成,通过一套[精心设计的色彩算法](https://github.com/ant-design/ant-design/blob/734beb84ffc3f0469fbae1566aa8450f966cb261/components/style/color/colorPalette.less),每种基本色又自动衍生出 10 种渐变色,其中第 6 种为基本色。 + +> 我们结合了色彩加白、加黑、加深,贝塞尔曲线,以及针对冷暖色的不同旋转角度,调教出一套色彩算法。使用者只需指定主色,便可导出一条完整的渐变色板。 `````__react const Palette = React.createClass({ render() { - const color = this.props.color; - return
-
- {color.colors.map(function(color) { - return (
); - })} + const { name, description, color } = this.props.color; + const colors = []; + for (let i = 1; i <= 10; i++) { + colors.push( +
5 ? '#fff' : 'unset', + fontWeight: i === 6 ? 'bold' : 'normal', + }} + > + {name}-{i} +
+ ); + } + return ( +
+
+ {name} + {description} +
+
{colors}
-
-

{color.title}

-

{color.description}

-
-
; + ); } }); const ExtendPalettes = React.createClass({ render() { const colors = [ { - 'title': 'Primary Color', - 'description': '尽管同一种颜色传达的含义会因人而异,受到文化和地域的影响。但颜色还是可以提取出一些共通的特性,例如暖色系的红、橙、黄通常用于象征活力,激情,积极;而冷色系的绿、蓝、紫通常给人感觉是安全、稳定、专业。', - 'colors': [ - "#E01515", "#FF6600", "#FAC450", - "#E4249B", "#CCCCCC", "#5FBC29", - "#582DAA", "#0097DA", "#01B3CA" - ] + name: 'red', + description: '热情、警示', }, { - 'title': 'Grey #CCCCCC', - 'description': '灰色是中性化的颜色,通常传递出来的感觉是沉稳,在配色心理学中描述 “专业化、系统化”的词条中灰色的使用占了较高的比例。建议可用于字体颜色的选择以及界面中大面积背景的底色搭配。', - 'colors': [ - "#FFFFFF", "#FCFCFC", "#ECECEC", - "#989898", "#CCCCCC", "#D9D9D9", - "#666666", "#323232", "#000000" - ] + name: 'green', + description: '成功、通过、安全', }, { - 'title': 'Red #E01515', - 'description': '红色是具有强烈情感因素的颜色,通常红色传递的心理暗示有激情、欲望、战争以及危险。考虑到红色的特性,在后台系统的设计中建议作为辅助色来突出元素特性或是强化信息,常见的有图表元素,状态,危险信号,错误提示等。', - 'colors': [ - "#F9CCD6", "#FFA5B4", "#FA727D", - "#BB0606", "#E01515", "#FF3858", - "#881414", "#4E1212", "#260404" - ] + name: 'blue', + description: '专业、科技', }, { - 'title': 'Green #60BE29', - 'description': '绿色是非常务实的颜色,它吸收了蓝色的沉稳同时具备黄色的活力。绿色蕴含着和平、生命、希望、轻松、富饶的含义。在我们的设计实例中绿色可用来传达任务完成、健康状态以及安全感等状态。', - 'colors': [ - "#E2F582", "#D0EE9C", "#A6E33C", - "#39A30E", "#60BE29", "#70D445", - "#18791B", "#1F4A12", "#102803" - ] + name: 'pink', + description: '典雅、明快、女性', }, { - 'title': 'Blue #00A0E9', - 'description': '这里的蓝色沿用的是蚂蚁金服的品牌色,深蓝色的运用可以传递出可靠和稳定的情绪,而浅蓝色系则更为友好和清新,同时还代表了科技感与想象力。在很多专业类、管理类的后台系统设计中蓝色系常常会被选择作为设计的主色来使用。', - 'colors': [ - "#CCE4F6", "#95CCF5", "#6AC2F5", - "#1D80D3", "#00A0E9", "#2DB7F5", - "#1F5AA3", "#0B366A", "#08172F" - ] + name: 'orange', + description: '醒目、温暖', }, { - 'title': 'Magenta #E9259E', - 'description': '玫红色是较为正面的色彩,含有鼓励、友好、活力的意义。但考虑到洋红色的特性,建议作为辅助色来使用。', - 'colors': [ - "#F8C5ED", "#F5A6D3", "#F387C0", - "#BC0F69", "#E9259E", "#F056AD", - "#890B4C", "#5E0B36", "#230213" - ] + name: 'purple', + description: '高雅、浪漫', }, { - 'title': 'Orange #FF6100', - 'description': '介于红色和黄色之间,传达愉悦,创造力,热情,吸引力。但橙色又不如红色那样具侵略性,同时又能够很好的引起视觉的注意力。可以作为设计的主色也可以用于辅助色。但大面积使用时需要慎重。', - 'colors': [ - "#F1DDBD", "#FBCA72", "#FDAC23", - "#CE630F", "#FF6100", "#FF8A0C", - "#8B4A04", "#523A13", "#341F0B" - ] + name: 'yellow', + description: '活力、提示', }, { - 'title': 'Purple #5E30B5', - 'description': '紫色是赤黄黄绿青蓝紫中最后一名,也是人类可见光谱中波长最短的光,有华贵、信仰、神秘等含义,同时是红与蓝的结合体,传达中性、中立等信息。在界面设计中建议作为辅助颜色使用。', - 'colors': [ - "#E8DFFA", "#B196EE", "#8867D2", - "#581CB6", "#5E30B5", "#7A43E2", - "#3F187D", "#2B1845", "#0F061B" - ] - }, - { - 'title': 'Yellow #FAC450', - 'description': '黄色传达了愉悦,活力,创造力等正面的情绪,是具正能量的色彩。在具体设计中黄色常常于表达警示性的信息。建议作为辅助色来使用。', - 'colors': [ - "#FAF4B2", "#FDF161", "#FDE023", - "#D9B416", "#FAC450", "#F7CD07", - "#B48513", "#6B4C01", "#241A06" - ] - }, - { - 'title': 'Cyan #01BAD2', - 'description': '介于蓝色和绿色之间,带有专业、冷静、从容的心理暗示。在体验专业化和结构化的设计中常常被用到,可以作为系统主色来使用。', - 'colors': [ - "#E0F7FA", "#B2EBF2", "#80DEEA", - "#00ACC2", "#01BAD2", "#26C6DA", - "#00708F", "#014B62", "#031213" - ] + name: 'cyan', + description: '清新、冷静、结构化', } ]; - return
- {colors.map((color, i) => { - return ; - })} -
; + return ( +
+ {colors.map((color, i) => )} +
+ ); } }); ReactDOM.render(, mountNode); diff --git a/site/theme/static/colors.less b/site/theme/static/colors.less index 8f58f60f2f..6e75ffc725 100644 --- a/site/theme/static/colors.less +++ b/site/theme/static/colors.less @@ -1,40 +1,59 @@ .color-palette { margin: 45px 0; - overflow: hidden; - height: 165px; } .main-color { - width: 165px; - height: 165px; - float: left; + overflow: hidden; } -.main-color div { - width: 50px; - height: 50px; +.main-color .main-color-item { + width: 80px; + height: 60px; border-radius: 4px; float: left; margin: 0 5px 5px 0; + transition: all .2s; + position: relative; + text-align: center; + padding-top: 20px; + font-family: Consolas; + font-size: 12px; + &:after { + font-size: 12px; + position: absolute; + bottom: -4px; + transform: scale(0.85); + left: 0; + width: 100%; + text-align: center; + opacity: 0; + transition: all .2s ease .1s; + } } -.color-palette .color-msg { - margin-left: 180px; -} - -.color-msg .color-msg-title { - margin: 0; - font-weight: 600; +.color-title { + margin: 0 0 16px 0; + font-weight: 500; color: #5C6B77; - line-height: 1.8; - font-size: 21px; + font-size: 22px; + text-transform: capitalize; } -.color-msg .color-msg-description { - color: #777; - font-size: 14px; - line-height: 1.8; - margin-top: 16px; +.color-description { + font-size: 16px; + margin-left: 12px; + font-weight: normal; + color: #888; +} + +.main-color:hover { + .main-color-item { + padding-top: 4px; + &:after { + opacity: 0.7; + bottom: 3px; + } + } } .color-block { @@ -68,3 +87,23 @@ .color-block.dark:after { color: #fff; } + +.make-palatte(@color, @index: 1) when (@index <= 10) { + .palatte-@{color}-@{index} { + @background: "@{color}-@{index}"; + background: @@background; + &:after { + content: "@{@{background}}"; + } + } + .make-palatte(@color, (@index + 1)); // next iteration +} + +.make-palatte(blue); +.make-palatte(purple); +.make-palatte(cyan); +.make-palatte(green); +.make-palatte(pink); +.make-palatte(red); +.make-palatte(orange); +.make-palatte(yellow); diff --git a/site/theme/static/common.less b/site/theme/static/common.less index b527744228..dffa159327 100644 --- a/site/theme/static/common.less +++ b/site/theme/static/common.less @@ -12,7 +12,7 @@ body { body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; line-height: 1.5; - color: #666; + color: @text-color; font-size: 14px; background: #FFF; transition: background 1s cubic-bezier(0.075, 0.82, 0.165, 1); @@ -86,4 +86,4 @@ div.main-container { .page-wrapper { background: #ECECEC; -} \ No newline at end of file +} diff --git a/site/theme/static/demo.less b/site/theme/static/demo.less index 3ecbb944ad..7b37d4f7cd 100644 --- a/site/theme/static/demo.less +++ b/site/theme/static/demo.less @@ -48,7 +48,7 @@ .code-box { .code-box-title a, .code-box-title a:hover { - color: #666; + color: @text-color; font-size: 14px; font-weight: 500; } diff --git a/site/theme/static/footer.less b/site/theme/static/footer.less index 134062f9b3..8056723f59 100644 --- a/site/theme/static/footer.less +++ b/site/theme/static/footer.less @@ -5,7 +5,7 @@ footer { background: #fff; position: relative; z-index: 1; - color: #666; + color: @text-color; box-shadow: 0 1000px 0 1000px #fff; } diff --git a/site/theme/static/header.less b/site/theme/static/header.less index 413fd24e49..52a8cf0a8a 100644 --- a/site/theme/static/header.less +++ b/site/theme/static/header.less @@ -16,7 +16,7 @@ border-left-color: #EBEDEE; } a { - color: #666; + color: @text-color; } } } diff --git a/site/theme/static/highlight.less b/site/theme/static/highlight.less index 4b6bd89f78..1fbf24a33d 100644 --- a/site/theme/static/highlight.less +++ b/site/theme/static/highlight.less @@ -7,7 +7,7 @@ pre code { display: block; background: white; - color: #666; + color: @text-color; line-height: 1.7; border: 1px solid #e9e9e9; padding: 10px 15px; diff --git a/site/theme/static/home.less b/site/theme/static/home.less index c0cc968d42..9e5c61cd20 100644 --- a/site/theme/static/home.less +++ b/site/theme/static/home.less @@ -135,7 +135,7 @@ .text-wrapper h2, .text-wrapper-bottom h2 { font-size: 32px; - color: #666; + color: @text-color; font-weight: normal; white-space: nowrap; } diff --git a/site/theme/static/markdown.less b/site/theme/static/markdown.less index 9f2e4d62b2..a312490df8 100644 --- a/site/theme/static/markdown.less +++ b/site/theme/static/markdown.less @@ -1,5 +1,5 @@ .markdown { - color: #666; + color: @text-color; font-size: 14px; line-height: 1.8; } @@ -14,7 +14,7 @@ } .markdown h1 { - color: #404040; + color: @heading-color; font-weight: 500; line-height: 40px; margin-bottom: 24px; @@ -33,7 +33,7 @@ .markdown h4, .markdown h5, .markdown h6 { - color: #404040; + color: @heading-color; font-family: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; margin: 1.6em 0 0.6em 0; font-weight: 500; @@ -109,7 +109,7 @@ margin: 0; padding: 0; font-size: 13px; - color: #666; + color: @text-color; overflow: auto; } diff --git a/site/theme/static/not-found.less b/site/theme/static/not-found.less index afa1b2092e..15589b0c24 100644 --- a/site/theme/static/not-found.less +++ b/site/theme/static/not-found.less @@ -29,7 +29,7 @@ } p { - color: #666; + color: @text-color; font-size: 18px; } } diff --git a/site/theme/static/preview-img.less b/site/theme/static/preview-img.less index bb98332eeb..2f1608acde 100644 --- a/site/theme/static/preview-img.less +++ b/site/theme/static/preview-img.less @@ -73,7 +73,7 @@ .preview-image-title { font-size: 12px; margin-top: 5px; - color: #666; + color: @text-color; } .preview-image-description { diff --git a/site/theme/static/resource.less b/site/theme/static/resource.less index c6d89a9e48..776f7c4ce5 100644 --- a/site/theme/static/resource.less +++ b/site/theme/static/resource.less @@ -55,7 +55,7 @@ .resource-card-title { display: block; font-size: 16px; - color: #666; + color: @text-color; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; diff --git a/site/theme/static/responsive.less b/site/theme/static/responsive.less index 1e8df8f572..a7958a73b0 100644 --- a/site/theme/static/responsive.less +++ b/site/theme/static/responsive.less @@ -101,8 +101,8 @@ button.lang { display: block; margin: 29px auto 16px; - color: #666; - border-color: #666; + color: @text-color; + border-color: @text-color; } .popover-menu { diff --git a/site/theme/static/toc.less b/site/theme/static/toc.less index 6bca055dde..4dd4711338 100644 --- a/site/theme/static/toc.less +++ b/site/theme/static/toc.less @@ -29,7 +29,7 @@ transition: all 0.3s ease; white-space: nowrap; overflow: hidden; - color: #666; + color: @text-color; } .toc a:hover { diff --git a/site/theme/template/Home/index.jsx b/site/theme/template/Home/index.jsx index 9de395649d..c39f2073b2 100644 --- a/site/theme/template/Home/index.jsx +++ b/site/theme/template/Home/index.jsx @@ -43,11 +43,11 @@ function getStyle() { border-left-color: #EBEDEE; } .home-nav-white #nav a { - color: #666; + color: @text-color; } .home-nav-white .lang:not(:hover) { - color: #666; - border-color: #666; + color: @text-color; + border-color: @text-color; } .nav-phone-icon:before { background: #eee;