From de23a24ee6e30a01da4152d8ab723e1aaf20eeeb Mon Sep 17 00:00:00 2001 From: youluna Date: Tue, 4 Feb 2020 15:11:46 +0800 Subject: [PATCH 01/53] chore(*): make icons configurable in locale --- scripts/server/loaders/theme/var-enums.json | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/scripts/server/loaders/theme/var-enums.json b/scripts/server/loaders/theme/var-enums.json index 2b372d200e..3b54b7d02a 100644 --- a/scripts/server/loaders/theme/var-enums.json +++ b/scripts/server/loaders/theme/var-enums.json @@ -74,6 +74,60 @@ "$icon-xxl": "icon-xxl", "$icon-xxxl": "icon-xxxl" }, + "icon.types": { + "$icon-content-smile": "smile", + "$icon-content-cry": "cry", + "$icon-content-success": "success", + "$icon-content-warning": "warning", + "$icon-content-prompt": "prompt", + "$icon-content-error": "error", + "$icon-content-help": "help", + "$icon-content-clock": "clock", + "$icon-content-success-filling": "success-filling", + "$icon-content-delete-filling": "delete-filling", + "$icon-content-favorites-filling": "favorites-filling", + "$icon-content-add": "add", + "$icon-content-minus": "minus", + "$icon-content-arrow-up": "arrow-up", + "$icon-content-arrow-down": "arrow-down", + "$icon-content-arrow-left": "arrow-left", + "$icon-content-arrow-right": "arrow-right", + "$icon-content-arrow-double-left": "arrow-double-left", + "$icon-content-arrow-double-right": "arrow-double-right", + "$icon-content-switch": "switch", + "$icon-content-sorting": "sorting", + "$icon-content-descending": "descending", + "$icon-content-ascending": "ascending", + "$icon-content-select": "select", + "$icon-content-semi-select": "semi-select", + "$icon-content-search": "search", + "$icon-content-close": "close", + "$icon-content-ellipsis": "ellipsis", + "$icon-content-picture": "picture", + "$icon-content-calendar": "calendar", + "$icon-content-ashbin": "ashbin", + "$icon-content-upload": "upload", + "$icon-content-download": "download", + "$icon-content-set": "set", + "$icon-content-edit": "edit", + "$icon-content-refresh": "refresh", + "$icon-content-filter": "filter", + "$icon-content-attachment": "attachment", + "$icon-content-account": "account", + "$icon-content-email": "email", + "$icon-content-atm": "atm", + "$icon-content-loading": "loading", + "$icon-content-eye": "eye", + "$icon-content-copy": "copy", + "$icon-content-toggle-left": "toggle-left", + "$icon-content-toggle-right": "toggle-right", + "$icon-content-eye-close": "eye-close", + "$icon-content-unlock": "unlock", + "$icon-content-lock": "lock", + "$icon-content-exit": "exit", + "$icon-content-chart-bar": "chart-bar", + "$icon-content-chart-pie": "chart-pie" + }, "line.width": { "$line-zero": "line-zero", "$line-1": "line-1", From fd1e0ff18ce21f5c116137b032dedf8f7c73eedc Mon Sep 17 00:00:00 2001 From: youluna Date: Tue, 4 Feb 2020 16:53:31 +0800 Subject: [PATCH 02/53] feat(Search): make icons be configurable --- src/search/Search.jsx | 48 ++++++++++++++++++++++++----------- src/search/main.scss | 5 ++++ src/search/scss/variable.scss | 5 ++++ test/search/index-spec.js | 5 ++++ types/search/index.d.ts | 3 +++ types/util.d.ts | 11 ++++++++ 6 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/search/Search.jsx b/src/search/Search.jsx index 43987eeb92..6478d419a5 100644 --- a/src/search/Search.jsx +++ b/src/search/Search.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { isValidElement } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { polyfill } from 'react-lifecycles-compat'; @@ -126,6 +126,10 @@ class Search extends React.Component { disabled: PropTypes.bool, locale: PropTypes.object, rtl: PropTypes.bool, + /** + * 可配置的icons,包括 search 等 + */ + icons: PropTypes.object, }; static defaultProps = { @@ -142,6 +146,7 @@ class Search extends React.Component { onFilterChange: func.noop, hasClear: false, disabled: false, + icons: {}, }; constructor(props) { @@ -237,6 +242,7 @@ class Search extends React.Component { visible, locale, rtl, + icons, ...others } = this.props; @@ -250,26 +256,31 @@ class Search extends React.Component { let searchIcon = null, filterSelect = null, - searchBtn = null; + searchBtn = null, + iconsSearch = icons.search; + + if (!isValidElement(icons.search) && icons.search) { + iconsSearch = {icons.search}; + } if (shape === 'simple') { const cls = classNames({ [`${prefix}search-icon`]: true, [buttonProps.className]: !!buttonProps.className, + [`${prefix}search-symbol-icon`]: !iconsSearch, }); hasIcon && - (searchIcon = ( - + (searchIcon = React.cloneElement( + iconsSearch || , + { + role: 'button', + 'aria-disabled': disabled, + 'aria-label': locale.buttonText, + ...buttonProps, + className: cls, + onClick: this.onSearch, + onKeyDown: this.onKeyDown, + } )); } else { const cls = classNames({ @@ -287,7 +298,14 @@ class Search extends React.Component { onClick={this.onSearch} onKeyDown={this.onKeyDown} > - {hasIcon ? : null} + {hasIcon + ? iconsSearch || ( + + ) + : null} {searchText ? ( {searchText} diff --git a/src/search/main.scss b/src/search/main.scss index 29eea51986..002e9bde0d 100644 --- a/src/search/main.scss +++ b/src/search/main.scss @@ -58,6 +58,11 @@ #{$search-prefix}-btn { box-shadow: none; } + + #{$search-prefix}-symbol-icon::before { + content: $search-search-icon-content; + } + &-normal { width: 600px; diff --git a/src/search/scss/variable.scss b/src/search/scss/variable.scss index 2c0b52c51f..49dd88980b 100644 --- a/src/search/scss/variable.scss +++ b/src/search/scss/variable.scss @@ -329,5 +329,10 @@ $search-simple-dark-l-icon-size: $icon-m !default; /// @namespace size/simple $search-simple-dark-m-icon-size: $icon-xs !default; +/// search icon +/// @namespace statement/normal +/// @type icon +$search-search-icon-content: $icon-content-search !default; + $color-calculate-search-normal-dark-bg: transparentize($search-normal-dark-bg-color, 1 - $search-normal-dark-bg-opacity) !default; $color-calculate-search-simple-dark-bg: transparentize($search-simple-dark-bg-color, 1 - $search-simple-dark-bg-opacity) !default; diff --git a/test/search/index-spec.js b/test/search/index-spec.js index 224fbae653..53b8b03729 100644 --- a/test/search/index-spec.js +++ b/test/search/index-spec.js @@ -65,6 +65,11 @@ describe('Search', () => { assert(wrapper.dive().find(`[aria-label="${enUS.Search.buttonText}"]`).length === 0); assert(wrapper.dive().find(`[aria-label="a11y search"]`).length === 1); }); + + it('should support icons', () => { + const wrapper = mount(sc}} aria-label="a11y search"/>); + assert(wrapper.find('.next-search-btn span').at(0).text() === 'sc'); + }); }); describe('behavior', () => { diff --git a/types/search/index.d.ts b/types/search/index.d.ts index f4954438d8..7e3775f874 100644 --- a/types/search/index.d.ts +++ b/types/search/index.d.ts @@ -203,6 +203,9 @@ export interface SearchProps extends HTMLAttributesWeak, CommonProps { * 是否显示搜索按钮 */ hasIcon?: boolean; + icons?: { + search?: React.ReactNode; + }; } export default class Search extends React.Component {} diff --git a/types/util.d.ts b/types/util.d.ts index 149c11ce4e..7b45ae111f 100644 --- a/types/util.d.ts +++ b/types/util.d.ts @@ -1,3 +1,9 @@ +import { ReactNode } from "react"; + +export interface IconsType { + [key: string]: ReactNode; +} + export default interface CommonProps { /** * 样式类名的品牌前缀 @@ -9,6 +15,11 @@ export default interface CommonProps { */ locale?: {}; + /** + * 组件上可配置的icons变量 + */ + icons?: IconsType; + /** * 是否开启 Pure Render 模式,会提高性能,但是也会带来副作用 */ From 18b7982bb6a289481ac6935e6be3d7f52d0ec680 Mon Sep 17 00:00:00 2001 From: youluna Date: Tue, 4 Feb 2020 16:55:06 +0800 Subject: [PATCH 03/53] feat(Menu): make icons be cofigurable --- src/menu/main.scss | 9 ++++++++- src/menu/scss/variable.scss | 6 ++++++ src/menu/view/menu.jsx | 5 +++++ src/menu/view/selectable-item.jsx | 32 +++++++++++++++++++------------ types/menu/index.d.ts | 3 +++ 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/menu/main.scss b/src/menu/main.scss index c8b93a208f..2604439b19 100644 --- a/src/menu/main.scss +++ b/src/menu/main.scss @@ -191,7 +191,7 @@ border-bottom: $menu-divider-width $menu-divider-style $menu-divider-color; } - & &-icon-selected.#{$css-prefix}icon { + & &-icon-selected { position: absolute; top: 0; @include icon-size($menu-icon-selected-size, -($menu-padding-horizontal + $menu-icon-selected-size) / 2); @@ -200,6 +200,9 @@ right: $menu-icon-selected-right; } } + & &-symbol-icon-selected::before { + content: $menu-select-icon-content; + } & &-icon-arrow.#{$css-prefix}icon { position: absolute; @@ -234,6 +237,10 @@ } & &-hoz-icon-arrow.#{$css-prefix}open { + // &::before { + // content: $icon-content-arrow-up; + // transition: content $motion-duration-immediately $motion-linear; + // } @include icon-size( $size: $menu-hoz-icon-size, $transform: rotate(180deg) diff --git a/src/menu/scss/variable.scss b/src/menu/scss/variable.scss index 017c73a8c5..5900f53f21 100644 --- a/src/menu/scss/variable.scss +++ b/src/menu/scss/variable.scss @@ -142,3 +142,9 @@ $menu-icon-selected-hover-color: $color-brand1-6 !default; /// color /// @namespace statement/disabled/text $menu-color-disabled: $color-text1-1 !default; + + +/// search icon +/// @namespace statement/normal +/// @type icon +$menu-select-icon-content: $icon-content-select !default; diff --git a/src/menu/view/menu.jsx b/src/menu/view/menu.jsx index 39c3332d04..2a9dc55581 100644 --- a/src/menu/view/menu.jsx +++ b/src/menu/view/menu.jsx @@ -174,6 +174,10 @@ export default class Menu extends Component { onItemKeyDown: PropTypes.func, expandAnimation: PropTypes.bool, itemClassName: PropTypes.string, + /** + * 可配置的icons,包括 selected 等 + */ + icons: PropTypes.object, }; static defaultProps = { @@ -206,6 +210,7 @@ export default class Menu extends Component { onItemKeyDown: noop, onItemClick: noop, expandAnimation: true, + icons: {}, }; constructor(props) { diff --git a/src/menu/view/selectable-item.jsx b/src/menu/view/selectable-item.jsx index 9880b9e1be..71ff334bc8 100644 --- a/src/menu/view/selectable-item.jsx +++ b/src/menu/view/selectable-item.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, isValidElement } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import Icon from '../../icon'; @@ -39,11 +39,13 @@ export default class SelectableItem extends Component { needIndent: PropTypes.bool, hasSelectedIcon: PropTypes.bool, isSelectIconRight: PropTypes.bool, + icons: PropTypes.object, }; static defaultProps = { disabled: false, needIndent: true, + icons: {}, }; constructor(props) { @@ -95,10 +97,18 @@ export default class SelectableItem extends Component { prefix, hasSelectedIcon: rootSelectedIcon, isSelectIconRight: rootSelectIconRight, + icons, } = root.props; + let iconsSelect = icons.select; + + if (!isValidElement(icons.select) && icons.select) { + iconsSelect = {icons.select}; + } + const cls = cx({ [`${prefix}menu-icon-selected`]: true, + [`${prefix}menu-symbol-icon-selected`]: !iconsSelect, [`${prefix}menu-icon-right`]: ('isSelectIconRight' in this.props ? isSelectIconRight @@ -107,17 +117,15 @@ export default class SelectableItem extends Component { return ('hasSelectedIcon' in this.props ? hasSelectedIcon - : rootSelectedIcon) && selected ? ( - 0 - ? { left: `${inlineIndent}px` } - : null - } - className={cls} - type="select" - /> - ) : null; + : rootSelectedIcon) && selected + ? React.cloneElement(iconsSelect || , { + style: + needIndent && inlineIndent > 0 + ? { left: `${inlineIndent}px` } + : null, + className: cls, + }) + : null; } render() { diff --git a/types/menu/index.d.ts b/types/menu/index.d.ts index 44bca97233..c99f38cb88 100644 --- a/types/menu/index.d.ts +++ b/types/menu/index.d.ts @@ -298,6 +298,9 @@ export interface MenuProps extends HTMLAttributesWeak, CommonProps { * 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合`` 自定义高度 */ embeddable?: boolean; + icons?: { + select?: React.ReactNode; + }; } export default class Menu extends React.Component { From ca60e98bb57155ba5a92312d575398754c7b9f79 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 6 Feb 2020 15:12:02 +0800 Subject: [PATCH 04/53] chore(Menu): make arrow configurable --- docs/menu/theme/index.jsx | 1 + scripts/server/loaders/theme/var-enums.json | 3 +- src/core/style/_icon.scss | 2 + src/menu/main.scss | 52 ++++++++++++++++----- src/menu/scss/variable.scss | 17 ++++++- src/menu/view/menu.jsx | 2 +- src/menu/view/popup-item.jsx | 2 +- 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/docs/menu/theme/index.jsx b/docs/menu/theme/index.jsx index 435f2ea8ba..88b4012026 100644 --- a/docs/menu/theme/index.jsx +++ b/docs/menu/theme/index.jsx @@ -233,6 +233,7 @@ class FunctionDemoNest extends FunctionDemo { {this.renderItem('2-2', { disabled: true })} {this.renderItem('2-3')} {this.renderItem('2-4')} + {`${i18n.option}1`} diff --git a/scripts/server/loaders/theme/var-enums.json b/scripts/server/loaders/theme/var-enums.json index 3b54b7d02a..2c24351cd4 100644 --- a/scripts/server/loaders/theme/var-enums.json +++ b/scripts/server/loaders/theme/var-enums.json @@ -126,7 +126,8 @@ "$icon-content-lock": "lock", "$icon-content-exit": "exit", "$icon-content-chart-bar": "chart-bar", - "$icon-content-chart-pie": "chart-pie" + "$icon-content-chart-pie": "chart-pie", + "$icon-reset": "" }, "line.width": { "$line-zero": "line-zero", diff --git a/src/core/style/_icon.scss b/src/core/style/_icon.scss index 3781fec2e6..eeb3995a1e 100644 --- a/src/core/style/_icon.scss +++ b/src/core/style/_icon.scss @@ -371,3 +371,5 @@ $icon-content-chart-bar: "\e612" !default; /// @export type /// @unconfigurable $icon-content-chart-pie: "\e613" !default; + +$icon-reset: "null" !default; diff --git a/src/menu/main.scss b/src/menu/main.scss index 2604439b19..7dadda22eb 100644 --- a/src/menu/main.scss +++ b/src/menu/main.scss @@ -213,11 +213,25 @@ transition: all $motion-duration-immediately $motion-linear; } + & &-icon-arrow-down::before { + content: $menu-fold-icon-content; + } + & &-icon-arrow-down.#{$css-prefix}open { - @include icon-size( - $size: $menu-icon-size, - $transform: rotate(180deg) - ); + @if $menu-unfold-icon-content != $icon-reset { + &::before { + content: $menu-unfold-icon-content; + } + } @else { + @include icon-size( + $size: $menu-icon-size, + $transform: rotate(180deg) + ); + } + } + + & &-symbol-popupfold::before { + content: $menu-popupfold-icon-content; } & &-icon-arrow-right.#{$css-prefix}open { @@ -234,17 +248,31 @@ @include icon-size($menu-hoz-icon-size); color: $menu-arrow-color; transition: all $motion-duration-immediately $motion-linear; + + @if $menu-fold-icon-content != $icon-reset { + &::before { + content: $menu-fold-icon-content; + } + } } + // --------- this is for config platform + &-unfold-icon::before { + content: $menu-unfold-icon-content; + } + // --------- this is for config platform + & &-hoz-icon-arrow.#{$css-prefix}open { - // &::before { - // content: $icon-content-arrow-up; - // transition: content $motion-duration-immediately $motion-linear; - // } - @include icon-size( - $size: $menu-hoz-icon-size, - $transform: rotate(180deg) - ); + @if $menu-unfold-icon-content != $icon-reset { + &::before { + content: $menu-unfold-icon-content; + } + } @else { + @include icon-size( + $size: $menu-hoz-icon-size, + $transform: rotate(180deg) + ); + } } &.#{$css-prefix}context { diff --git a/src/menu/scss/variable.scss b/src/menu/scss/variable.scss index 5900f53f21..5d55bb85ce 100644 --- a/src/menu/scss/variable.scss +++ b/src/menu/scss/variable.scss @@ -144,7 +144,22 @@ $menu-icon-selected-hover-color: $color-brand1-6 !default; $menu-color-disabled: $color-text1-1 !default; -/// search icon +/// select icon /// @namespace statement/normal /// @type icon $menu-select-icon-content: $icon-content-select !default; + +/// fold icon +/// @namespace statement/normal +/// @type icon +$menu-fold-icon-content: $icon-content-arrow-down !default; + +/// unfold icon +/// @namespace statement/normal +/// @type icon +$menu-unfold-icon-content: $icon-reset !default; + +/// popup fold icon +/// @namespace statement/normal +/// @type icon +$menu-popupfold-icon-content: $icon-content-arrow-right !default; diff --git a/src/menu/view/menu.jsx b/src/menu/view/menu.jsx index 2a9dc55581..f38845f7a1 100644 --- a/src/menu/view/menu.jsx +++ b/src/menu/view/menu.jsx @@ -175,7 +175,7 @@ export default class Menu extends Component { expandAnimation: PropTypes.bool, itemClassName: PropTypes.string, /** - * 可配置的icons,包括 selected 等 + * 可配置的icons,包括 select 等 */ icons: PropTypes.object, }; diff --git a/src/menu/view/popup-item.jsx b/src/menu/view/popup-item.jsx index 9298140356..0c3fcc8e21 100644 --- a/src/menu/view/popup-item.jsx +++ b/src/menu/view/popup-item.jsx @@ -287,7 +287,7 @@ export default class PopupItem extends Component { arrowProps = { type: 'arrow-right', - className: `${prefix}menu-icon-arrow`, + className: `${prefix}menu-icon-arrow ${prefix}menu-symbol-popupfold`, }; } From bd7d2f0cde51e0b8aa1e13b90987e3648b6d8128 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 6 Feb 2020 15:34:01 +0800 Subject: [PATCH 05/53] feat(Collapse): make arrow configurable --- docs/collapse/theme/index.jsx | 5 +++++ docs/menu/theme/index.jsx | 6 +++++- src/collapse/main.scss | 20 ++++++++++++++++++-- src/collapse/panel.jsx | 2 +- src/collapse/rtl.scss | 2 +- src/collapse/scss/variable.scss | 10 ++++++++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/docs/collapse/theme/index.jsx b/docs/collapse/theme/index.jsx index 3039e014df..e83cc97318 100644 --- a/docs/collapse/theme/index.jsx +++ b/docs/collapse/theme/index.jsx @@ -35,6 +35,11 @@ function render(i18n) { {content} + {/* --------- this is for config platform ----------- */} +
+
+
+ {/* --------- this is for config platform ----------- */} {content} diff --git a/docs/menu/theme/index.jsx b/docs/menu/theme/index.jsx index 88b4012026..2e43e3ebd5 100644 --- a/docs/menu/theme/index.jsx +++ b/docs/menu/theme/index.jsx @@ -233,7 +233,11 @@ class FunctionDemoNest extends FunctionDemo { {this.renderItem('2-2', { disabled: true })} {this.renderItem('2-3')} {this.renderItem('2-4')} - + {/* --------- this is for config platform ----------- */} +
+
+
+ {/* --------- this is for config platform ----------- */} {`${i18n.option}1`} diff --git a/src/collapse/main.scss b/src/collapse/main.scss index 6061965a91..f6b315c4a5 100644 --- a/src/collapse/main.scss +++ b/src/collapse/main.scss @@ -28,7 +28,7 @@ left: $collapse-icon-margin-l; margin-top: -2px; - @include icon-size($collapse-icon-size, 0, 0, rotate($collapse-icon-rotation-collapsed)); + @include icon-size($collapse-icon-size, 0, 0); } &-panel-title { @@ -72,9 +72,25 @@ } } + // --------- this is for config platform + #{$collapse-prefix}-unfold-icon::before { + content: $collapse-unfold-icon-content; + } + // --------- this is for config platform + #{$collapse-prefix}-panel-icon { + &::before { + content: $collapse-fold-icon-content; + } + &#{$collapse-prefix}-panel-icon-expanded { - @include icon-size($collapse-icon-size, 0, 0, rotate($collapse-icon-rotation-expanded)); + @if $collapse-unfold-icon-content != $icon-reset { + &::before { + content: $collapse-unfold-icon-content; + } + } @else { + @include icon-size($collapse-icon-size, 0, 0, rotate(90deg)); + } } } diff --git a/src/collapse/panel.jsx b/src/collapse/panel.jsx index 8c8f18819b..c21b40e212 100644 --- a/src/collapse/panel.jsx +++ b/src/collapse/panel.jsx @@ -93,7 +93,7 @@ class Panel extends React.Component { role="button" >
, mountNode); diff --git a/index.js b/index.js index 63463521f7..88992cd435 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ var next = require('./lib/index.js'); -next.version = '1.19.11'; +next.version = '1.19.12'; module.exports = next; diff --git a/package.json b/package.json index 639237c8ad..ec4cf6d27c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@alifd/next", - "version": "1.19.11", + "version": "1.19.12", "description": "A configurable component library for web built on React.", "keywords": [ "fusion", From 3e039f3892665ec67d466d1945f0ee780325cd92 Mon Sep 17 00:00:00 2001 From: youluna Date: Wed, 12 Feb 2020 14:22:03 +0800 Subject: [PATCH 10/53] docs(Table): remove useless api --- docs/table/demo/expanded-complex.md | 4 ---- docs/table/demo/expanded.md | 1 - docs/table/index.en-us.md | 1 - docs/table/index.md | 1 - src/table/base.jsx | 6 ------ src/table/expanded.jsx | 6 ------ 6 files changed, 19 deletions(-) diff --git a/docs/table/demo/expanded-complex.md b/docs/table/demo/expanded-complex.md index a20852fbe3..b86a115a1b 100644 --- a/docs/table/demo/expanded-complex.md +++ b/docs/table/demo/expanded-complex.md @@ -130,9 +130,6 @@ class App extends React.Component { console.log('rowProps', record, index); return {className: `next-myclass-${index}`}; } - onExpandedRowClick(record, index) { - console.log('onExpandedRowClick', record, index); - } render() { const renderTitle = (value, index, record) => { return
{value}index:{index} +++++
; @@ -153,7 +150,6 @@ class App extends React.Component { hasExpandedRowCtrl={this.state.hasExpandedRowCtrl} onRowOpen={this.onRowOpen.bind(this)} rowProps={this.rowProps.bind(this)} - onExpandedRowClick={this.onExpandedRowClick.bind(this)} > diff --git a/docs/table/demo/expanded.md b/docs/table/demo/expanded.md index 9410ea1b5e..cb468aaa90 100644 --- a/docs/table/demo/expanded.md +++ b/docs/table/demo/expanded.md @@ -69,7 +69,6 @@ class App extends React.Component { onSort={this.onSort.bind(this)} expandedRowRender={(record) => record.title} onRowClick={() => console.log('rowClick')} - onExpandedRowClick={() => console.log('expandedRowClick')} expandedRowIndent={this.state.expandedRowIndent} > diff --git a/docs/table/index.en-us.md b/docs/table/index.en-us.md index 53bb03682a..f9cbd38f9f 100644 --- a/docs/table/index.en-us.md +++ b/docs/table/index.en-us.md @@ -109,7 +109,6 @@ ReactDOM.render( | hasExpandedRowCtrl | whether to show the + button that clicks to expand additional row | Boolean | - | | getExpandedColProps | get properties of expanded row

**signatures**:
Function() => void | Function | - | | onRowOpen | callback triggered when expand row

**signatures**:
Function(openRowKeys: Array, currentRowKey: String, expanded: Boolean, currentRecord: Object) => void
**params**:
_openRowKeys_: {Array} key of expanded row
_currentRowKey_: {String} key of current clicked row
_expanded_: {Boolean} whether is expanded
_currentRecord_: {Object} the data corresponding to the current clicked row | Function | - | -| onExpandedRowClick | callback triggered when click the expanded row

**signatures**:
Function(record: Object, index: Number, e: Event) => void
**params**:
_record_: {Object} the data corresponding to the row
_index_: {Number} the index corresponding to the row
_e_: {Event} event object | Function | - | | fixedHeader | whether the table header is fixed, this property is used with maxBodyHeight. When the height of the content area exceeds maxBodyHeight, a scroll bar appears in the content area. | Boolean | - | | maxBodyHeight | the height of the largest content area, when `fixedHeader` is `true`, scroll bars will appear above this height | Number/String | - | | rowSelection | whether to enable selection mode

**properties**:
_getProps_: {Function} `Function(record, index)=>Object` get default attributes of selection
_onChange_: {Function} `Function(selectedRowKeys:Array, records:Array)` callback triggered when selection change, **Note:** where records only contains the data of the current dataSource, it is likely to be less than the length of the selectedRowKeys.
_onSelect_: {Function} `Function(selected:Boolean, record:Object, records:Array)` callback triggered when user select
_onSelectAll_: {Function} `Function(selected:Boolean, records:Array)` callback triggered when user select all
_selectedRowKeys_: {Array} if this property is set, the rowSelection is controlled, and the received value is the value of the primaryKey of the row's data.
_mode_: {String} the mode of selection, the optional value is `single`, `multiple`, the default is `multiple`
_columnProps_: {Function} `Function()=>Object` props of checkbox columns which inherit from `Table.Column`
_titleProps_: {Function} `Function()=>Object` props of checkbox columns header, works only in `multiple` mode
_titleAddons_: {Function} `Function()=>Node` element added to checkbox columns header, works in both `single` and `multiple` mode | Object | - | diff --git a/docs/table/index.md b/docs/table/index.md index 9d588100a1..ee3c49258f 100644 --- a/docs/table/index.md +++ b/docs/table/index.md @@ -121,7 +121,6 @@ ReactDOM.render( | hasExpandedRowCtrl | 是否显示点击展开额外渲染行的+号按钮 | Boolean | - | | getExpandedColProps | 设置额外渲染行的属性

**签名**:
Function() => void | Function | - | | onRowOpen | 在额外渲染行或者Tree展开或者收起的时候触发的事件

**签名**:
Function(openRowKeys: Array, currentRowKey: String, expanded: Boolean, currentRecord: Object) => void
**参数**:
_openRowKeys_: {Array} 展开的渲染行的key
_currentRowKey_: {String} 当前点击的渲染行的key
_expanded_: {Boolean} 当前点击是展开还是收起
_currentRecord_: {Object} 当前点击额外渲染行的记录 | Function | - | -| onExpandedRowClick | 点击额外渲染行触发的事件

**签名**:
Function(record: Object, index: Number, e: Event) => void
**参数**:
_record_: {Object} 该行所对应的数据
_index_: {Number} 该行所对应的序列
_e_: {Event} DOM事件对象 | Function | - | | fixedHeader | 表头是否固定,该属性配合maxBodyHeight使用,当内容区域的高度超过maxBodyHeight的时候,在内容区域会出现滚动条 | Boolean | - | | maxBodyHeight | 最大内容区域的高度,在`fixedHeader`为`true`的时候,超过这个高度会出现滚动条 | Number/String | - | | rowSelection | 是否启用选择模式

**属性**:
_getProps_: {Function} `Function(record, index)=>Object` 获取selection的默认属性
_onChange_: {Function} `Function(selectedRowKeys:Array, records:Array)` 选择改变的时候触发的事件,**注意:** 其中records只会包含当前dataSource的数据,很可能会小于selectedRowKeys的长度。
_onSelect_: {Function} `Function(selected:Boolean, record:Object, records:Array)` 用户手动选择/取消选择某行的回调
_onSelectAll_: {Function} `Function(selected:Boolean, records:Array)` 用户手动选择/取消选择所有行的回调
_selectedRowKeys_: {Array} 设置了此属性,将rowSelection变为受控状态,接收值为该行数据的primaryKey的值
_mode_: {String} 选择selection的模式, 可选值为`single`, `multiple`,默认为`multiple`
_columnProps_: {Function} `Function()=>Object` 选择列 的props,例如锁列、对齐等,可使用`Table.Column` 的所有参数
_titleProps_: {Function} `Function()=>Object` 选择列 表头的props,仅在 `multiple` 模式下生效
_titleAddons_: {Function} `Function()=>Node` 选择列 表头添加的元素,在`single` `multiple` 下都生效 | Object | - | diff --git a/src/table/base.jsx b/src/table/base.jsx index 006a79f3c2..a2e66e985e 100644 --- a/src/table/base.jsx +++ b/src/table/base.jsx @@ -213,12 +213,6 @@ export default class Table extends React.Component { * @param {Object} currentRecord 当前点击额外渲染行的记录 */ onRowOpen: PropTypes.func, - /** - * 点击额外渲染行触发的事件 - * @param {Object} record 该行所对应的数据 - * @param {Number} index 该行所对应的序列 - * @param {Event} e DOM事件对象 - */ onExpandedRowClick: PropTypes.func, /** * 表头是否固定,该属性配合maxBodyHeight使用,当内容区域的高度超过maxBodyHeight的时候,在内容区域会出现滚动条 diff --git a/src/table/expanded.jsx b/src/table/expanded.jsx index cbf594a7af..6a056e1f46 100644 --- a/src/table/expanded.jsx +++ b/src/table/expanded.jsx @@ -45,12 +45,6 @@ export default function expanded(BaseComponent) { * @param {Object} currentRecord 当前点击额外渲染行的记录 */ onRowOpen: PropTypes.func, - /** - * 点击额外渲染行触发的事件 - * @param {Object} record 该行所对应的数据 - * @param {Number} index 该行所对应的序列 - * @param {Event} e DOM事件对象 - */ onExpandedRowClick: PropTypes.func, locale: PropTypes.object, ...BaseComponent.propTypes, From c2767ec370c588952ae162e3d6786fa4c29de9e6 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 13 Feb 2020 14:54:30 +0800 Subject: [PATCH 11/53] fix(Collapse): collapsed panel should be overflow hidden, close #1569 --- src/collapse/main.scss | 6 +++++ src/collapse/panel.jsx | 1 + test/collapse/index-spec.js | 49 +++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/collapse/main.scss b/src/collapse/main.scss index 6061965a91..9c303cf877 100644 --- a/src/collapse/main.scss +++ b/src/collapse/main.scss @@ -72,6 +72,12 @@ } } + &-panel-hidden { + > #{$collapse-prefix}-panel-content { + overflow: hidden; + } + } + #{$collapse-prefix}-panel-icon { &#{$collapse-prefix}-panel-icon-expanded { @include icon-size($collapse-icon-size, 0, 0, rotate($collapse-icon-rotation-expanded)); diff --git a/src/collapse/panel.jsx b/src/collapse/panel.jsx index 8c8f18819b..52b927aa54 100644 --- a/src/collapse/panel.jsx +++ b/src/collapse/panel.jsx @@ -66,6 +66,7 @@ class Panel extends React.Component { const cls = classNames({ [`${prefix}collapse-panel`]: true, + [`${prefix}collapse-panel-hidden`]: !isExpanded, [`${prefix}collapse-panel-expanded`]: isExpanded, [`${prefix}collapse-panel-disabled`]: disabled, [className]: className, diff --git a/test/collapse/index-spec.js b/test/collapse/index-spec.js index 13a30b56b3..08c58a7612 100644 --- a/test/collapse/index-spec.js +++ b/test/collapse/index-spec.js @@ -26,8 +26,19 @@ describe('Collapse', () => { assert(wrapper.find(Panel).length === 2); }); + it('hidden panel should be hidden', () => { + const wrapper = mount( + + Pannel Content + Pannel Content + + ); + const el = wrapper.find('.next-collapse-panel-hidden'); + assert(el.length === 2); + }); + it('Should render from dataSource', () => { - let list = [ + const list = [ { title: 'Well, hello there', content: @@ -65,7 +76,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -74,7 +85,7 @@ describe('Collapse', () => { .at(2); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should expand panel with number key', () => { const wrapper = mount( @@ -82,7 +93,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -91,7 +102,7 @@ describe('Collapse', () => { .at(2); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should close default expanded string keys', () => { const wrapper = mount( @@ -99,7 +110,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -109,7 +120,7 @@ describe('Collapse', () => { .simulate('click'); assert(wrapper.find('.next-collapse-panel-expanded').length === 0); }); - + it('should close default expanded number keys', () => { const wrapper = mount( @@ -117,7 +128,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -127,7 +138,7 @@ describe('Collapse', () => { .simulate('click'); assert(wrapper.find('.next-collapse-panel-expanded').length === 0); }); - + it('should open default expanded datasource using number keys', () => { const list = [ { @@ -149,7 +160,7 @@ describe('Collapse', () => { .at(1); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should close default expanded datasource using number keys on click', () => { const list = [ { @@ -182,7 +193,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -191,7 +202,7 @@ describe('Collapse', () => { .at(2); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should expand panel with number key', () => { const wrapper = mount( @@ -199,7 +210,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -208,7 +219,7 @@ describe('Collapse', () => { .at(2); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should close default expanded string keys', () => { const wrapper = mount( @@ -216,7 +227,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -226,7 +237,7 @@ describe('Collapse', () => { .simulate('click'); assert(wrapper.find('.next-collapse-panel-expanded').length === 0); }); - + it('should close default expanded number keys', () => { const wrapper = mount( @@ -234,7 +245,7 @@ describe('Collapse', () => { Pannel Content Pannel Content Pannel Content - +
others
); @@ -244,7 +255,7 @@ describe('Collapse', () => { .simulate('click'); assert(wrapper.find('.next-collapse-panel-expanded').length === 0); }); - + it('should open default expanded datasource using number keys', () => { const list = [ { @@ -266,7 +277,7 @@ describe('Collapse', () => { .at(1); assert(el.hasClass('next-collapse-panel-expanded')); }); - + it('should close default expanded datasource using number keys on click', () => { const list = [ { From 8a89c0a5bbc8b32c76068c173dc3b9af5452ce21 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 13 Feb 2020 17:05:28 +0800 Subject: [PATCH 12/53] feat(Table): add htmlTitle for header --- docs/table/demo/basic.md | 2 +- src/table/base/cell.jsx | 3 ++- src/table/column.jsx | 4 ++++ types/table/index.d.ts | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/table/demo/basic.md b/docs/table/demo/basic.md index e5dfe4a00c..91de8f5d4f 100644 --- a/docs/table/demo/basic.md +++ b/docs/table/demo/basic.md @@ -32,7 +32,7 @@ const render = (value, index, record) => { return Remove({record.id}); }; ReactDOM.render( - + diff --git a/src/table/base/cell.jsx b/src/table/base/cell.jsx index 21cc972015..e3da1854c9 100644 --- a/src/table/base/cell.jsx +++ b/src/table/base/cell.jsx @@ -90,6 +90,7 @@ export default class Cell extends React.Component { rtl, isIconLeft, type, + htmlTitle, ...others } = this.props; const tagStyle = { ...style }; @@ -121,7 +122,7 @@ export default class Cell extends React.Component {
diff --git a/src/table/column.jsx b/src/table/column.jsx index 10aab456df..75add1aff8 100644 --- a/src/table/column.jsx +++ b/src/table/column.jsx @@ -29,6 +29,10 @@ export default class Column extends React.Component { PropTypes.node, PropTypes.func, ]), + /** + * 写到 header 单元格上的title属性 + */ + htmlTitle: PropTypes.string, /** * 是否支持排序 */ diff --git a/types/table/index.d.ts b/types/table/index.d.ts index 354887c289..c6263ca17d 100644 --- a/types/table/index.d.ts +++ b/types/table/index.d.ts @@ -26,6 +26,7 @@ export interface ColumnProps extends HTMLAttributesWeak, CommonProps { */ title?: React.ReactElement | React.ReactNode | (() => void); + htmlTitle?: string; /** * 是否支持排序 */ From b6c4b6ad4d56f38a8cefb08f4501cfbd5455288f Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 13 Feb 2020 17:12:06 +0800 Subject: [PATCH 13/53] docs(Table): update docs --- docs/table/index.en-us.md | 1 + docs/table/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/table/index.en-us.md b/docs/table/index.en-us.md index 53bb03682a..297f373748 100644 --- a/docs/table/index.en-us.md +++ b/docs/table/index.en-us.md @@ -129,6 +129,7 @@ ReactDOM.render( | dataIndex | specify the column corresponding field, support the fast value of `a.b` format | String | - | | cell | cell rendering logic
Function(value, index, record) => Element | ReactElement/ReactNode/Function | (value) => value | | title | content of table header | ReactElement/ReactNode/Function | - | +| htmlTitle | the props of title, which will be writen on header cells' dom | String | - | | sortable | whether to support sorting | Boolean | - | | width | width of column,width needs to be set in lock style | Number/String | - | | align | alignment of cell

**options**:
'left', 'center', 'right' | Enum | - | diff --git a/docs/table/index.md b/docs/table/index.md index 9d588100a1..028b21c3c9 100644 --- a/docs/table/index.md +++ b/docs/table/index.md @@ -142,6 +142,7 @@ ReactDOM.render( | dataIndex | 指定列对应的字段,支持`a.b`形式的快速取值 | String | - | | cell | 行渲染的逻辑
value, rowIndex, record, context四个属性只可读不可被更改
Function(value, index, record) => Element | ReactElement/ReactNode/Function | value => value | | title | 表头显示的内容 | ReactElement/ReactNode/Function | - | +| htmlTitle | 写到 header 单元格上的title属性 | String | - | | sortable | 是否支持排序 | Boolean | - | | width | 列宽,注意在锁列的情况下一定需要配置宽度 | Number/String | - | | align | 单元格的对齐方式

**可选值**:
'left', 'center', 'right' | Enum | - | From e6318c34c5179a1c00e836056270ba61cdc09c02 Mon Sep 17 00:00:00 2001 From: aboutblank Date: Fri, 14 Feb 2020 18:33:40 +0800 Subject: [PATCH 14/53] feat(Shell): add align for Shell.Navigaiton (#1576) feat(Shell): add align for Shell.Navigaiton --- docs/menu/demo/hoz.md | 2 +- docs/menu/demo/render-more.md | 2 +- docs/shell/index.en-us.md | 6 +++++- docs/shell/index.md | 1 + src/menu/main.scss | 1 - src/menu/view/menu.jsx | 2 +- src/shell/base.jsx | 6 ++++++ src/shell/main.scss | 11 +++++++++++ test/menu/index-spec.js | 4 ++-- types/shell/index.d.ts | 5 +++++ 10 files changed, 33 insertions(+), 7 deletions(-) diff --git a/docs/menu/demo/hoz.md b/docs/menu/demo/hoz.md index 8406e00e7b..719fba54e4 100644 --- a/docs/menu/demo/hoz.md +++ b/docs/menu/demo/hoz.md @@ -49,6 +49,6 @@ ReactDOM.render( width: 160px; } .my-hoz-menu .next-menu-item.next-menu-more { - width: 40px; + width: 60px; } ```` diff --git a/docs/menu/demo/render-more.md b/docs/menu/demo/render-more.md index dd2bc852eb..1eb3da122b 100644 --- a/docs/menu/demo/render-more.md +++ b/docs/menu/demo/render-more.md @@ -109,7 +109,7 @@ ReactDOM.render( }; }); - return ( + return ( ); }}> diff --git a/docs/shell/index.en-us.md b/docs/shell/index.en-us.md index 59dba278a7..ddd2680216 100644 --- a/docs/shell/index.en-us.md +++ b/docs/shell/index.en-us.md @@ -54,20 +54,24 @@ It will tell his children whether it's collapse or not by `isCollapse` via Conte | -------------------- | ------------ | ----------------- | ------------------ | | collapse | collapse or not | Boolean | false | | direction | header or asider

**option**:
'hoz', 'ver' | Enum | hoz | +| align | Arrangement of Navigation when direction is hoz

**option**:
'left', 'right', 'center' | Enum | right | +| onCollapseChange | this will be triggered when collapse changed by inner icon | Function | () => {} | ### Shell.LocalNavigation | Param | Description | Type | Default Value | | -------------------- | ------------ | ----------------- | ------------------ | | collapse | collapse or not | Boolean | false | +| onCollapseChange | this will be triggered when collapse changed by inner icon | Function | () => {} | ### Shell.ToolDock | Param | Description | Type | Default Value | | -------------------- | ------------ | ----------------- | ------------------ | | collapse | collapse or not | Boolean | false | +| onCollapseChange | this will be triggered when collapse changed by inner icon | Function | () => {} | ### Shell.Ancillary | Param | Description | Type | Default Value | | -------------------- | ------------ | ----------------- | ------------------ | | collapse | collapse or not | Boolean | false | - +| onCollapseChange | this will be triggered when collapse changed by inner icon | Function | () => {} | diff --git a/docs/shell/index.md b/docs/shell/index.md index ef98ceff21..101a4a4072 100644 --- a/docs/shell/index.md +++ b/docs/shell/index.md @@ -55,6 +55,7 @@ Shell 是整个应用的基础结构框架。它体现应用的结构形式和 | -------------------- | ------------ | ----------------- | ------------------ | | direction | 方向

**可选值**:
'hoz', 'ver' | Enum | hoz | | collapse | 是否折叠(折叠成只有icon状态) | Boolean | false | +| align | 横向模式下,导航排布的位置

**可选值**:
'left', 'right', 'center' | Enum | right | | onCollapseChange | 默认按钮触发的展开收起状态 | Function | () => {} | diff --git a/src/menu/main.scss b/src/menu/main.scss index c8b93a208f..84f4911f21 100644 --- a/src/menu/main.scss +++ b/src/menu/main.scss @@ -158,7 +158,6 @@ white-space: nowrap; #{$menu-prefix}-more { - padding: 0; text-align: center; } } diff --git a/src/menu/view/menu.jsx b/src/menu/view/menu.jsx index 39c3332d04..9418d9f073 100644 --- a/src/menu/view/menu.jsx +++ b/src/menu/view/menu.jsx @@ -421,7 +421,7 @@ export default class Menu extends Component { // keep placehold to get width if (isPlaceholder) { style.visibility = 'hidden'; - style.display = 'unset'; + style.display = 'inline-block'; // indicators which not in use, just display: none } else if (items && items.length === 0) { style.display = 'none'; diff --git a/src/shell/base.jsx b/src/shell/base.jsx index 1c58bea6ce..fb4fb7bb9a 100644 --- a/src/shell/base.jsx +++ b/src/shell/base.jsx @@ -19,6 +19,7 @@ export default function Base(props) { trigger: PropTypes.node, triggerProps: PropTypes.object, direction: PropTypes.oneOf(['hoz', 'ver']), + align: PropTypes.oneOf(['left', 'right', 'center']), /** * 弹层显示或隐藏时触发的回调函数 * @param {Boolean} collapse 弹层是否显示 @@ -56,6 +57,7 @@ export default function Base(props) { triggerProps, onCollapseChange, component, + align, ...others } = this.props; @@ -65,6 +67,10 @@ export default function Base(props) { [`${prefix}shell-${componentName.toLowerCase()}`]: true, [`${prefix}shell-collapse`]: !!collapse, [`${prefix}shell-mini`]: miniable, + [`${prefix}shell-nav-${align}`]: + componentName === 'Navigation' && + direction === 'hoz' && + align, [className]: !!className, }); diff --git a/src/shell/main.scss b/src/shell/main.scss index 085803610e..941c42b4de 100644 --- a/src/shell/main.scss +++ b/src/shell/main.scss @@ -538,6 +538,17 @@ } } + &-header #{$shell-prefix}-navigation { + &#{$shell-prefix}-nav-left { + justify-content: flex-start; + } + &#{$shell-prefix}-nav-right { + justify-content: flex-end; + } + &#{$shell-prefix}-nav-center { + justify-content: center; + } + } &#{$shell-prefix}-phone { diff --git a/test/menu/index-spec.js b/test/menu/index-spec.js index 8f171fa969..4a5428d617 100644 --- a/test/menu/index-spec.js +++ b/test/menu/index-spec.js @@ -913,7 +913,7 @@ describe('Menu', () => { mode="popup" hozInLine > - 0 + 0 1 2 @@ -976,7 +976,7 @@ describe('Menu', () => { const overlay = document.querySelector('.next-overlay-wrapper'); assert(overlay); - assert(overlay.querySelectorAll('li').length === 3); + assert(overlay.querySelectorAll('li').length === 4); ReactDOM.unmountComponentAtNode(div); document.body.removeChild(div); diff --git a/types/shell/index.d.ts b/types/shell/index.d.ts index 1ec01482ea..235398bdce 100644 --- a/types/shell/index.d.ts +++ b/types/shell/index.d.ts @@ -16,18 +16,23 @@ export interface ShellCommonProps extends HTMLAttributes, CommonPro export interface ShellNavigationProps extends ShellCommonProps { collapse?: boolean; direction?: 'hoz' | 'ver'; + align?: 'left' | 'right' | 'center'; + onCollapseChange?: (collapse?: boolean) => {}; } export interface ShellLocalNavigationProps extends ShellCommonProps { collapse?: boolean; + onCollapseChange?: (collapse?: boolean) => {}; } export interface ShellToolDockProps extends ShellCommonProps { collapse?: boolean; + onCollapseChange?: (collapse?: boolean) => {}; } export interface ShellAncillaryProps extends ShellCommonProps { collapse?: boolean; + onCollapseChange?: (collapse?: boolean) => {}; } export default class Shell extends Component { From d26b26215ff150ad29fec5ce1ed02bc02deaa691 Mon Sep 17 00:00:00 2001 From: youluna Date: Fri, 14 Feb 2020 18:41:48 +0800 Subject: [PATCH 15/53] chore(*): Release-1.19.13 --- CHANGELOG.md | 16 ++++++++++++++++ LATESTLOG.md | 11 ++++++++--- index.js | 2 +- package.json | 2 +- site/en-us/theme.md | 5 ++++- site/zh-cn/theme.md | 5 ++++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd2a408c0..98fe5bb5a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +## [1.19.13](https://github.com/alibaba-fusion/next/compare/1.19.12...1.19.13) (2020-02-14) + + +### Bug Fixes + +* **Collapse:** collapsed panel should be overflow hidden, close [#1569](https://github.com/alibaba-fusion/next/issues/1569) ([c2767ec](https://github.com/alibaba-fusion/next/commit/c2767ec)) + + +### Features + +* **Shell:** add align for Shell.Navigaiton ([#1576](https://github.com/alibaba-fusion/next/issues/1576)) ([e6318c3](https://github.com/alibaba-fusion/next/commit/e6318c3)) +* **Table:** add htmlTitle for header ([8a89c0a](https://github.com/alibaba-fusion/next/commit/8a89c0a)) + + + + ## [1.19.12](https://github.com/alibaba-fusion/next/compare/1.19.11...1.19.12) (2020-02-10) diff --git a/LATESTLOG.md b/LATESTLOG.md index 0f41e15d6f..74cc3212ed 100644 --- a/LATESTLOG.md +++ b/LATESTLOG.md @@ -1,11 +1,16 @@ # Latest Log -## [1.19.12](https://github.com/alibaba-fusion/next/compare/1.19.11...1.19.12) (2020-02-10) +## [1.19.13](https://github.com/alibaba-fusion/next/compare/1.19.12...1.19.13) (2020-02-14) ### Bug Fixes -* **Checkbox:** allow pass title to label ([fd36f8c](https://github.com/alibaba-fusion/next/commit/fd36f8c)) -* **Tab:** fix tab hover shake ([#1563](https://github.com/alibaba-fusion/next/issues/1563)) ([c921c89](https://github.com/alibaba-fusion/next/commit/c921c89)) +* **Collapse:** collapsed panel should be overflow hidden, close [#1569](https://github.com/alibaba-fusion/next/issues/1569) ([c2767ec](https://github.com/alibaba-fusion/next/commit/c2767ec)) + + +### Features + +* **Shell:** add align for Shell.Navigaiton ([#1576](https://github.com/alibaba-fusion/next/issues/1576)) ([e6318c3](https://github.com/alibaba-fusion/next/commit/e6318c3)) +* **Table:** add htmlTitle for header ([8a89c0a](https://github.com/alibaba-fusion/next/commit/8a89c0a)) diff --git a/index.js b/index.js index 88992cd435..90c22b02ac 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ var next = require('./lib/index.js'); -next.version = '1.19.12'; +next.version = '1.19.13'; module.exports = next; diff --git a/package.json b/package.json index ec4cf6d27c..c19ce5958d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@alifd/next", - "version": "1.19.12", + "version": "1.19.13", "description": "A configurable component library for web built on React.", "keywords": [ "fusion", diff --git a/site/en-us/theme.md b/site/en-us/theme.md index d665284b85..5eb55fe047 100644 --- a/site/en-us/theme.md +++ b/site/en-us/theme.md @@ -56,7 +56,10 @@ module.exports = { plugins: [ 'add-module-exports', 'transform-decorators-legacy', - ['babel-plugin-import', { style: true }] + ['babel-plugin-import', { + libraryName: '@alifd/next', + style: true + }] ] } }, diff --git a/site/zh-cn/theme.md b/site/zh-cn/theme.md index 50ed9f734c..d3dfd2f05c 100644 --- a/site/zh-cn/theme.md +++ b/site/zh-cn/theme.md @@ -64,7 +64,10 @@ module.exports = { plugins: [ 'add-module-exports', 'transform-decorators-legacy', - ['babel-plugin-import', { style: true }], + ['babel-plugin-import', { + libraryName: '@alifd/next', + style: true + }], ], }, }, From 6a989902102cc9093bf98bf218d3941ffa061674 Mon Sep 17 00:00:00 2001 From: youluna Date: Tue, 18 Feb 2020 21:05:15 +0800 Subject: [PATCH 16/53] feat(List): make list configurable --- docs/list/theme/index.jsx | 68 ++++++++++++++++++++++++++++--------- src/list/scss/variable.scss | 46 ++++++++++++------------- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/docs/list/theme/index.jsx b/docs/list/theme/index.jsx index f3f9f35a3d..bb5394656e 100644 --- a/docs/list/theme/index.jsx +++ b/docs/list/theme/index.jsx @@ -3,19 +3,29 @@ import ReactDOM from 'react-dom'; import '../../../src/demo-helper/style.js'; import { Demo, DemoGroup, initDemo } from '../../../src/demo-helper'; import ConfigProvider from '../../../src/config-provider'; +import Box from '../../../src/box'; +import Button from '../../../src/button'; +import Avatar from '../../../src/avatar'; +import Divider from '../../../src/divider'; import zhCN from '../../../src/locale/zh-cn'; import enUS from '../../../src/locale/en-us'; import '../../../src/list/style.js'; +import '../../../src/box/style.js'; +import '../../../src/button/style.js'; +import '../../../src/divider/style.js'; +import '../../../src/avatar/style.js'; import List from '../../../src/list'; const i18nMap = { 'zh-cn': { 'list': '列表', - normal: '正常' + normal: '正常', + small: '小列表' }, 'en-us': { 'list': 'List', normal: 'Normal', + small: '小列表' }, }; @@ -24,17 +34,7 @@ class RenderList extends React.Component { super(props); this.state = { demoFunction: { - hasChildren: { - label: 'List使用', - value: 'false', - enum: [{ - label: '不独立使用', - value: false - }, { - label: '独立使用', - value: true - }] - } + } }; } @@ -46,12 +46,48 @@ class RenderList extends React.Component { render() { const { i18nMap } = this.props; const { demoFunction } = this.state; - const hasChildren = demoFunction.hasChildren.value === 'true'; + const actions = ( + + + + + + ); - return ( - + return ( + + + Notifications
}> + } title="Title">List Item 1 + }>List Item 2 + }>List Item 3 + }>List Item 4 + }>List Item 5 + + - + + } title="构建一套产品化设计系统"> +

随着互联网行业的聚变式发展,在电商业务从“信息透出” 到 “在线交易” 的过程中,网站 UI 构建也经历了“体验一致性”、“设计效率”、“UI系统构建/应用效率”、“多端适配” …

+
谢瑶 3 小时前更新
+
+ }> +

随着互联网行业的聚变式发展,在电商业务从“信息透出” 到 “在线交易” 的过程中,网站 UI 构建也经历了“体验一致性”、“设计效率”、“UI系统构建/应用效率”、“多端适配” …

+
谢瑶 3 小时前更新
+
+ }> +

随着互联网行业的聚变式发展,在电商业务从“信息透出” 到 “在线交易” 的过程中,网站 UI 构建也经历了“体验一致性”、“设计效率”、“UI系统构建/应用效率”、“多端适配” …

+
谢瑶 3 小时前更新
+
+ }> +

随着互联网行业的聚变式发展,在电商业务从“信息透出” 到 “在线交易” 的过程中,网站 UI 构建也经历了“体验一致性”、“设计效率”、“UI系统构建/应用效率”、“多端适配” …

+
谢瑶 3 小时前更新
+
+ }> +

随着互联网行业的聚变式发展,在电商业务从“信息透出” 到 “在线交易” 的过程中,网站 UI 构建也经历了“体验一致性”、“设计效率”、“UI系统构建/应用效率”、“多端适配” …

+
谢瑶 3 小时前更新
+
+
); diff --git a/src/list/scss/variable.scss b/src/list/scss/variable.scss index bb1eb1537c..971341c9df 100644 --- a/src/list/scss/variable.scss +++ b/src/list/scss/variable.scss @@ -10,7 +10,7 @@ /// @family data-display /// @varPrefix $list- /// @classPrefix {prefix}-list -/// @order {} +/// @order {"size/title":10,"size/item":11,"size/item/title":110,"size/item/content":111,"statement/normal":10,"statement/normal/divider":100,"statement/normal/title":101,"statement/normal/content":102,"statement/normal/extra":103} //// // Unconfigurable @@ -28,27 +28,27 @@ $list-size-s-title-font-size: $font-size-subhead !default; $list-size-s-title-font-weight: $font-weight-3 !default; /// padding(l, r) /// @namespace size/item -$list-size-s-item-padding-lr: $s-0 !default; +$list-size-s-item-padding-lr: $s-zero !default; /// padding(t, b) /// @namespace size/item $list-size-s-item-padding-tb: $s-3 !default; /// margin(l, r) /// @namespace size/item $list-size-s-item-media-margin: $s-2 !default; -/// font size -/// @namespace size/item/title +/// title font-size +/// @namespace size/item $list-size-s-item-title-font-size: $font-size-body-2 !default; -/// line height -/// @namespace size/item/title +/// title line-height +/// @namespace size/item $list-size-s-item-title-line-height: $font-lineheight-2 !default; -/// font size -/// @namespace size/item/content +/// content font-size +/// @namespace size/item $list-size-s-item-content-font-size: $font-size-body-1 !default; -/// line height -/// @namespace size/item/content +/// content line-height +/// @namespace size/item $list-size-s-item-content-line-height: $font-lineheight-1 !default; -/// font-weight -/// @namespace size/item/title +/// title font-weight +/// @namespace size/item $list-size-s-item-title-font-weight: $font-weight-3 !default; /// font-size /// @namespace size/title @@ -58,27 +58,27 @@ $list-size-m-title-font-size: $font-size-title !default; $list-size-m-title-font-weight: $font-weight-3 !default; /// padding(l, r) /// @namespace size/item -$list-size-m-item-padding-lr: $s-0 !default; +$list-size-m-item-padding-lr: $s-zero !default; /// padding(t, b) /// @namespace size/item $list-size-m-item-padding-tb: $s-4 !default; /// margin(l, r) /// @namespace size/item $list-size-m-item-media-margin: $s-2 !default; -/// font size -/// @namespace size/item/title +/// title font-size +/// @namespace size/item $list-size-m-item-title-font-size: $font-size-subhead !default; -/// line height -/// @namespace size/item/title +/// title line-height +/// @namespace size/item $list-size-m-item-title-line-height: $font-lineheight-2 !default; -/// font size -/// @namespace size/item/content +/// content font-size +/// @namespace size/item $list-size-m-item-content-font-size: $font-size-body-2 !default; -/// line height -/// @namespace size/item/content +/// content line-height +/// @namespace size/item $list-size-m-item-content-line-height: $font-lineheight-2 !default; -/// font-weight -/// @namespace size/item/title +/// title font-weight +/// @namespace size/item $list-size-m-item-title-font-weight: $font-weight-3 !default; /// color /// @namespace statement/normal/divider From 4455570736dacc8a7b10e7477540767600f8729c Mon Sep 17 00:00:00 2001 From: frankqian Date: Fri, 21 Feb 2020 09:45:20 +0800 Subject: [PATCH 17/53] fix(Tree): bug of selected close #1578 * fix(Tree): bug of selected close #1578 --- src/tree/view/tree.jsx | 2 +- test/tree/index-spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tree/view/tree.jsx b/src/tree/view/tree.jsx index fa27611289..30865ce0a3 100644 --- a/src/tree/view/tree.jsx +++ b/src/tree/view/tree.jsx @@ -665,7 +665,7 @@ export default class Tree extends Component { if (multiple) { this.processKey(selectedKeys, key, select); } else { - selectedKeys = [key]; + selectedKeys = select ? [key] : []; } if (!('selectedKeys' in this.props)) { diff --git a/test/tree/index-spec.js b/test/tree/index-spec.js index b0bfba2de4..158a4a40a1 100644 --- a/test/tree/index-spec.js +++ b/test/tree/index-spec.js @@ -403,7 +403,7 @@ describe('Tree', () => { assertSelected('3', true); selectTreeNode('3'); - assertSelected('3', true); + assertSelected('3', false); }); it('should support selectedKeys and onSelect', () => { From 338876f221f71a873922bd9d64320c5706201374 Mon Sep 17 00:00:00 2001 From: xuhong Date: Fri, 21 Feb 2020 14:31:09 +0800 Subject: [PATCH 18/53] fix(Tab): fix tab style and aria (#1577) * fix(Tab): fix tab style and aria --- src/locale/en-us.js | 3 +++ src/locale/ja-jp.js | 3 +++ src/locale/zh-cn.js | 3 +++ src/locale/zh-tw.js | 3 +++ src/tab/scss/mixin.scss | 3 +++ src/tab/tab.jsx | 5 +++++ src/tab/tabs/nav.jsx | 4 ++++ src/tab/tabs/tab-item.jsx | 3 ++- types/locale/default.d.ts | 3 +++ 9 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/locale/en-us.js b/src/locale/en-us.js index 3d8cbfb10e..0b9fe16fb7 100644 --- a/src/locale/en-us.js +++ b/src/locale/en-us.js @@ -133,4 +133,7 @@ export default { on: 'on', off: 'off', }, + Tab: { + closeAriaLabel: 'close', + }, }; diff --git a/src/locale/ja-jp.js b/src/locale/ja-jp.js index b7f9bb92b8..c54bf6983b 100644 --- a/src/locale/ja-jp.js +++ b/src/locale/ja-jp.js @@ -131,4 +131,7 @@ export default { on: '開いています', off: '閉じられました', }, + Tab: { + closeAriaLabel: '閉じられました', + }, }; diff --git a/src/locale/zh-cn.js b/src/locale/zh-cn.js index a377af45db..f7a1d30e4f 100644 --- a/src/locale/zh-cn.js +++ b/src/locale/zh-cn.js @@ -131,4 +131,7 @@ export default { on: '已打开', off: '已关闭', }, + Tab: { + closeAriaLabel: '关闭', + }, }; diff --git a/src/locale/zh-tw.js b/src/locale/zh-tw.js index fe465b1c9e..7339ded8c2 100644 --- a/src/locale/zh-tw.js +++ b/src/locale/zh-tw.js @@ -131,4 +131,7 @@ export default { on: '已打開', off: '已關閉', }, + Tab: { + closeAriaLabel: '關閉', + }, }; diff --git a/src/tab/scss/mixin.scss b/src/tab/scss/mixin.scss index 572161ec49..3f6651fc5a 100755 --- a/src/tab/scss/mixin.scss +++ b/src/tab/scss/mixin.scss @@ -97,6 +97,9 @@ &:hover { color: $icon-color-hover; } + &:focus { + outline: none; + } } &.active { diff --git a/src/tab/tab.jsx b/src/tab/tab.jsx index 98d6ff9ea4..fec1cbbc2c 100644 --- a/src/tab/tab.jsx +++ b/src/tab/tab.jsx @@ -5,6 +5,7 @@ import { KEYCODE, obj } from '../util'; import TabNav from './tabs/nav'; import TabContent from './tabs/content'; import { toArray } from './tabs/utils'; +import zhCN from '../locale/zh-cn'; const noop = () => {}; @@ -104,6 +105,7 @@ export default class Tab extends Component { popupProps: PropTypes.object, children: PropTypes.any, className: PropTypes.string, + locale: PropTypes.object, }; static defaultProps = { @@ -119,6 +121,7 @@ export default class Tab extends Component { onClick: noop, onChange: noop, onClose: noop, + locale: zhCN.Tab, }; constructor(props, context) { @@ -248,6 +251,7 @@ export default class Tab extends Component { children, rtl, device, + locale, ...others } = this.props; const { activeKey } = this.state; @@ -289,6 +293,7 @@ export default class Tab extends Component { onKeyDown: this.onNavKeyDown, style: navStyle, className: navClassName, + locale, }; const contentProps = { diff --git a/src/tab/tabs/nav.jsx b/src/tab/tabs/nav.jsx index 33280777a4..ea9bb17c54 100644 --- a/src/tab/tabs/nav.jsx +++ b/src/tab/tabs/nav.jsx @@ -36,6 +36,7 @@ class Nav extends React.Component { onClose: PropTypes.func, style: PropTypes.object, className: PropTypes.string, + locale: PropTypes.object, }; constructor(props, context) { @@ -299,8 +300,10 @@ class Nav extends React.Component { }; defaultTabTemplateRender = (key, { prefix, title, closeable }) => { + const { locale } = this.props; const tail = closeable ? ( this.onCloseKeyDown(key, e)} @@ -319,6 +322,7 @@ class Nav extends React.Component { renderTabList(props) { const { prefix, tabs, activeKey, tabRender } = props; const tabTemplateFn = tabRender || this.defaultTabTemplateRender; + const { locale } = this.props; const rst = []; React.Children.forEach(tabs, child => { diff --git a/src/tab/tabs/tab-item.jsx b/src/tab/tabs/tab-item.jsx index ec09ea226d..481be7c1db 100644 --- a/src/tab/tabs/tab-item.jsx +++ b/src/tab/tabs/tab-item.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { polyfill } from 'react-lifecycles-compat'; /** Tab.Item */ class TabItem extends React.Component { @@ -64,4 +65,4 @@ class TabItem extends React.Component { } } -export default TabItem; +export default polyfill(TabItem); diff --git a/types/locale/default.d.ts b/types/locale/default.d.ts index cab673f477..f6de967184 100644 --- a/types/locale/default.d.ts +++ b/types/locale/default.d.ts @@ -131,4 +131,7 @@ export interface locale { on: string; off: string; }; + Tab: { + closeAriaLabel: string; + }; } From 66fb5bed1c69f028c1660c148b578988291768e6 Mon Sep 17 00:00:00 2001 From: aboutblank Date: Fri, 21 Feb 2020 14:36:01 +0800 Subject: [PATCH 19/53] Add side effect (#1591) * temp(*): add side effects for webpack4 * fix(ResponsiveGrid): fix chrome 80 --- package.json | 13 ++++++++++++- src/responsive-grid/create-style.js | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c19ce5958d..cbc9f8b98f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,12 @@ "fusion design", "next", "component", - "ui tookit" + "ui tookit", + "react", + "react-components", + "components", + "design", + "frontend" ], "homepage": "https://github.com/alibaba-fusion/next", "bugs": "https://github.com/alibaba-fusion/next/issues", @@ -32,6 +37,12 @@ "type": "git", "url": "https://github.com/alibaba-fusion/next.git" }, + "sideEffects": [ + "dist/*", + "es/**/style/*", + "lib/**/style/*", + "*.scss" + ], "scripts": { "report-coverage": "codecov", "dev": "node ./scripts/server/index.js", diff --git a/src/responsive-grid/create-style.js b/src/responsive-grid/create-style.js index 3c0066caf3..2875c2565c 100644 --- a/src/responsive-grid/create-style.js +++ b/src/responsive-grid/create-style.js @@ -133,7 +133,7 @@ const getGridGap = gap => { const getTemplateCount = counts => { if (!isNaN(counts)) { - return `repeat(${counts}, 1fr)`; + return `repeat(${counts}, minmax(0,1fr))`; } return counts; From cb6597c30ebb0748313c342e815371027fbee543 Mon Sep 17 00:00:00 2001 From: youluna Date: Fri, 21 Feb 2020 14:52:08 +0800 Subject: [PATCH 20/53] chore(*): Release-1.19.14 --- CHANGELOG.md | 10 ++++++++++ LATESTLOG.md | 10 ++-------- index.js | 2 +- package.json | 2 +- types/upload/index.d.ts | 4 ++++ 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fe5bb5a2..00ff043769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## [1.19.14](https://github.com/alibaba-fusion/next/compare/1.19.13...1.19.14) (2020-02-21) + + +### Bug Fixes + +* **Tree:** bug of selected close [#1578](https://github.com/alibaba-fusion/next/issues/1578) ([4455570](https://github.com/alibaba-fusion/next/commit/4455570)) + + + + ## [1.19.13](https://github.com/alibaba-fusion/next/compare/1.19.12...1.19.13) (2020-02-14) diff --git a/LATESTLOG.md b/LATESTLOG.md index 74cc3212ed..bd0d818154 100644 --- a/LATESTLOG.md +++ b/LATESTLOG.md @@ -1,16 +1,10 @@ # Latest Log -## [1.19.13](https://github.com/alibaba-fusion/next/compare/1.19.12...1.19.13) (2020-02-14) +## [1.19.14](https://github.com/alibaba-fusion/next/compare/1.19.13...1.19.14) (2020-02-21) ### Bug Fixes -* **Collapse:** collapsed panel should be overflow hidden, close [#1569](https://github.com/alibaba-fusion/next/issues/1569) ([c2767ec](https://github.com/alibaba-fusion/next/commit/c2767ec)) - - -### Features - -* **Shell:** add align for Shell.Navigaiton ([#1576](https://github.com/alibaba-fusion/next/issues/1576)) ([e6318c3](https://github.com/alibaba-fusion/next/commit/e6318c3)) -* **Table:** add htmlTitle for header ([8a89c0a](https://github.com/alibaba-fusion/next/commit/8a89c0a)) +* **Tree:** bug of selected close [#1578](https://github.com/alibaba-fusion/next/issues/1578) ([4455570](https://github.com/alibaba-fusion/next/commit/4455570)) diff --git a/index.js b/index.js index 90c22b02ac..c93bdfb6c9 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ var next = require('./lib/index.js'); -next.version = '1.19.13'; +next.version = '1.19.14'; module.exports = next; diff --git a/package.json b/package.json index cbc9f8b98f..dbfb9f6e45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@alifd/next", - "version": "1.19.13", + "version": "1.19.14", "description": "A configurable component library for web built on React.", "keywords": [ "fusion", diff --git a/types/upload/index.d.ts b/types/upload/index.d.ts index e3b05c6acf..7b24f7e21d 100644 --- a/types/upload/index.d.ts +++ b/types/upload/index.d.ts @@ -391,6 +391,10 @@ export interface UploadProps extends HTMLAttributesWeak, CommonProps { */ onRemove?: (file: {}) => boolean | any; + /** + * 自定义额外渲染 + */ + extraRender?: (file: File) => any; /** * 自定义class */ From 9e528280324109999746b0513134d7287c8bef88 Mon Sep 17 00:00:00 2001 From: youluna Date: Fri, 21 Feb 2020 21:53:55 +0800 Subject: [PATCH 21/53] fix(*): correct sideEffect path --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index dbfb9f6e45..ee30caf647 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,8 @@ }, "sideEffects": [ "dist/*", - "es/**/style/*", - "lib/**/style/*", + "es/**/style.js", + "lib/**/style.js", "*.scss" ], "scripts": { From 8b483f83e9715193e450d8a528329d794667718a Mon Sep 17 00:00:00 2001 From: bindoon Date: Fri, 21 Feb 2020 22:48:18 +0800 Subject: [PATCH 22/53] feat(Form): api useLabelForErrorMessage for replace name fix #294 --- docs/form/demo/validate-custom-error.md | 2 +- docs/form/demo/validate-label-as-name.md | 91 ++++++++++++++++++++++++ package.json | 2 +- src/form/enhance.jsx | 12 +++- src/form/form.jsx | 6 ++ src/form/item.jsx | 30 +++++++- test/form/validate-spec.js | 20 ++++++ 7 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 docs/form/demo/validate-label-as-name.md diff --git a/docs/form/demo/validate-custom-error.md b/docs/form/demo/validate-custom-error.md index a14a04baa0..0f9ab26a86 100644 --- a/docs/form/demo/validate-custom-error.md +++ b/docs/form/demo/validate-custom-error.md @@ -1,4 +1,4 @@ -# 校验 +# 校验(自定义错误) - order: 9 diff --git a/docs/form/demo/validate-label-as-name.md b/docs/form/demo/validate-label-as-name.md new file mode 100644 index 0000000000..16498ff18b --- /dev/null +++ b/docs/form/demo/validate-label-as-name.md @@ -0,0 +1,91 @@ +# label作为校验提示 + +- order: 9 + +使用 label 作为校验提示 + +:::lang=en-us +# Validate + +- order: 9 + +use label as name for validate message +::: + +--- + +````jsx +import { Form, Input, Radio } from '@alifd/next'; + + +const FormItem = Form.Item; +const RadioGroup = Radio.Group; + +const formItemLayout = { + labelCol: { + span: 6 + }, + wrapperCol: { + span: 14 + } +}; + +class Demo extends React.Component { + render() { + return ( +
+ + + + + + + + + + + + + + Male + Female + + + + + + + + + console.log(v, e)} style={{marginRight: 10}}>Submit + Reset + + + ); + } +} + +ReactDOM.render(, mountNode); +```` diff --git a/package.json b/package.json index c19ce5958d..a6925261d2 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ }, "dependencies": { "@alifd/field": "~1.3.3", - "@alifd/validate": "~1.1.4", + "@alifd/validate": "~1.2.0", "babel-runtime": "^6.26.0", "classnames": "^2.2.3", "hoist-non-react-statics": "^2.1.0", diff --git a/src/form/enhance.jsx b/src/form/enhance.jsx index 7dc0df708f..1d1e5730b2 100644 --- a/src/form/enhance.jsx +++ b/src/form/enhance.jsx @@ -32,7 +32,7 @@ function getValueName(props, displayName) { return 'value'; } -export function getRules(props) { +export function getRules(props, labelForErrorMessage) { const result = []; // required @@ -99,14 +99,20 @@ export function getRules(props) { }); } + if (labelForErrorMessage) { + result.forEach(r => { + r.aliasName = labelForErrorMessage; + }); + } + return result; } -export function getFieldInitCfg(props, displayName) { +export function getFieldInitCfg(props, displayName, labelForErrorMessage) { return { valueName: getValueName(props, displayName), trigger: props.trigger ? props.trigger : 'onChange', autoValidate: props.autoValidate, - rules: getRules(props), + rules: getRules(props, labelForErrorMessage), }; } diff --git a/src/form/form.jsx b/src/form/form.jsx index 39898d6bf0..cef125c1bb 100644 --- a/src/form/form.jsx +++ b/src/form/form.jsx @@ -112,6 +112,10 @@ export default class Form extends React.Component { * 是否开启预览态 */ isPreview: PropTypes.bool, + /** + * 是否使用 label 替换校验信息的 name 字段 + */ + useLabelForErrorMessage: PropTypes.bool, }; static defaultProps = { @@ -130,6 +134,7 @@ export default class Form extends React.Component { _formSize: PropTypes.string, _formPreview: PropTypes.bool, _formFullWidth: PropTypes.bool, + _formLabelForErrorMessage: PropTypes.bool, }; constructor(props) { @@ -165,6 +170,7 @@ export default class Form extends React.Component { _formSize: this.props.size, _formPreview: this.props.isPreview, _formFullWidth: this.props.fullWidth, + _formLabelForErrorMessage: this.props.useLabelForErrorMessage, }; } diff --git a/src/form/item.jsx b/src/form/item.jsx index 75708866b3..160a91c510 100644 --- a/src/form/item.jsx +++ b/src/form/item.jsx @@ -218,6 +218,10 @@ export default class Item extends React.Component { * @param {any} value 根据包裹的组件的 value 类型而决定 */ renderPreview: PropTypes.func, + /** + * 是否使用 label 替换校验信息的 name 字段 + */ + useLabelForErrorMessage: PropTypes.bool, }; static defaultProps = { @@ -231,6 +235,7 @@ export default class Item extends React.Component { _formSize: PropTypes.oneOf(['large', 'small', 'medium']), _formPreview: PropTypes.bool, _formFullWidth: PropTypes.bool, + _formLabelForErrorMessage: PropTypes.bool, }; static _typeMark = 'form_item'; @@ -299,6 +304,26 @@ export default class Item extends React.Component { : this.props.fullWidth; } + getLabelForErrorMessage() { + let label = this.props.label; + + if (!label || typeof label !== 'string') { + return null; + } + + label = label.replace(':', '').replace(':', ''); + + const labelForErrorMessage = + 'useLabelForErrorMessage' in this.props + ? this.props.useLabelForErrorMessage + : this.context._formLabelForErrorMessage; + if (labelForErrorMessage && label) { + return label; + } + + return null; + } + getItemLabel() { const { id, @@ -403,6 +428,8 @@ export default class Item extends React.Component { childrenNode = children(this.context._formField.getValues()); } + const labelForErrorMessage = this.getLabelForErrorMessage(); + const ele = React.Children.map(childrenNode, child => { if ( child && @@ -421,7 +448,8 @@ export default class Item extends React.Component { { ...getFieldInitCfg( this.props, - child.type.displayName + child.type.displayName, + labelForErrorMessage ), props: { ...child.props, ref: child.ref }, }, diff --git a/test/form/validate-spec.js b/test/form/validate-spec.js index 3904615d40..d0863706a0 100644 --- a/test/form/validate-spec.js +++ b/test/form/validate-spec.js @@ -204,6 +204,26 @@ describe('Submit', () => { .text() === 'first 是必填字段' ); }); + it('validate useLabelForErrorMessage', () => { + const wrapper = mount( +
+ + + + + ); + + wrapper + .find('input#first') + .simulate('change', { target: { value: '' } }); + wrapper.update(); + assert( + wrapper + .find('.next-form-item-help') + .first() + .text() === '姓名 是必填字段' + ); + }); }); describe('Reset', () => { From a036fff859720e2ecfa8c4785fdaee9cafef31f0 Mon Sep 17 00:00:00 2001 From: youluna Date: Mon, 24 Feb 2020 11:05:29 +0800 Subject: [PATCH 23/53] chore(*): Release-1.19.15 --- CHANGELOG.md | 10 ++++++++++ LATESTLOG.md | 4 ++-- index.js | 2 +- package.json | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00ff043769..68e0472238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## [1.19.15](https://github.com/alibaba-fusion/next/compare/1.19.14...1.19.15) (2020-02-24) + + +### Bug Fixes + +* correct sideEffect path ([9e52828](https://github.com/alibaba-fusion/next/commit/9e52828)) + + + + ## [1.19.14](https://github.com/alibaba-fusion/next/compare/1.19.13...1.19.14) (2020-02-21) diff --git a/LATESTLOG.md b/LATESTLOG.md index bd0d818154..2411231f21 100644 --- a/LATESTLOG.md +++ b/LATESTLOG.md @@ -1,10 +1,10 @@ # Latest Log -## [1.19.14](https://github.com/alibaba-fusion/next/compare/1.19.13...1.19.14) (2020-02-21) +## [1.19.15](https://github.com/alibaba-fusion/next/compare/1.19.14...1.19.15) (2020-02-24) ### Bug Fixes -* **Tree:** bug of selected close [#1578](https://github.com/alibaba-fusion/next/issues/1578) ([4455570](https://github.com/alibaba-fusion/next/commit/4455570)) +* correct sideEffect path ([9e52828](https://github.com/alibaba-fusion/next/commit/9e52828)) diff --git a/index.js b/index.js index c93bdfb6c9..bff9da3e35 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ var next = require('./lib/index.js'); -next.version = '1.19.14'; +next.version = '1.19.15'; module.exports = next; diff --git a/package.json b/package.json index ee30caf647..8dfa2b50d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@alifd/next", - "version": "1.19.14", + "version": "1.19.15", "description": "A configurable component library for web built on React.", "keywords": [ "fusion", From 8908dc6c33ab33d929ecb3e2683b6ce04cb6bc3f Mon Sep 17 00:00:00 2001 From: bindoon Date: Tue, 25 Feb 2020 16:10:13 +0800 Subject: [PATCH 24/53] docs(Upload): update demo to support IE/Edge --- docs/upload/demo/crop.md | 59 ++++++++++++--------- docs/upload/demo/error.md | 44 ---------------- scripts/upload-server.js | 106 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 69 deletions(-) delete mode 100644 docs/upload/demo/error.md create mode 100644 scripts/upload-server.js diff --git a/docs/upload/demo/crop.md b/docs/upload/demo/crop.md index 3a475f9c05..9f7a36f4ef 100644 --- a/docs/upload/demo/crop.md +++ b/docs/upload/demo/crop.md @@ -2,23 +2,15 @@ - order: 10 -提醒: `https://www.easy-mock.com/mock/5b713974309d0d7d107a74a3/alifd/upload`接口: - - -> 1. 该接口仅作为测试使用,业务请勿使用 - -> 2. 该接口仅支持图片上传,其他文件类型接口请自备 +提供了两种方案,如果不需要支持 IE 推荐方案1 :::lang=en-us # Crop - order: 10 -Waring: `https://www.easy-mock.com/mock/5b713974309d0d7d107a74a3/alifd/upload` API: +transfor dataURL to Blob to File -> 1. only for test & develop, Never Use in production enviroments - -> 2. only support upload images ::: --- @@ -28,26 +20,43 @@ import Cropper from 'react-cropper'; import 'cropperjs/dist/cropper.css'; -function convertBase64UrlToFile(urlData) { - - const bytes = window.atob(urlData.split(',')[1]); - - const ab = new ArrayBuffer(bytes.length); - const ia = new Uint8Array(ab); - for (let i = 0; i < bytes.length; i++) { - ia[i] = bytes.charCodeAt(i); +// 方案1: 通过new File()将base64转换成file文件。简单,但是 IE/Edge 因为不支持 File Constructor 无法使用 +function dataURL2File(dataURL, filename) { + const arr = dataURL.split(','), + mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), + u8arr = new Uint8Array(bstr.length); + let n = bstr.length; + while (n--) { + u8arr[n] = bstr.charCodeAt(n); } - - const blob = new Blob([ab], {type: 'image/png'}); - - return new File([blob], 'test.png', {type: 'image/png'}); + return new File([u8arr], filename, { type: mime }); } +// 方案2: 将base64转换成blob,再将blob转换成file文件 +function dataURL2Blob(dataURL) { + const arr = dataURL.split(','), + mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), + u8arr = new Uint8Array(bstr.length); + let n = bstr.length; + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], { type: mime }); +}; +function dataURL2Blob2File(dataURL, fileName){ + const blob = dataURL2Blob(dataURL); + blob.lastModifiedDate = new Date(); + blob.name = fileName; + return blob; +}; + class App extends React.Component { constructor(props) { super(props); this.uploader = new Upload.Uploader({ - action: 'https://www.easy-mock.com/mock/5b713974309d0d7d107a74a3/alifd/upload', + action: 'http://127.0.0.1:6001/upload.do', onSuccess: this.onSuccess, name: 'file' }); @@ -87,8 +96,8 @@ class App extends React.Component { const data = this.cropperRef.getCroppedCanvas().toDataURL(); - const blob = convertBase64UrlToFile(data); - const file = new File([blob], 'test.png', {type: 'image/png'}); + // const file = dataURL2File(data, 'test.png'); + const file = dataURL2Blob2File(data, 'test.png'); // start upload this.uploader.startUpload(file); diff --git a/docs/upload/demo/error.md b/docs/upload/demo/error.md deleted file mode 100644 index 58c4bf7e5e..0000000000 --- a/docs/upload/demo/error.md +++ /dev/null @@ -1,44 +0,0 @@ -# 上传失败 - -- order: 12 - -:::lang=en-us - -# Fail Status - -- order: 4 - ::: - ---- - -````jsx -import { Upload, Button } from '@alifd/next'; - - -const value = [ - { - uid: '2', - name: 'IMG.png', - state: 'error', - url: - 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg', - downloadURL: - 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg', - imgURL: - 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg' - } -]; - -ReactDOM.render( -
- - -
- - -
- -
, - mountNode -); -```` diff --git a/scripts/upload-server.js b/scripts/upload-server.js new file mode 100644 index 0000000000..ae5f8db404 --- /dev/null +++ b/scripts/upload-server.js @@ -0,0 +1,106 @@ +/** + * test server for Upload demo + * $ node script/upload-server.js + */ +const formidable = require('formidable'); +const path = require('path'); +const fs = require('fs'); +const http = require('http'); + +const port = 6001; +const tmpdir = path.resolve(__dirname, '../node_modules'); + +http.createServer(function(req, res) { + const method = req.method.toLowerCase(); + /* eslint-disable no-console */ + console.log(method, req.url); + // console.log(req.headers) + + if (req.url.match('/upload.do')) { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader( + 'Access-Control-Allow-Headers', + 'Origin, X-Requested-With, Content-Type, Accept' + ); + + if (method === 'post') { + // parse a file upload + const form = new formidable.IncomingForm(); + form.encoding = 'utf-8'; + form.uploadDir = tmpdir; + form.keepExtensions = true; + + form.parse(req, function(err, fields, files) { + if (err) { + res.send({ success: false, message: err }); + return; + } + + console.log('fields:', fields); + console.log('files:', files); + + res.writeHead(200); + if (files.file) { + console.log(`recive file: ${files.file.path}`); + + // res.writeHead(200, {'content-type': 'application/json'}); + // res.write(``); + + res.end( + JSON.stringify({ + success: true, + message: 'success', + url: `http://${ + req.headers.host + }${files.file.path.replace(tmpdir, '')}`, + }) + ); + } else { + res.end( + JSON.stringify({ + success: false, + message: 'use like name = file', + }) + ); + } + }); + + return; + } else { + res.writeHead(200, { 'content-type': 'text/html' }); + res.end(`
+ +
+ + `); + } + } else if (req.url === '/crossdomain.xml') { + res.writeHead(200, { 'content-type': 'application/xml' }); + res.end(` + + + +`); + return; + } else if (method === 'get') { + const pathname = req.url.split('?')[0]; + const realPath = tmpdir + pathname; //所有文件都存在与resources目录下 + console.log(realPath); + fs.exists(realPath, function(exists) { + //判断文件是否存在 + if (!exists || !fs.statSync(realPath).isFile()) { + res.writeHead(404, { 'Content-Type': 'text/plain' }); + res.write('Not Found!\n'); + res.end(); + } else { + fs.readFile(realPath, 'binary', function(err, file) { + res.writeHead(200, { 'Content-Type': 'image/jpg' }); + res.write(file, 'binary'); + res.end(); + }); + } + }); + } +}).listen(port); + +console.log(`Listen to: http://127.0.0.1:${port}/upload.do`); From 5b4fe854c3f0ff6c6d57c2c702725a0f18f1e4f7 Mon Sep 17 00:00:00 2001 From: bindoon Date: Tue, 25 Feb 2020 16:17:21 +0800 Subject: [PATCH 25/53] chore(Upload): update demo usage --- docs/upload/demo/crop.md | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/docs/upload/demo/crop.md b/docs/upload/demo/crop.md index 9f7a36f4ef..89d1d80596 100644 --- a/docs/upload/demo/crop.md +++ b/docs/upload/demo/crop.md @@ -19,9 +19,7 @@ import { Upload, Button, Dialog } from '@alifd/next'; import Cropper from 'react-cropper'; import 'cropperjs/dist/cropper.css'; - -// 方案1: 通过new File()将base64转换成file文件。简单,但是 IE/Edge 因为不支持 File Constructor 无法使用 -function dataURL2File(dataURL, filename) { +function dataURL2File(dataURL, fileName){ const arr = dataURL.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), @@ -30,23 +28,8 @@ function dataURL2File(dataURL, filename) { while (n--) { u8arr[n] = bstr.charCodeAt(n); } - return new File([u8arr], filename, { type: mime }); -} - -// 方案2: 将base64转换成blob,再将blob转换成file文件 -function dataURL2Blob(dataURL) { - const arr = dataURL.split(','), - mime = arr[0].match(/:(.*?);/)[1], - bstr = atob(arr[1]), - u8arr = new Uint8Array(bstr.length); - let n = bstr.length; - while (n--) { - u8arr[n] = bstr.charCodeAt(n); - } - return new Blob([u8arr], { type: mime }); -}; -function dataURL2Blob2File(dataURL, fileName){ - const blob = dataURL2Blob(dataURL); + const blob = new Blob([u8arr], { type: mime }); + // to File blob.lastModifiedDate = new Date(); blob.name = fileName; return blob; @@ -95,9 +78,7 @@ class App extends React.Component { onOk = () => { const data = this.cropperRef.getCroppedCanvas().toDataURL(); - - // const file = dataURL2File(data, 'test.png'); - const file = dataURL2Blob2File(data, 'test.png'); + const file = dataURL2File(data, 'test.png'); // start upload this.uploader.startUpload(file); From 3e8f2d9143e7f62044598252e0b3d3e45d0a7993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=9D=E9=B8=9F?= Date: Thu, 27 Feb 2020 12:00:10 +0800 Subject: [PATCH 26/53] fix(Checkbox): pass value and name to input dom --- src/checkbox/checkbox.jsx | 5 +++++ test/checkbox/index-spec.js | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/checkbox/checkbox.jsx b/src/checkbox/checkbox.jsx index 06e1e1ac73..bd38c5bc59 100644 --- a/src/checkbox/checkbox.jsx +++ b/src/checkbox/checkbox.jsx @@ -180,6 +180,7 @@ class Checkbox extends UIState { onChange(e) { const checked = e.target.checked; const value = this.props.value; + if (this.disabled) { return; } @@ -214,6 +215,8 @@ class Checkbox extends UIState { rtl, isPreview, renderPreview, + value, + name, ...otherProps } = this.props; const checked = !!this.state.checked; @@ -231,6 +234,8 @@ class Checkbox extends UIState { { wrapper.find('input').simulate('change'); assert(onChange.calledOnce); }); + it('should return the passed value', () => { + const onChange = sinon.spy(); + const wrapper = mount(); + wrapper.find('input').simulate('change'); + assert(onChange.getCalls()[0].args[1].target.value === 'banana'); + }); it('should call `onMouseEnter`', () => { const onMouseEnter = sinon.spy(); const wrapper1 = mount(); From 02e63e4ce527f48baa700fd04608d6a5b460f819 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 27 Feb 2020 16:39:38 +0800 Subject: [PATCH 27/53] fix(Card): bad time of warning, close #1612 --- src/card/media.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/card/media.jsx b/src/card/media.jsx index ff22075693..637c8325e9 100644 --- a/src/card/media.jsx +++ b/src/card/media.jsx @@ -48,10 +48,11 @@ class CardMedia extends Component { ...others } = this.props; - warning( - 'children' in others || Boolean(image || src), - 'either `children`, `image` or `src` prop must be specified.' - ); + if (!('children' in others || Boolean(image || src))) { + warning( + 'either `children`, `image` or `src` prop must be specified.' + ); + } const isMediaComponent = MEDIA_COMPONENTS.indexOf(Component) !== -1; const composedStyle = From a1525412e67b1866e81867f43e21125750df731f Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 27 Feb 2020 18:09:57 +0800 Subject: [PATCH 28/53] chore(*): Release-1.19.16 --- CHANGELOG.md | 11 +++++++++++ LATESTLOG.md | 5 +++-- docs/nav/demo/basic.md | 2 +- index.js | 2 +- package.json | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e0472238..d9a5f74c91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Change Log +## [1.19.16](https://github.com/alibaba-fusion/next/compare/1.19.15...1.19.16) (2020-02-27) + + +### Bug Fixes + +* **Card:** bad time of warning, close [#1612](https://github.com/alibaba-fusion/next/issues/1612) ([02e63e4](https://github.com/alibaba-fusion/next/commit/02e63e4)) +* **Checkbox:** pass value and name to input dom ([3e8f2d9](https://github.com/alibaba-fusion/next/commit/3e8f2d9)) + + + + ## [1.19.15](https://github.com/alibaba-fusion/next/compare/1.19.14...1.19.15) (2020-02-24) diff --git a/LATESTLOG.md b/LATESTLOG.md index 2411231f21..5df0e1ea00 100644 --- a/LATESTLOG.md +++ b/LATESTLOG.md @@ -1,10 +1,11 @@ # Latest Log -## [1.19.15](https://github.com/alibaba-fusion/next/compare/1.19.14...1.19.15) (2020-02-24) +## [1.19.16](https://github.com/alibaba-fusion/next/compare/1.19.15...1.19.16) (2020-02-27) ### Bug Fixes -* correct sideEffect path ([9e52828](https://github.com/alibaba-fusion/next/commit/9e52828)) +* **Card:** bad time of warning, close [#1612](https://github.com/alibaba-fusion/next/issues/1612) ([02e63e4](https://github.com/alibaba-fusion/next/commit/02e63e4)) +* **Checkbox:** pass value and name to input dom ([3e8f2d9](https://github.com/alibaba-fusion/next/commit/3e8f2d9)) diff --git a/docs/nav/demo/basic.md b/docs/nav/demo/basic.md index 5f07e80d24..3f333f9a27 100644 --- a/docs/nav/demo/basic.md +++ b/docs/nav/demo/basic.md @@ -26,7 +26,7 @@ const footer = Login in; ReactDOM.render(
` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效 | Object | - | -| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | Object | - | -| help | 自定义提示信息,如不设置,则会根据校验规则自动生成. | ReactNode | - | -| extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面 | ReactNode | - | -| validateState | 校验状态,如不设置,则会根据校验规则自动生成

**可选值**:
'error'(失败)
'success'(成功)
'loading'(校验中)
'warning'(警告) | Enum | - | -| hasFeedback | 配合 validateState 属性使用,是否展示 success/loading 的校验状态图标, 目前只有Input支持 | Boolean | false | -| children | node 或者 function(values) | ReactNode/Function | - | -| fullWidth | 单个 Item 中表单类组件宽度是否是100% | Boolean | - | -| labelAlign | 标签的位置

**可选值**:
'top'(上)
'left'(左)
'inset'(内) | Enum | - | -| labelTextAlign | 标签的左右对齐方式

**可选值**:
'left'(左)
'right'(右) | Enum | - | -| required | [表单校验] 不能为空 | Boolean | - | -| asterisk | required 的星号是否显示 | Boolean | - | -| requiredMessage | required 自定义错误信息 | String | - | -| requiredTrigger | required 自定义触发方式 | String/Array | - | -| min | [表单校验] 最小值 | Number | - | -| max | [表单校验] 最大值 | Number | - | -| minmaxMessage | min/max 自定义错误信息 | String | - | -| minmaxTrigger | min/max 自定义触发方式 | String/Array | - | -| minLength | [表单校验] 字符串最小长度 / 数组最小个数 | Number | - | -| maxLength | [表单校验] 字符串最大长度 / 数组最大个数 | Number | - | -| minmaxLengthMessage | minLength/maxLength 自定义错误信息 | String | - | -| minmaxLengthTrigger | minLength/maxLength 自定义触发方式 | String/Array | - | -| length | [表单校验] 字符串精确长度 / 数组精确个数 | Number | - | -| lengthMessage | length 自定义错误信息 | String | - | -| lengthTrigger | length 自定义触发方式 | String/Array | - | -| pattern | 正则校验 | any | - | -| patternMessage | pattern 自定义错误信息 | String | - | -| patternTrigger | pattern 自定义触发方式 | String/Array | - | -| format | [表单校验] 四种常用的 pattern

**可选值**:
'number', 'email', 'url', 'tel' | Enum | - | -| formatMessage | format 自定义错误信息 | String | - | -| formatTrigger | format 自定义触发方式 | String/Array | - | -| validator | [表单校验] 自定义校验函数

**签名**:
Function() => void | Function | - | -| validatorTrigger | validator 自定义触发方式 | String/Array | - | -| autoValidate | 是否修改数据时自动触发校验 | Boolean | - | -| device | 预设屏幕宽度

**可选值**:
'phone', 'tablet', 'desktop' | Enum | - | -| colSpan | 在响应式布局模式下,表单项占多少列 | Number | - | -| labelWidth | 在响应式布局下,且label在左边时,label的宽度是多少 | String/Number | 100 | -| isPreview | 是否开启预览态 | Boolean | - | -| renderPreview | 预览态模式下渲染的内容

**签名**:
Function(value: any) => void
**参数**:
_value_: {any} 根据包裹的组件的 value 类型而决定 | Function | - | +| 参数 | 说明 | 类型 | 默认值 | +| ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- | +| label | label 标签的文本 | ReactNode | - | +| size | 单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。

**可选值**:
'large', 'small', 'medium' | Enum | - | +| labelCol | label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效 | Object | - | +| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | Object | - | +| help | 自定义提示信息,如不设置,则会根据校验规则自动生成. | ReactNode | - | +| extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面 | ReactNode | - | +| validateState | 校验状态,如不设置,则会根据校验规则自动生成

**可选值**:
'error'(失败)
'success'(成功)
'loading'(校验中)
'warning'(警告) | Enum | - | +| hasFeedback | 配合 validateState 属性使用,是否展示 success/loading 的校验状态图标, 目前只有Input支持 | Boolean | false | +| children | node 或者 function(values) | ReactNode/Function | - | +| fullWidth | 单个 Item 中表单类组件宽度是否是100% | Boolean | - | +| labelAlign | 标签的位置

**可选值**:
'top'(上)
'left'(左)
'inset'(内) | Enum | - | +| labelTextAlign | 标签的左右对齐方式

**可选值**:
'left'(左)
'right'(右) | Enum | - | +| required | [表单校验] 不能为空 | Boolean | - | +| asterisk | required 的星号是否显示 | Boolean | - | +| requiredMessage | required 自定义错误信息 | String | - | +| requiredTrigger | required 自定义触发方式 | String/Array | - | +| min | [表单校验] 最小值 | Number | - | +| max | [表单校验] 最大值 | Number | - | +| minmaxMessage | min/max 自定义错误信息 | String | - | +| minmaxTrigger | min/max 自定义触发方式 | String/Array | - | +| minLength | [表单校验] 字符串最小长度 / 数组最小个数 | Number | - | +| maxLength | [表单校验] 字符串最大长度 / 数组最大个数 | Number | - | +| minmaxLengthMessage | minLength/maxLength 自定义错误信息 | String | - | +| minmaxLengthTrigger | minLength/maxLength 自定义触发方式 | String/Array | - | +| length | [表单校验] 字符串精确长度 / 数组精确个数 | Number | - | +| lengthMessage | length 自定义错误信息 | String | - | +| lengthTrigger | length 自定义触发方式 | String/Array | - | +| pattern | 正则校验 | any | - | +| patternMessage | pattern 自定义错误信息 | String | - | +| patternTrigger | pattern 自定义触发方式 | String/Array | - | +| format | [表单校验] 四种常用的 pattern

**可选值**:
'number', 'email', 'url', 'tel' | Enum | - | +| formatMessage | format 自定义错误信息 | String | - | +| formatTrigger | format 自定义触发方式 | String/Array | - | +| validator | [表单校验] 自定义校验函数

**签名**:
Function() => void | Function | - | +| validatorTrigger | validator 自定义触发方式 | String/Array | - | +| autoValidate | 是否修改数据时自动触发校验 | Boolean | - | +| device | 预设屏幕宽度

**可选值**:
'phone', 'tablet', 'desktop' | Enum | - | +| colSpan | 在响应式布局模式下,表单项占多少列 | Number | - | +| labelWidth | 在响应式布局下,且label在左边时,label的宽度是多少 | String/Number | 100 | +| isPreview | 是否开启预览态 | Boolean | - | +| renderPreview | 预览态模式下渲染的内容

**签名**:
Function(value: any) => void
**参数**:
_value_: {any} 根据包裹的组件的 value 类型而决定 | Function | - | +| useLabelForErrorMessage | 是否使用 label 替换校验信息的 name 字段 | Boolean | - | ### Form.Submit diff --git a/docs/menu/index.md b/docs/menu/index.md index 09839e85c0..d004851218 100644 --- a/docs/menu/index.md +++ b/docs/menu/index.md @@ -43,6 +43,7 @@ | autoFocus | 是否自动获得焦点 | Boolean | false | | focusedKey | 当前获得焦点的子菜单或菜单项 key 值 | String | - | | embeddable | 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合`` 自定义高度 | Boolean | false | +| icons | 可配置的icons,包括 select 等 | Object | {} | ### Menu.Item diff --git a/docs/number-picker/index.md b/docs/number-picker/index.md index 62d0727af0..b52a02a9d4 100644 --- a/docs/number-picker/index.md +++ b/docs/number-picker/index.md @@ -28,32 +28,32 @@ ### NumberPicker -| 参数 | 说明 | 类型 | 默认值 | -| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------- | -| size | 大小

**可选值**:
'large', 'medium' | Enum | 'medium' | -| type | 设置类型

**可选值**:
'normal'(普通)
'inline'(内联) | Enum | 'normal' | -| value | 当前值 | Number | - | -| defaultValue | 默认值 | Number | - | -| disabled | 是否禁用 | Boolean | - | -| step | 步长 | Number/String | 1 | -| precision | 保留小数点后位数 | Number | 0 | -| editable | 用户是否可以输入 | Boolean | true | -| autoFocus | 自动焦点 | Boolean | - | -| onChange | 数值被改变的事件

**签名**:
Function(value: Number, e: Event) => void
**参数**:
_value_: {Number} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | -| onKeyDown | 键盘按下

**签名**:
Function() => void | Function | func.noop | -| onFocus | 焦点获得

**签名**:
Function() => void | Function | - | -| onBlur | 焦点失去

**签名**:
Function() => void | Function | func.noop | -| onCorrect | 数值订正后的回调

**签名**:
Function(obj: Object) => void
**参数**:
_obj_: {Object} {currentValue,oldValue:String} | Function | func.noop | -| max | 最大值 | Number | Infinity | -| min | 最小值 | Number | -Infinity | -| format | 格式化当前值

**签名**:
Function(value: Number) => String/Number
**参数**:
_value_: {Number} null
**返回值**:
{String/Number} null
| Function | - | -| upBtnProps | 增加按钮的props | Object | - | -| downBtnProps | 减少按钮的props | Object | - | -| label | 内联 label | ReactNode | - | -| innerAfter | inner after | ReactNode | - | -| isPreview | 是否为预览态 | Boolean | - | -| renderPreview | 预览态模式下渲染的内容

**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | -| device | 预设屏幕宽度

**可选值**:
'phone', 'tablet', 'desktop' | Enum | - | +| 参数 | 说明 | 类型 | 默认值 | +| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------- | +| size | 大小

**可选值**:
'large', 'medium' | Enum | 'medium' | +| type | 设置类型

**可选值**:
'normal'(普通)
'inline'(内联) | Enum | 'normal' | +| value | 当前值 | Number | - | +| defaultValue | 默认值 | Number | - | +| disabled | 是否禁用 | Boolean | - | +| step | 步长 | Number/String | 1 | +| precision | 保留小数点后位数 | Number | 0 | +| editable | 用户是否可以输入 | Boolean | true | +| autoFocus | 自动焦点 | Boolean | - | +| onChange | 数值被改变的事件

**签名**:
Function(value: Number, e: Event) => void
**参数**:
_value_: {Number} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | +| onKeyDown | 键盘按下

**签名**:
Function() => void | Function | func.noop | +| onFocus | 焦点获得

**签名**:
Function() => void | Function | - | +| onBlur | 焦点失去

**签名**:
Function() => void | Function | func.noop | +| onCorrect | 数值订正后的回调

**签名**:
Function(obj: Object) => void
**参数**:
_obj_: {Object} {currentValue,oldValue:String} | Function | func.noop | +| max | 最大值 | Number | Infinity | +| min | 最小值 | Number | -Infinity | +| format | 格式化当前值

**签名**:
Function(value: Number) => String/Number
**参数**:
_value_: {Number} null
**返回值**:
{String/Number} null
| Function | - | +| upBtnProps | 增加按钮的props | Object | - | +| downBtnProps | 减少按钮的props | Object | - | +| label | 内联 label | ReactNode | - | +| innerAfter | inner after | ReactNode | - | +| isPreview | 是否为预览态 | Boolean | - | +| renderPreview | 预览态模式下渲染的内容

**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | +| device | 预设屏幕宽度

**可选值**:
'phone', 'tablet', 'desktop' | Enum | - | | hasTrigger | 是否展示点击按钮 | Boolean | true | | alwaysShowTrigger | 是否一直显示点击按钮(无须hover) | Boolean | false | diff --git a/docs/search/index.md b/docs/search/index.md index 7f97eee627..0500e0d913 100644 --- a/docs/search/index.md +++ b/docs/search/index.md @@ -44,6 +44,7 @@ | hasClear | 是否显示清除按钮 | Boolean | false | | hasIcon | 是否显示搜索按钮 | Boolean | true | | disabled | 是否禁用 | Boolean | false | +| icons | 可配置的icons,包括 search 等 | Object | {} | ## ARIA and KeyBoard diff --git a/docs/tab/index.en-us.md b/docs/tab/index.en-us.md index 7a741afe62..96712c9314 100644 --- a/docs/tab/index.en-us.md +++ b/docs/tab/index.en-us.md @@ -41,6 +41,7 @@ Disable animation with `animation={false}` | onClose | Callback when close the tab

**signature**:
Function(key: String/Number)) => void
**parameter**:
_key_: {String/Number)} theClosedKey | Function | () => {} | | tabRender | Custom template render for tab

**signature**:
Function(key: String, props: Object) => ReactNode
**parameter**:
_key_: {String} tabKey
_props_: {Object} propsOfTabItem
**return**:
{ReactNode} the rendered tab item
| Function | - | | popupProps | properties pass down to Popup Menu in dropdown excess mode | Object | - | +| icons | customize icons used in tab nav | Object | {} | ### Tab.Item @@ -55,4 +56,4 @@ Disable animation with `animation={false}` | KeyBoard | Descripiton | | :---------- | :------------------------------ | | Right Arrow | switch to previous Tab.Item | -| Left Arrow | switch to next Tab.Item | \ No newline at end of file +| Left Arrow | switch to next Tab.Item | diff --git a/docs/tab/index.md b/docs/tab/index.md index 9ececcffbb..ea1a5d95bc 100644 --- a/docs/tab/index.md +++ b/docs/tab/index.md @@ -53,6 +53,7 @@ Fusion 提供了三级选项卡,分别用于不同的场景。 | onClose | 选项卡被关闭时的事件回调

**签名**:
Function(key: String/Number) => void
**参数**:
_key_: {String/Number} 关闭的选项卡的 key | Function | () => {} | | tabRender | 自定义选项卡模板渲染函数

**签名**:
Function(key: String, props: Object) => ReactNode
**参数**:
_key_: {String} 当前 Tab.Item 的 key 值
_props_: {Object} 传给 Tab.Item 的所有属性键值对
**返回值**:
{ReactNode} 返回自定义组件
| Function | - | | popupProps | 弹层属性透传, 只有当 excessMode 为 dropdown 时生效 | Object | - | +| icons | 自定义组件内 icon | Object | {} | ### Tab.Item diff --git a/src/tab/main.scss b/src/tab/main.scss index 6095d72308..c3dae34ada 100644 --- a/src/tab/main.scss +++ b/src/tab/main.scss @@ -147,6 +147,18 @@ right: $tab-nav-arrow-down-positon-right; } + & .#{$css-prefix}tab-icon-dropdown::before { + content: $tab-icon-dropdown-content; + } + + & .#{$css-prefix}tab-icon-prev::before { + content: $tab-icon-prev-content; + } + + & .#{$css-prefix}tab-icon-next::before { + content: $tab-icon-next-content; + } + &-content { overflow: hidden; } diff --git a/src/tab/scss/variable.scss b/src/tab/scss/variable.scss index 35625a3cac..cfafd83826 100644 --- a/src/tab/scss/variable.scss +++ b/src/tab/scss/variable.scss @@ -395,3 +395,15 @@ $tab-text-text-color-selected: $color-brand1-6 !default; /// text /// @namespace statement/disabled/tab $tab-text-text-color-disabled: $color-text1-1 !default; + +/// icon dropdown +/// @namespace statement/normal/icon +$tab-icon-dropdown-content: $icon-content-arrow-down !default; + +/// icon prev +/// @namespace statement/normal/icon +$tab-icon-prev-content: $icon-content-arrow-left !default; + +/// icon next +/// @namespace statement/normal/icon +$tab-icon-next-content: $icon-content-arrow-right !default; diff --git a/src/tab/tab.jsx b/src/tab/tab.jsx index fec1cbbc2c..22c55f8238 100644 --- a/src/tab/tab.jsx +++ b/src/tab/tab.jsx @@ -106,6 +106,14 @@ export default class Tab extends Component { children: PropTypes.any, className: PropTypes.string, locale: PropTypes.object, + /** + * 自定义组件内 icon + */ + icons: PropTypes.shape({ + prev: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), + next: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), + dropdown: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), + }), }; static defaultProps = { @@ -122,6 +130,7 @@ export default class Tab extends Component { onChange: noop, onClose: noop, locale: zhCN.Tab, + icons: {}, }; constructor(props, context) { @@ -252,6 +261,7 @@ export default class Tab extends Component { rtl, device, locale, + icons, ...others } = this.props; const { activeKey } = this.state; @@ -294,6 +304,7 @@ export default class Tab extends Component { style: navStyle, className: navClassName, locale, + icons, }; const contentProps = { diff --git a/src/tab/tabs/nav.jsx b/src/tab/tabs/nav.jsx index ea9bb17c54..8f8a8eaed8 100644 --- a/src/tab/tabs/nav.jsx +++ b/src/tab/tabs/nav.jsx @@ -16,6 +16,11 @@ import { const floatRight = { float: 'right', zIndex: 1 }; const floatLeft = { float: 'left', zIndex: 1 }; +const iconTypeMap = { + dropdown: 'arrow-down', + prev: 'arrow-left', + next: 'arrow-right', +}; const { Popup } = Overlay; class Nav extends React.Component { @@ -37,6 +42,7 @@ class Nav extends React.Component { style: PropTypes.object, className: PropTypes.string, locale: PropTypes.object, + icons: PropTypes.object, }; constructor(props, context) { @@ -322,7 +328,6 @@ class Nav extends React.Component { renderTabList(props) { const { prefix, tabs, activeKey, tabRender } = props; const tabTemplateFn = tabRender || this.defaultTabTemplateRender; - const { locale } = this.props; const rst = []; React.Children.forEach(tabs, child => { @@ -453,16 +458,38 @@ class Nav extends React.Component { }, 100); }; + getIcon(type) { + const { prefix, icons, rtl } = this.props; + const iconType = iconTypeMap[type]; + let icon = ( + + ); + if (icons[type]) { + icon = + typeof icons[type] === 'string' ? ( + + ) : ( + icons[type] + ); + } + + return icon; + } + renderDropdownTabs(tabs = []) { if (!tabs.length) { return null; } const { prefix, activeKey, triggerType, popupProps, rtl } = this.props; + const dropdownIcon = this.getIcon('dropdown'); + const trigger = ( - + ); return ( @@ -571,23 +598,25 @@ class Nav extends React.Component { prevButton = null; nextButton = null; } else if (showNextPrev) { + const prevIcon = this.getIcon('prev'); prevButton = ( ); + const nextIcon = this.getIcon('next'); nextButton = ( ); restButton = null; diff --git a/types/tab/index.d.ts b/types/tab/index.d.ts index 3effb2c8a8..046854a09d 100644 --- a/types/tab/index.d.ts +++ b/types/tab/index.d.ts @@ -130,6 +130,15 @@ export interface TabProps extends HTMLAttributesWeak, CommonProps { * 弹层属性透传, 只有当 excessMode 为 dropdown 时生效 */ popupProps?: {}; + + /** + * 自定义 icon + */ + icons?: { + dropdown?: string | React.ReactNode; + prev?: string | React.ReactNode; + next?: string | React.ReactNode; + } } export default class Tab extends React.Component { From 3101978c297a11c3437356a4b51d1463f0e18cae Mon Sep 17 00:00:00 2001 From: haoxutong Date: Wed, 4 Mar 2020 20:40:49 +0800 Subject: [PATCH 35/53] feat(Locale): add language zh-hk * feat(Locale): Add zh-hk language support Co-authored-by: aboutblank --- docs/config-provider/index.en-us.md | 1 + docs/config-provider/index.md | 1 + index-with-locales.js | 1 + scripts/build/export-api-schema.js | 2 +- scripts/init-options.js | 1 + site/en-us/i18n.md | 1 + site/zh-cn/i18n.md | 2 + src/locale/zh-hk.js | 138 ++++++++++++++++++++++++++++ test/locale/index-spec.js | 4 +- types/locale/zh-hk.d.ts | 1 + 10 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 src/locale/zh-hk.js create mode 100644 types/locale/zh-hk.d.ts diff --git a/docs/config-provider/index.en-us.md b/docs/config-provider/index.en-us.md index efdf1309c8..141468a825 100644 --- a/docs/config-provider/index.en-us.md +++ b/docs/config-provider/index.en-us.md @@ -27,6 +27,7 @@ Now support four languages: Simplified Chinese, Traditional Chinese, English and import { ConfigProvider, DatePicker } from '@alifd/next'; import enUS from '@alifd/next/lib/locale/en-us'; // import zhCN from '@alifd/next/lib/locale/zh-cn'; +// import zhHK from '@alifd/next/lib/locale/zh-hk'; // import zhTW from '@alifd/next/lib/locale/zh-tw'; // import jaJP from '@alifd/next/lib/locale/ja-jp'; diff --git a/docs/config-provider/index.md b/docs/config-provider/index.md index 686d283de6..71e15bb611 100644 --- a/docs/config-provider/index.md +++ b/docs/config-provider/index.md @@ -94,6 +94,7 @@ class App extends React.Component { import { ConfigProvider, DatePicker } from '@alifd/next'; import enUS from '@alifd/next/lib/locale/en-us'; // import zhCN from '@alifd/next/lib/locale/zh-cn'; +// import zhHK from '@alifd/next/lib/locale/zh-hk'; // import zhTW from '@alifd/next/lib/locale/zh-tw'; // import jaJP from '@alifd/next/lib/locale/ja-jp'; diff --git a/index-with-locales.js b/index-with-locales.js index eb103be960..b86117831f 100644 --- a/index-with-locales.js +++ b/index-with-locales.js @@ -4,6 +4,7 @@ next.locales = {}; next.locales['en-us'] = require('./lib/locale/en-us.js'); next.locales['ja-ja'] = require('./lib/locale/ja-jp.js'); next.locales['zh-cn'] = require('./lib/locale/zh-cn.js'); +next.locales['zh-hk'] = require('./lib/locale/zh-hk.js'); next.locales['zh-tw'] = require('./lib/locale/zh-tw.js'); module.exports = next; diff --git a/scripts/build/export-api-schema.js b/scripts/build/export-api-schema.js index 164e1548de..ff0c8d9f0e 100644 --- a/scripts/build/export-api-schema.js +++ b/scripts/build/export-api-schema.js @@ -95,7 +95,7 @@ export default ${exportName}; }); // generate d.ts for locale - ['zh-cn', 'en-us', 'ja-jp', 'zh-tw'].forEach(file => { + ['zh-cn', 'en-us', 'ja-jp', 'zh-hk', 'zh-tw'].forEach(file => { const localePath = path.join(cwd, 'lib', 'locale', `${file}.d.ts`); fs.writeFileSync( localePath, diff --git a/scripts/init-options.js b/scripts/init-options.js index eaf46d8f15..e03e6dbe55 100644 --- a/scripts/init-options.js +++ b/scripts/init-options.js @@ -80,6 +80,7 @@ const options = { 'lib/en-us.js', 'lib/ja-jp.js', 'lib/zh-cn.js', + 'lib/zh-hk.js', 'lib/zh-tw.js', ], }, diff --git a/site/en-us/i18n.md b/site/en-us/i18n.md index f0e02b1f1d..ffa198222d 100644 --- a/site/en-us/i18n.md +++ b/site/en-us/i18n.md @@ -10,6 +10,7 @@ Currently support Simplified Chinese, Traditional Chinese, English and Japanese: import { ConfigProvider, DatePicker } from '@alifd/next'; import enUS from '@alifd/next/lib/locale/en-us'; // import zhCN from '@alifd/next/lib/locale/zh-cn'; +// import zhHK from '@alifd/next/lib/locale/zh-hk'; // import zhTW from '@alifd/next/lib/locale/zh-tw'; // import jaJP from '@alifd/next/lib/locale/ja-jp'; diff --git a/site/zh-cn/i18n.md b/site/zh-cn/i18n.md index a1932d3712..3b03e5ef73 100644 --- a/site/zh-cn/i18n.md +++ b/site/zh-cn/i18n.md @@ -7,6 +7,7 @@ | 语言名称 | 文件名 | | -------- | -------- | | 简体中文 | zh-cn | +| 繁体中文(香港) | zh-hk | | 繁体中文 | zh-tw | | 美式英语 | en-us | | 日文 | ja-jp | @@ -83,6 +84,7 @@ class App extends React.Component { import { ConfigProvider, DatePicker } from '@alifd/next'; import enUS from '@alifd/next/lib/locale/en-us'; // import zhCN from '@alifd/next/lib/locale/zh-cn'; +// import zhHK from '@alifd/next/lib/locale/zh-hk'; // import zhTW from '@alifd/next/lib/locale/zh-tw'; // import jaJP from '@alifd/next/lib/locale/ja-jp'; diff --git a/src/locale/zh-hk.js b/src/locale/zh-hk.js new file mode 100644 index 0000000000..1da35ada39 --- /dev/null +++ b/src/locale/zh-hk.js @@ -0,0 +1,138 @@ +export default { + momentLocale: 'zh-hk', + Timeline: { + expand: '展開', + fold: '收起', + }, + Balloon: { + close: '關閉', + }, + Card: { + expand: '展開', + fold: '收起', + }, + Calendar: { + today: '今天', + now: '此刻', + ok: '確定', + clear: '清除', + month: '月', + year: '年', + prevYear: '上一年', + nextYear: '下一年', + prevMonth: '上個月', + nextMonth: '下個月', + prevDecade: '上十年', + nextDecade: '後十年', + yearSelectAriaLabel: '選擇年份', + monthSelectAriaLabel: '選擇月份', + }, + DatePicker: { + placeholder: '請選擇日期', + datetimePlaceholder: '請選擇日期和時間', + monthPlaceholder: '請選擇月', + yearPlaceholder: '請選擇年', + weekPlaceholder: '請選擇周', + now: '此刻', + selectTime: '選擇時間', + selectDate: '選擇日期', + ok: '確定', + clear: '清除', + startPlaceholder: '起始日期', + endPlaceholder: '結束日期', + hour: '時', + minute: '分', + second: '秒', + }, + Dialog: { + close: '關閉', + ok: '確認', + cancel: '取消', + }, + Drawer: { + close: '關閉', + }, + Message: { + closeAriaLabel: '關閉', + }, + Pagination: { + prev: '上一頁', + next: '下一頁', + goTo: '到第', + page: '頁', + go: '確定', + total: '第{current}頁,共{total}頁', + labelPrev: '上一頁,當前第{current}頁', + labelNext: '下一頁,當前第{current}頁', + inputAriaLabel: '請輸入跳轉到第幾頁', + selectAriaLabel: '請選擇每頁顯示幾條', + pageSize: '每頁顯示:', + }, + Input: { + clear: '清除', + }, + Select: { + selectPlaceholder: '請選擇', + autoCompletePlaceholder: '請輸入', + notFoundContent: '無選項', + maxTagPlaceholder: '已選擇 {selected}/{total} 項', + selectAll: '全選', + }, + Table: { + empty: '沒有數據', + ok: '確認', + reset: '重置', + asc: '升序', + desc: '降序', + expanded: '已展開', + folded: '已摺疊', + filter: '篩選', + selectAll: '全選', + }, + TimePicker: { + placeholder: '請選擇時間', + clear: '清除', + hour: '時', + minute: '分', + second: '秒', + }, + Transfer: { + items: '項', + item: '項', + moveAll: '移動全部', + searchPlaceholder: '請輸入', + moveToLeft: '撤銷選中元素', + moveToRight: '提交選中元素', + }, + Upload: { + card: { + cancel: '取消', + addPhoto: '上傳圖片', + download: '下載', + delete: '刪除', + }, + drag: { + text: '點擊或者拖動文件到虛線框內上傳', + hint: '支持 docx, xls, PDF, rar, zip, PNG, JPG 等類型的文件', + }, + upload: { + delete: '刪除', + }, + }, + Search: { + buttonText: '檢索', + }, + Tag: { + delete: '删除', + }, + Rating: { + description: '評分選項', + }, + Switch: { + on: '已打開', + off: '已關閉', + }, + Tab: { + closeAriaLabel: '關閉', + }, +}; diff --git a/test/locale/index-spec.js b/test/locale/index-spec.js index 394b587d61..5825a5c27f 100644 --- a/test/locale/index-spec.js +++ b/test/locale/index-spec.js @@ -3,6 +3,7 @@ import assert from 'power-assert'; import US from '../../src/locale/en-us'; import JP from '../../src/locale/ja-jp'; import CN from '../../src/locale/zh-cn'; +import HK from '../../src/locale/zh-hk'; import TW from '../../src/locale/zh-tw'; describe('Locale', () => { @@ -10,9 +11,10 @@ describe('Locale', () => { const usKeys = getKeys(US); const jpKeys = getKeys(JP); const cnKeys = getKeys(CN); + const hkKeys = getKeys(HK); const twKeys = getKeys(TW); - assert(usKeys === jpKeys && jpKeys === cnKeys && cnKeys === twKeys); + assert(usKeys === jpKeys && jpKeys === cnKeys && cnKeys === hkKeys && hkKeys === twKeys); }); }); diff --git a/types/locale/zh-hk.d.ts b/types/locale/zh-hk.d.ts new file mode 100644 index 0000000000..acced897e5 --- /dev/null +++ b/types/locale/zh-hk.d.ts @@ -0,0 +1 @@ +export * from './default'; From 08596b103500a14ec00cfa0aca9a9fe20383230c Mon Sep 17 00:00:00 2001 From: frankqian Date: Wed, 4 Mar 2020 20:45:37 +0800 Subject: [PATCH 36/53] feat(Input/upload): support icon config for #1256 (#1625) * feat(Input): support icon config for #1256 * feat(Upload): support icon config for #1256 * feat(NumberPicker): support icon config for #1256 add type incase of using old verison of theme Co-authored-by: aboutblank --- src/input/input.jsx | 10 +++--- src/input/main.scss | 27 +++++++++++++--- src/input/scss/variable.scss | 48 ++++++++++++++++++---------- src/number-picker/main.scss | 14 ++++++++ src/number-picker/number-picker.jsx | 8 ++--- src/number-picker/scss/variable.scss | 19 +++++++++-- src/upload/main.scss | 5 +-- src/upload/scss/variable.scss | 6 +++- src/upload/upload.jsx | 2 +- test/date-picker/index-spec.js | 34 ++++++++++---------- test/input/index-spec.js | 6 ++-- 11 files changed, 122 insertions(+), 57 deletions(-) diff --git a/src/input/input.jsx b/src/input/input.jsx index 4e8459097c..46a8b7fe54 100644 --- a/src/input/input.jsx +++ b/src/input/input.jsx @@ -151,11 +151,11 @@ export default class Input extends Base { let stateWrap = null; if (state === 'success') { - stateWrap = ; + stateWrap = ; } else if (state === 'loading') { - stateWrap = ; + stateWrap = ; } else if (state === 'warning') { - stateWrap = ; + stateWrap = ; } let clearWrap = null; @@ -173,7 +173,7 @@ export default class Input extends Base { type="delete-filling" role="button" tabIndex="0" - className={`${prefix}input-hint`} + className={`${prefix}input-hint ${prefix}input-clear-icon`} aria-label={locale.clear} onClick={this.onClear.bind(this)} onMouseDown={preventDefault} @@ -189,7 +189,7 @@ export default class Input extends Base { type="delete-filling" role="button" tabIndex="0" - className={`${prefix}input-clear`} + className={`${prefix}input-clear ${prefix}input-clear-icon`} aria-label={locale.clear} onClick={this.onClear.bind(this)} onMouseDown={preventDefault} diff --git a/src/input/main.scss b/src/input/main.scss index 559561bfff..2b47d7dcbb 100644 --- a/src/input/main.scss +++ b/src/input/main.scss @@ -115,7 +115,9 @@ } } - .#{$css-prefix}icon-delete-filling, .#{$css-prefix}icon-eye, .#{$css-prefix}icon-eye-close { + + + #{$input-prefix}-clear-icon, .#{$css-prefix}icon-eye, .#{$css-prefix}icon-eye-close { &:hover { cursor: pointer; color: $input-hint-hover-color; @@ -218,14 +220,29 @@ color: $input-hint-color; } - .#{$css-prefix}icon-warning { + #{$input-prefix}-warning-icon { color: $input-feedback-warning-color; + &::before { + content: $input-feedback-warning-icon; + } } - .#{$css-prefix}icon-success-filling { + #{$input-prefix}-success-icon { color: $input-feedback-success-color; + &::before { + content: $input-feedback-success-icon; + } } - .#{$css-prefix}icon-loading { + #{$input-prefix}-loading-icon { color: $input-feedback-loading-color; + &::before { + content: $input-feedback-loading-icon; + animation: loadingCircle 1s infinite linear; + } + } + #{$input-prefix}-clear-icon { + &::before { + content: $input-feedback-clear-icon; + } } } @@ -268,7 +285,7 @@ color: $input-disabled-color; - .#{$css-prefix}icon-delete-filling:hover { + #{$input-prefix}-clear-icon:hover { cursor: not-allowed; color: $input-disabled-color; } diff --git a/src/input/scss/variable.scss b/src/input/scss/variable.scss index 4a784ceeac..11bb31a090 100644 --- a/src/input/scss/variable.scss +++ b/src/input/scss/variable.scss @@ -7,7 +7,7 @@ /// @family data-entry /// @varPrefix $input- /// @classPrefix {prefix}-input -/// @order {"statement/normal":10,"statement/normal/addon":100,"statement/normal/feedback":101,"statement/normal/maxlen":102,"statement/normal/clear":103,"statement/hover":11,"statement/hover/clear":110,"statement/focus":12,"statement/disabled":13,"statement/error":14,"size/bounding":10,"size/bounding/addon":100,"size/label":11,"size/maxlen":12} +/// @order {"statement/normal":10,"statement/normal/addon":100,"statement/normal/warning":101,"statement/normal/success":102,"statement/normal/loading":103,"statement/normal/maxlen":104,"statement/normal/clear":105,"statement/hover":11,"statement/hover/clear":110,"statement/focus":12,"statement/disabled":13,"statement/error":14,"size/bounding":10,"size/bounding/addon":100,"size/label":11,"size/maxlen":12} //// $input-prefix: '.#{$css-prefix}input'; @@ -153,16 +153,34 @@ $input-s-icon-padding-right: $s-1 !default; // feedback // -------------------------------------------------- -/// warning -/// @namespace statement/normal/feedback +/// border +/// @namespace statement/normal/warning +$input-feedback-warning-border-color: $color-warning-3 !default; +$color-calculate-input-feedback-warning-shadow: rgba($input-feedback-warning-border-color, .2); +/// background +/// @namespace statement/normal/warning +$input-feedback-warning-bg-color: $color-white !default; +/// icon color +/// @namespace statement/normal/warning $input-feedback-warning-color: $color-warning-3 !default; -/// success -/// @namespace statement/normal/feedback +/// icon +/// @namespace statement/normal/warning +/// @type icon +$input-feedback-warning-icon: $icon-content-warning !default; +/// icon color +/// @namespace statement/normal/success $input-feedback-success-color: $color-success-3 !default; - -/// loading -/// @namespace statement/normal/feedback +/// icon +/// @namespace statement/normal/success +/// @type icon +$input-feedback-success-icon: $icon-content-success-filling !default; +/// icon color +/// @namespace statement/normal/loading $input-feedback-loading-color: $color-notice-3 !default; +/// icon +/// @namespace statement/normal/loading +/// @type icon +$input-feedback-loading-icon: $icon-content-loading !default; /// border /// @namespace statement/error @@ -173,15 +191,6 @@ $color-calculate-input-feedback-error-shadow: rgba($input-feedback-error-border- /// @namespace statement/error $input-feedback-error-bg-color: $color-white !default; -/// border -/// @namespace statement/warning -$input-feedback-warning-border-color: $color-warning-3 !default; -$color-calculate-input-feedback-warning-shadow: rgba($input-feedback-warning-border-color, .2); - -/// background -/// @namespace statement/warning -$input-feedback-warning-bg-color: $color-white !default; - // maxlen // -------------------------------------------------- @@ -211,3 +220,8 @@ $input-hint-color: $color-text1-2 !default; /// background /// @namespace statement/hover/clear $input-hint-hover-color: $color-text1-3 !default; + +/// clear icon +/// @namespace statement/normal/clear +/// @type icon +$input-feedback-clear-icon: $icon-content-delete-filling !default; diff --git a/src/number-picker/main.scss b/src/number-picker/main.scss index 8bdd9159f8..fb2f039c0d 100644 --- a/src/number-picker/main.scss +++ b/src/number-picker/main.scss @@ -73,6 +73,13 @@ opacity: 0; } + #{$number-picker-prefix}-up-icon::before { + content: $number-picker-normal-up-icon; + } + #{$number-picker-prefix}-down-icon::before { + content: $number-picker-normal-down-icon; + } + &.#{$css-prefix}small { width: 68px; .#{$css-prefix}btn { @@ -140,6 +147,13 @@ padding: 0; } + #{$number-picker-prefix}-add-icon::before { + content: $number-picker-inline-add-icon; + } + #{$number-picker-prefix}-minus-icon::before { + content: $number-picker-inline-minus-icon; + } + &.#{$css-prefix}small { width: 68px; min-width: $form-element-small-height * 3; diff --git a/src/number-picker/number-picker.jsx b/src/number-picker/number-picker.jsx index 60d11eb48c..7ea4c337ba 100644 --- a/src/number-picker/number-picker.jsx +++ b/src/number-picker/number-picker.jsx @@ -529,7 +529,7 @@ class NumberPicker extends React.Component { }`} onClick={this.up.bind(this, upDisabled)} > - + ); @@ -555,7 +555,7 @@ class NumberPicker extends React.Component { }`} onClick={this.down.bind(this, downDisabled)} > - + ); addonAfter = ( @@ -568,7 +568,7 @@ class NumberPicker extends React.Component { }`} onClick={this.up.bind(this, upDisabled)} > - + ); } diff --git a/src/number-picker/scss/variable.scss b/src/number-picker/scss/variable.scss index 3a7d3bcf8f..258d8548e7 100644 --- a/src/number-picker/scss/variable.scss +++ b/src/number-picker/scss/variable.scss @@ -15,6 +15,14 @@ $number-picker-prefix: '.#{$css-prefix}number-picker'; // Normal // -------------------------------------------------- +/// up icon +/// @namespace statement/normal +/// @type icon +$number-picker-normal-up-icon: $icon-content-arrow-up !default; +/// down icon +/// @namespace statement/normal +/// @type icon +$number-picker-normal-down-icon: $icon-content-arrow-down !default; /// width /// @namespace size/button $number-picker-normal-s-button-width: $s-5 !default; @@ -46,8 +54,15 @@ $number-picker-normal-l-button-icon-size: $icon-xxs !default; // inline // -------------------------------------------------- - -/// icon +/// add icon +/// @namespace statement/normal +/// @type icon +$number-picker-inline-add-icon: $icon-content-add !default; +/// minus icon +/// @namespace statement/normal +/// @type icon +$number-picker-inline-minus-icon: $icon-content-minus !default; +/// icon size /// @namespace size/button $number-picker-inline-s-button-icon-size: $icon-xs !default; /// margin diff --git a/src/upload/main.scss b/src/upload/main.scss index 22d06d859b..5e032c0971 100644 --- a/src/upload/main.scss +++ b/src/upload/main.scss @@ -434,6 +434,9 @@ .#{$css-prefix}icon { color: $upload-card-icon-color; + &::before { + content: $upload-card-add-icon; + } @include icon-size($upload-card-add-icon-size); } @@ -479,8 +482,6 @@ } } - - &-text { margin: $s-3 0 0; font-size: $upload-drag-zone-font-size; diff --git a/src/upload/scss/variable.scss b/src/upload/scss/variable.scss index 766362924d..fbd97c9815 100644 --- a/src/upload/scss/variable.scss +++ b/src/upload/scss/variable.scss @@ -192,6 +192,10 @@ $upload-card-icon-color: $color-line1-3 !default; /// text /// @namespace statement/hover/add $upload-card-hover-font-color: $color-brand1-6 !default; +/// icon +/// @namespace statement/normal/add +/// @type icon +$upload-card-add-icon: $icon-content-add !default; // Card Item /// background @@ -284,7 +288,7 @@ $upload-drag-zone-bg-color: $color-transparent !default; /// @type icon /// @namespace statement/normal $upload-drag-zone-upload-icon: $icon-content-upload !default; -/// icon-color +/// icon color /// @namespace statement/normal $upload-drag-zone-upload-icon-color: $color-text1-3 !default; /// title diff --git a/src/upload/upload.jsx b/src/upload/upload.jsx index 4b27c4b0d8..d9322669d4 100644 --- a/src/upload/upload.jsx +++ b/src/upload/upload.jsx @@ -499,7 +499,7 @@ class Upload extends Base { }); children = (
- +
{ wrapper.find('.next-date-picker-input input').instance() .value === '2017-11-20' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should set hasClear to false', () => { wrapper = mount( ); - assert(!wrapper.find('.next-icon-delete-filling').length); + assert(!wrapper.find('i.next-input-clear-icon').length); }); it('should render controlled value of DatePicker', () => { @@ -124,7 +124,7 @@ describe('DatePicker', () => { onChange={val => (ret = val)} /> ); - wrapper.find('.next-icon-delete-filling').simulate('click'); + wrapper.find('i.next-input-clear-icon').simulate('click'); assert(ret === null); }); @@ -361,7 +361,7 @@ describe('DatePicker', () => { wrapper.find('.next-date-picker-input input').instance() .value === '2018-01-23' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should value as string', () => { @@ -418,14 +418,14 @@ describe('YearPicker', () => { wrapper.find('.next-year-picker-input input').instance() .value === '2018' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should set hasClear to false', () => { wrapper = mount( ); - assert(!wrapper.find('.next-icon-delete-filling').length); + assert(!wrapper.find('i.next-input-clear-icon').length); }); it('should render controlled value of YearPicker', () => { @@ -487,7 +487,7 @@ describe('YearPicker', () => { onChange={val => (ret = val)} /> ); - wrapper.find('.next-icon-delete-filling').simulate('click'); + wrapper.find('i.next-input-clear-icon').simulate('click'); assert(ret === null); }); @@ -580,7 +580,7 @@ describe('YearPicker', () => { wrapper.find('.next-year-picker-input input').instance() .value === '2018' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should value as string', () => { @@ -617,14 +617,14 @@ describe('MonthPicker', () => { wrapper.find('.next-month-picker-input input').instance() .value === '2018-01' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should set hasClear to false', () => { wrapper = mount( ); - assert(!wrapper.find('.next-icon-delete-filling').length); + assert(!wrapper.find('i.next-input-clear-icon').length); }); it('should render controlled value of MonthPicker', () => { @@ -691,7 +691,7 @@ describe('MonthPicker', () => { onChange={val => (ret = val)} /> ); - wrapper.find('.next-icon-delete-filling').simulate('click'); + wrapper.find('i.next-input-clear-icon').simulate('click'); assert(ret === null); }); @@ -792,7 +792,7 @@ describe('MonthPicker', () => { wrapper.find('.next-month-picker-input input').instance() .value === '2018-01' ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should value as string', () => { @@ -827,14 +827,14 @@ describe('WeekPicker', () => { assert( wrapper.find('.next-week-picker-input input').instance().value.indexOf('2018-') !== -1 ); - assert(wrapper.find('.next-icon-delete-filling').length === 1); + assert(wrapper.find('i.next-input-clear-icon').length === 1); }); it('should set hasClear to false', () => { wrapper = mount( ); - assert(!wrapper.find('.next-icon-delete-filling').length); + assert(!wrapper.find('i.next-input-clear-icon').length); }); it('should render controlled value of YearPicker', () => { @@ -894,7 +894,7 @@ describe('WeekPicker', () => { onChange={val => (ret = val)} /> ); - wrapper.find('.next-icon-delete-filling').simulate('click'); + wrapper.find('i.next-input-clear-icon').simulate('click'); assert(ret === null); }); @@ -974,7 +974,7 @@ describe('RangePicker', () => { hasClear={false} /> ); - assert(!wrapper.find('.next-icon-delete-filling').length); + assert(!wrapper.find('i.next-input-clear-icon').length); }); it('should render controlled value of RangePicker', () => { @@ -1202,7 +1202,7 @@ describe('RangePicker', () => { onChange={val => (ret = val)} /> ); - wrapper.find('.next-icon-delete-filling').simulate('click'); + wrapper.find('i.next-input-clear-icon').simulate('click'); assert(!ret[0]); assert(!ret[1]); }); diff --git a/test/input/index-spec.js b/test/input/index-spec.js index 9899b9ab80..95f8ef453f 100644 --- a/test/input/index-spec.js +++ b/test/input/index-spec.js @@ -157,10 +157,10 @@ describe('input', () => { assert(wrapper.find('.next-input').hasClass('next-error')); const wrapper2 = mount(); - assert(wrapper2.find('.next-icon-success-filling').length === 1); + assert(wrapper2.find('i.next-input-success-icon').length === 1); const wrapper3 = mount(); - assert(wrapper3.find('.next-icon-loading').length === 1); + assert(wrapper3.find('i.next-input-loading-icon').length === 1); done(); }); @@ -206,7 +206,7 @@ describe('input', () => { ); assert( - wrapper.find('.next-icon').hasClass('next-icon-delete-filling') + wrapper.find('.next-icon').hasClass('next-input-clear-icon') ); wrapper.find('.next-icon').simulate('click'); assert(wrapper.find('input').prop('value') === ''); From 1bb04953c6e21751856b572f58132a42095c5022 Mon Sep 17 00:00:00 2001 From: xdddi <35244644+xdddi@users.noreply.github.com> Date: Wed, 4 Mar 2020 22:39:37 +0800 Subject: [PATCH 37/53] feat(Calendar): make icons configurable (#1634) * feat(Calendar): make icons configurable Co-authored-by: aboutblank --- src/calendar/head/date-panel-header.jsx | 20 ++++++++++++++++---- src/calendar/head/month-panel-header.jsx | 10 ++++++++-- src/calendar/head/range-panel-header.jsx | 20 ++++++++++++++++---- src/calendar/head/year-panel-header.jsx | 10 ++++++++-- src/calendar/main.scss | 13 +++++++++++++ src/calendar/scss/variable.scss | 16 ++++++++++++++++ 6 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/calendar/head/date-panel-header.jsx b/src/calendar/head/date-panel-header.jsx index 0b122fddea..201fda079c 100644 --- a/src/calendar/head/date-panel-header.jsx +++ b/src/calendar/head/date-panel-header.jsx @@ -135,7 +135,10 @@ class DatePanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-prev-year`} onClick={goPrevYear} > - +
{monthButton} @@ -155,7 +161,10 @@ class DatePanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-next-month`} onClick={goNextMonth} > - +
); diff --git a/src/calendar/head/month-panel-header.jsx b/src/calendar/head/month-panel-header.jsx index 7d534c10c3..380e1cc0d9 100644 --- a/src/calendar/head/month-panel-header.jsx +++ b/src/calendar/head/month-panel-header.jsx @@ -22,7 +22,10 @@ class MonthPanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-prev-year`} onClick={goPrevYear} > - +
); diff --git a/src/calendar/head/range-panel-header.jsx b/src/calendar/head/range-panel-header.jsx index 5077d7d744..8e7abef8aa 100644 --- a/src/calendar/head/range-panel-header.jsx +++ b/src/calendar/head/range-panel-header.jsx @@ -69,7 +69,10 @@ class RangePanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-prev-year`} onClick={goPrevYear} > - +
{disableChangeMode ? ( @@ -235,7 +241,10 @@ class RangePanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-next-month`} onClick={goNextMonth} > - +
); diff --git a/src/calendar/head/year-panel-header.jsx b/src/calendar/head/year-panel-header.jsx index 7ece4016b3..08debc8006 100644 --- a/src/calendar/head/year-panel-header.jsx +++ b/src/calendar/head/year-panel-header.jsx @@ -28,7 +28,10 @@ class YearPanelHeader extends React.PureComponent { className={`${btnCls} ${btnCls}-prev-decade`} onClick={goPrevDecade} > - +
); diff --git a/src/calendar/main.scss b/src/calendar/main.scss index 688ed83ddd..7fe064308c 100644 --- a/src/calendar/main.scss +++ b/src/calendar/main.scss @@ -35,4 +35,17 @@ @include clearfix; } } + + &-symbol-prev::before { + content: $calendar-btn-arrow-content-prev; + } + &-symbol-next::before { + content: $calendar-btn-arrow-content-next; + } + &-symbol-prev-super::before { + content: $calendar-btn-arrow-content-prev-super; + } + &-symbol-next-super::before { + content: $calendar-btn-arrow-content-next-super; + } } diff --git a/src/calendar/scss/variable.scss b/src/calendar/scss/variable.scss index d51892e200..126867fe70 100644 --- a/src/calendar/scss/variable.scss +++ b/src/calendar/scss/variable.scss @@ -369,3 +369,19 @@ $calendar-btn-date-color: $color-white !default; /// text /// @namespace statement/hover/header $calendar-btn-date-color-hover: $color-white !default; + +/// prev +/// @namespace statement/normal/table head +$calendar-btn-arrow-content-prev: $icon-content-arrow-left !default; + +/// next +/// @namespace statement/normal/table head +$calendar-btn-arrow-content-next: $icon-content-arrow-right !default; + +/// prev super +/// @namespace statement/normal/table head +$calendar-btn-arrow-content-prev-super: $icon-content-arrow-double-left !default; + +/// next super +/// @namespace statement/normal/table head +$calendar-btn-arrow-content-next-super: $icon-content-arrow-double-right !default; From dd2241926b833fb62db21c66d2cba0bc31e9f6d5 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 5 Mar 2020 11:27:38 +0800 Subject: [PATCH 38/53] feat(SplitButton): support fold / unfold icon config --- docs/split-button/theme/index.jsx | 10 +++++++++- src/split-button/index.jsx | 6 +++++- src/split-button/main.scss | 22 ++++++++++++++++++++-- src/split-button/scss/variable.scss | 10 ++++++++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/docs/split-button/theme/index.jsx b/docs/split-button/theme/index.jsx index ea01cfdf71..41dc1c690d 100644 --- a/docs/split-button/theme/index.jsx +++ b/docs/split-button/theme/index.jsx @@ -44,11 +44,19 @@ const i18nMap = { function renderButton(type, locale, props) { const menu = ['undo', 'redo', 'cut', 'copy', 'paste'].map(item => {locale[item]}); const cols = [locale.large, locale.medium, locale.small]; + const newLabel =
+ {locale.editDocument} + {/* --------- this is for config platform ----------- */} +
+
+
+ {/* --------- this is for config platform ----------- */} +
; const commonProps = { ...props, type: type.toLowerCase(), - label: locale.editDocument + label: newLabel }; let style; diff --git a/src/split-button/index.jsx b/src/split-button/index.jsx index fc32357142..799f2e8cec 100644 --- a/src/split-button/index.jsx +++ b/src/split-button/index.jsx @@ -252,13 +252,17 @@ class SplitButton extends React.Component { opened: state.visible, }); + const iconCls = classnames({ + [`${prefix}split-btn-symbol-fold`]: true, + }); + const trigger = ( ); diff --git a/src/split-button/main.scss b/src/split-button/main.scss index f2ce4ad407..48e1d66c3f 100644 --- a/src/split-button/main.scss +++ b/src/split-button/main.scss @@ -11,8 +11,14 @@ transition: transform $motion-duration-immediately $motion-linear; } - &.#{$css-prefix}expand .#{$css-prefix}icon { - transform: rotate(180deg); + &.#{$css-prefix}expand #{$split-btn-prefix}-symbol-fold { + @if $split-btn-unfold-icon-content != $icon-reset { + &::before { + content: $split-btn-unfold-icon-content; + } + } @else { + transform: rotate(180deg); + } } &.#{$css-prefix}btn-normal:not(:disabled):not(.disabled) .#{$css-prefix}icon { @@ -29,4 +35,16 @@ padding-right: $s-2; } } + + &-symbol-fold { + &::before { + content: $split-btn-fold-icon-content; + } + } + + // --------- this is for config platform + &-symbol-unfold::before { + content: $split-btn-unfold-icon-content; + } + // --------- this is for config platform } diff --git a/src/split-button/scss/variable.scss b/src/split-button/scss/variable.scss index 04d74641a6..4f9f7c49c7 100644 --- a/src/split-button/scss/variable.scss +++ b/src/split-button/scss/variable.scss @@ -16,3 +16,13 @@ $split-btn-prefix: ".#{$css-prefix}split-btn"; /// icon /// @namespace statement/normal $split-btn-trigger-normal-icon-color: $color-text1-2 !default; + +/// fold icon +/// @namespace statement/normal +/// @type icon +$split-btn-fold-icon-content: $icon-content-arrow-down !default; + +/// unfold icon +/// @namespace statement/normal +/// @type icon +$split-btn-unfold-icon-content: $icon-reset !default; From 563d2a3d14148ca2824acac6b081208a677ea4c5 Mon Sep 17 00:00:00 2001 From: youluna Date: Thu, 5 Mar 2020 11:38:48 +0800 Subject: [PATCH 39/53] feat(MenuButton): support theme icons config --- docs/menu-button/theme/index.jsx | 13 +++++++++---- src/menu-button/main.scss | 17 ++++++++++++++++- src/menu-button/scss/variable.scss | 10 ++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/menu-button/theme/index.jsx b/docs/menu-button/theme/index.jsx index 2b38979e3e..fa98fd5829 100644 --- a/docs/menu-button/theme/index.jsx +++ b/docs/menu-button/theme/index.jsx @@ -46,16 +46,21 @@ const i18nMap = { function renderButton(type, locale, props) { const menu = ['undo', 'redo', 'cut', 'copy', 'paste'].map(item => {locale[item]}); const cols = [locale.large, locale.medium, locale.small]; + const newLabel =
+ {locale.editDocument} + {/* --------- this is for config platform ----------- */} +
+
+
+ {/* --------- this is for config platform ----------- */} +
; const commonProps = { ...props, type: type.toLowerCase(), - label: locale.editDocument, + label: newLabel, }; - let labelColor; - let bgColor; - let style; if (props) { diff --git a/src/menu-button/main.scss b/src/menu-button/main.scss index 1d3329ee85..bf8f6538dc 100644 --- a/src/menu-button/main.scss +++ b/src/menu-button/main.scss @@ -11,9 +11,24 @@ transition: transform $motion-duration-immediately $motion-linear; } + .#{$css-prefix}menu-btn-arrow::before { + content: $menu-btn-fold-icon-content; + } + &.#{$css-prefix}expand .#{$css-prefix}menu-btn-arrow { - transform: rotate(180deg); + @if $menu-btn-unfold-icon-content != $icon-reset { + &::before { + content: $menu-btn-unfold-icon-content; + } + } @else { + transform: rotate(180deg); + } + } + // --------- this is for config platform + &-symbol-unfold::before { + content: $menu-btn-unfold-icon-content; } + // --------- this is for config platform &.#{$css-prefix}btn-normal .#{$css-prefix}menu-btn-arrow { color: $menu-btn-pure-text-normal-icon-color; diff --git a/src/menu-button/scss/variable.scss b/src/menu-button/scss/variable.scss index 47759fb0de..1081e9e720 100644 --- a/src/menu-button/scss/variable.scss +++ b/src/menu-button/scss/variable.scss @@ -50,3 +50,13 @@ $menu-btn-ghost-light-icon-color: $color-text1-4 !default; /// icon /// @namespace statement/dark $menu-btn-ghost-dark-icon-color: $color-white !default; + +/// fold icon +/// @namespace statement/normal +/// @type icon +$menu-btn-fold-icon-content: $icon-content-arrow-down !default; + +/// unfold icon +/// @namespace statement/normal +/// @type icon +$menu-btn-unfold-icon-content: $icon-reset !default; From e09d23f2dc432abf42da63299f6d20d35629ce3a Mon Sep 17 00:00:00 2001 From: aboutblank Date: Thu, 5 Mar 2020 21:40:18 +0800 Subject: [PATCH 40/53] Icons input update hint (#1649) * fix(Input): hint can be a react node * test(Input): add test case --- src/input/input.jsx | 32 +++++++++++++++++++++++++------- test/input/index-spec.js | 15 +++++++++++++++ types/input/index.d.ts | 2 +- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/input/input.jsx b/src/input/input.jsx index 46a8b7fe54..47384eecc6 100644 --- a/src/input/input.jsx +++ b/src/input/input.jsx @@ -51,7 +51,7 @@ export default class Input extends Base { /** * 水印 (Icon的type类型,和hasClear占用一个地方) */ - hint: PropTypes.string, + hint: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** * 文字前附加内容 */ @@ -151,11 +151,26 @@ export default class Input extends Base { let stateWrap = null; if (state === 'success') { - stateWrap = ; + stateWrap = ( + + ); } else if (state === 'loading') { - stateWrap = ; + stateWrap = ( + + ); } else if (state === 'warning') { - stateWrap = ; + stateWrap = ( + + ); } let clearWrap = null; @@ -164,9 +179,12 @@ export default class Input extends Base { if (hint || showClear) { let hintIcon = null; if (hint) { - hintIcon = ( - - ); + hintIcon = + typeof hint === 'string' ? ( + + ) : ( + hint + ); } else { hintIcon = ( { done(); }); + it('should support string hint', done => { + const wrapper = mount(); + assert(wrapper.find('input .next-icon-calendar')); + + done(); + }); + + it('should support node hint', done => { + const wrapper = mount(} />); + assert(wrapper.find('input .next-icon-smile')); + + done(); + }); + it('should support maxLength & hasLimitHint', done => { const wrapper = mount( diff --git a/types/input/index.d.ts b/types/input/index.d.ts index 974f28b368..aa10db5f93 100644 --- a/types/input/index.d.ts +++ b/types/input/index.d.ts @@ -282,7 +282,7 @@ export interface InputProps extends HTMLAttributesWeak, CommonProps { /** * 水印 (Icon的type类型,和hasClear占用一个地方) */ - hint?: string; + hint?: string | React.ReactNode; /** * 文字前附加内容 From 846f286e966974f99bfcf6d0d298c3319ae6c14d Mon Sep 17 00:00:00 2001 From: hongxingshi Date: Thu, 5 Mar 2020 22:57:58 +0800 Subject: [PATCH 41/53] feat(Pagination): make icons configurable --- src/pagination/main.scss | 12 ++++++++++++ src/pagination/pagination.jsx | 16 +++++++++++++--- src/pagination/scss/variable.scss | 14 +++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/pagination/main.scss b/src/pagination/main.scss index 8d29e7f42e..3953395bc1 100644 --- a/src/pagination/main.scss +++ b/src/pagination/main.scss @@ -245,4 +245,16 @@ @include mini-size($s-2); } } + + &-icon-prev::before { + content: $pagination-icon-prev-content; + } + + &-icon-next::before { + content: $pagination-icon-next-content; + } + + &-icon-ellipsis::before { + content: $pagination-icon-ellipsis-content; + } } diff --git a/src/pagination/pagination.jsx b/src/pagination/pagination.jsx index 0f307650a1..a3c060b4d8 100644 --- a/src/pagination/pagination.jsx +++ b/src/pagination/pagination.jsx @@ -302,7 +302,12 @@ class Pagination extends Component { onClick: this.onPageItemClick.bind(this, current - 1), }; - const icon = ; + const icon = ( + + ); return (
); diff --git a/src/date-picker/scss/variable.scss b/src/date-picker/scss/variable.scss index 77b3cfcaee..5b9ed12cb3 100644 --- a/src/date-picker/scss/variable.scss +++ b/src/date-picker/scss/variable.scss @@ -48,3 +48,7 @@ $date-picker-panel-background: $color-white !default; /// separator border /// @namespace statement/normal/panel $date-picker-panel-time-panel-separator-color: $color-line1-2 !default; + +/// calendar icon +/// @namespace statement/normal/header +$date-picker-calendar-icon: $icon-content-calendar !default; diff --git a/src/date-picker/week-picker.jsx b/src/date-picker/week-picker.jsx index bd398a5d1b..b079007751 100644 --- a/src/date-picker/week-picker.jsx +++ b/src/date-picker/week-picker.jsx @@ -5,6 +5,7 @@ import moment from 'moment'; import { polyfill } from 'react-lifecycles-compat'; import Overlay from '../overlay'; import Input from '../input'; +import Icon from '../icon'; import Calendar from '../calendar'; import ConfigProvider from '../config-provider'; import nextLocale from '../locale/zh-cn'; @@ -405,7 +406,12 @@ class WeekPicker extends Component { aria-expanded={visible} readOnly placeholder={placeholder || locale.weekPlaceholder} - hint="calendar" + hint={ + + } hasClear={value && hasClear} className={`${prefix}week-picker-input`} /> diff --git a/src/date-picker/year-picker.jsx b/src/date-picker/year-picker.jsx index 19335c00e8..d26c2fc2b7 100644 --- a/src/date-picker/year-picker.jsx +++ b/src/date-picker/year-picker.jsx @@ -5,6 +5,7 @@ import classnames from 'classnames'; import moment from 'moment'; import Overlay from '../overlay'; import Input from '../input'; +import Icon from '../icon'; import Calendar from '../calendar'; import nextLocale from '../locale/zh-cn'; import { func, obj } from '../util'; @@ -428,7 +429,12 @@ class YearPicker extends Component { aria-expanded={visible} readOnly placeholder={placeholder || locale.yearPlaceholder} - hint="calendar" + hint={ + + } hasClear={allowClear} className={triggerInputCls} /> From 37049c7a0729b7c1e588f6b77b0851e502d4cc8c Mon Sep 17 00:00:00 2001 From: hongxingshi Date: Thu, 5 Mar 2020 23:21:19 +0800 Subject: [PATCH 43/53] feat(Breadcrumb): make sep icon configurable --- src/breadcrumb/index.jsx | 13 +++++++++---- src/breadcrumb/main.scss | 4 ++++ src/breadcrumb/scss/variable.scss | 9 +++++++-- types/breadcrumb/index.d.ts | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/breadcrumb/index.jsx b/src/breadcrumb/index.jsx index 3abeb26a16..389ed642da 100644 --- a/src/breadcrumb/index.jsx +++ b/src/breadcrumb/index.jsx @@ -1,4 +1,4 @@ -import React, { Component, Children } from 'react'; +import React, { Component, Children, isValidElement } from 'react'; import PropTypes from 'prop-types'; import { polyfill } from 'react-lifecycles-compat'; import Icon from '../icon'; @@ -48,7 +48,7 @@ class Breadcrumb extends Component { /** * 分隔符,可以是文本或 Icon */ - separator: PropTypes.node, + separator: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), /** * 设置标签类型 */ @@ -59,7 +59,6 @@ class Breadcrumb extends Component { static defaultProps = { prefix: 'next-', maxNode: 100, - separator: , component: 'nav', }; @@ -134,12 +133,18 @@ class Breadcrumb extends Component { rtl, className, children, - separator, component, maxNode: maxNodeProp, ...others } = this.props; + const separator = this.props.separator || ( + + ); + const { maxNode } = this.state; let items; diff --git a/src/breadcrumb/main.scss b/src/breadcrumb/main.scss index 2a6826ce8e..445501d380 100644 --- a/src/breadcrumb/main.scss +++ b/src/breadcrumb/main.scss @@ -31,5 +31,9 @@ $breadcrumb-text-current-color-hover, $breadcrumb-text-keyword-color-hover ); + + &-icon-sep::before { + content: $breadcrumb-icon-sep-content; + } } } diff --git a/src/breadcrumb/scss/variable.scss b/src/breadcrumb/scss/variable.scss index 7ca2e96e32..9dc16c679f 100644 --- a/src/breadcrumb/scss/variable.scss +++ b/src/breadcrumb/scss/variable.scss @@ -10,7 +10,7 @@ /// @family navigation /// @varPrefix $breadcrumb- /// @classPrefix {prefix}-breadcrumb -/// @order {"size/item":10,"size/ellipsis":11,"size/number":12,"size/keyword":13,"size/seperator":14,"statement/normal":10,"statement/normal/item":100,"statement/normal/item current":101,"statement/normal/ellipsis":102,"statement/normal/number":103,"statement/normal/keyword":104,"statement/normal/seperator":105,"statement/hover":11,"statement/hover/item":110,"statement/hover/item current":111,"statement/hover/number":112,"statement/hover/keyword":113} +/// @order {"size/item":10,"size/ellipsis":11,"size/number":12,"size/keyword":13,"size/seperator":14,"statement/normal":10,"statement/normal/item":100,"statement/normal/item current":101,"statement/normal/ellipsis":102,"statement/normal/number":103,"statement/normal/keyword":104,"statement/normal/seperator color":105,"statement/normal/seperator icon":106,"statement/hover":11,"statement/hover/item":110,"statement/hover/item current":111,"statement/hover/number":112,"statement/hover/keyword":113} //// // Unconfigurable @@ -63,9 +63,14 @@ $breadcrumb-text-ellipsis-color: $color-text1-3 !default; $breadcrumb-text-keyword-color: $color-brand1-6 !default; /// text -/// @namespace statement/normal/seperator +/// @namespace statement/normal/seperator color $breadcrumb-icon-color: $color-line1-4 !default; +/// icon +/// @namespace statement/normal/seperator icon +$breadcrumb-icon-sep-content: $icon-content-arrow-right !default; + + // Statement:Hover // ---------------------------------------- diff --git a/types/breadcrumb/index.d.ts b/types/breadcrumb/index.d.ts index 3dfb63b0ad..c1db2d2f89 100644 --- a/types/breadcrumb/index.d.ts +++ b/types/breadcrumb/index.d.ts @@ -29,7 +29,7 @@ export interface BreadcrumbProps extends React.HTMLAttributes { /** * 分隔符,可以是文本或 Icon */ - separator?: React.ReactNode; + separator?: string | React.ReactNode; /** * 设置标签类型 From 04360696fc9f6bb0ee6ad0980a6e3ebf1b6d34bc Mon Sep 17 00:00:00 2001 From: aboutblank Date: Thu, 5 Mar 2020 23:43:51 +0800 Subject: [PATCH 44/53] feat(DatePicker): icon config (#1651) From a525c0577a37e83628061457be8eb01ff1c8fd59 Mon Sep 17 00:00:00 2001 From: xdddi <35244644+xdddi@users.noreply.github.com> Date: Fri, 6 Mar 2020 11:39:53 +0800 Subject: [PATCH 45/53] feat(TimePicker): make icon configurable in theme (#1655) * feat(TimePicker): make icon configurable in theme Co-authored-by: wb-xd391517 --- src/date-picker/style.js | 1 + src/time-picker/main.scss | 4 ++++ src/time-picker/scss/variable.scss | 4 ++++ src/time-picker/style.js | 1 + src/time-picker/time-picker.jsx | 8 +++++++- 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/date-picker/style.js b/src/date-picker/style.js index 6c3649c3d0..f6e636ed04 100644 --- a/src/date-picker/style.js +++ b/src/date-picker/style.js @@ -3,4 +3,5 @@ import '../overlay/style.js'; import '../calendar/style.js'; import '../time-picker/style.js'; import '../button/style.js'; +import '../icon/style.js'; import './main.scss'; diff --git a/src/time-picker/main.scss b/src/time-picker/main.scss index 764ee40a13..5f8066c641 100644 --- a/src/time-picker/main.scss +++ b/src/time-picker/main.scss @@ -23,4 +23,8 @@ background: $time-picker-panel-background; box-shadow: $time-picker-panel-shadow; } + + &-symble-clock-icon::before { + content: $time-picker-clock-icon; + } } diff --git a/src/time-picker/scss/variable.scss b/src/time-picker/scss/variable.scss index ea1ba82815..f2918925eb 100644 --- a/src/time-picker/scss/variable.scss +++ b/src/time-picker/scss/variable.scss @@ -100,3 +100,7 @@ $time-picker-menu-item-background-disabled: $color-white !default; /// font weight /// @namespace statement/selected/menu item $time-picker-menu-item-font-weight-selected: $font-weight-3 !default; + +/// timepicker icon +/// @namespace statement/normal/header +$time-picker-clock-icon: $icon-content-clock !default; diff --git a/src/time-picker/style.js b/src/time-picker/style.js index 8e94360767..537e00f7de 100644 --- a/src/time-picker/style.js +++ b/src/time-picker/style.js @@ -1,3 +1,4 @@ import '../input/style.js'; import '../overlay/style.js'; +import '../icon/style.js'; import './main.scss'; diff --git a/src/time-picker/time-picker.jsx b/src/time-picker/time-picker.jsx index dcc6160dbd..e3e9b87b07 100644 --- a/src/time-picker/time-picker.jsx +++ b/src/time-picker/time-picker.jsx @@ -5,6 +5,7 @@ import classnames from 'classnames'; import moment from 'moment'; import ConfigProvider from '../config-provider'; import Input from '../input'; +import Icon from '../icon'; import Overlay from '../overlay'; import nextLocale from '../locale/zh-cn'; import { func, obj } from '../util'; @@ -410,7 +411,12 @@ class TimePicker extends Component { onBlur: this.onInputBlur, onPressEnter: this.onInputBlur, onKeyDown: this.onKeyown, - hint: 'clock', + hint: ( + + ), }; const triggerInput = ( From 929da881afec117924f480005d7e8cacea463378 Mon Sep 17 00:00:00 2001 From: aboutblank Date: Fri, 6 Mar 2020 15:20:26 +0800 Subject: [PATCH 46/53] feat(Icon): add icons (#1574) --- .fusion | 2 +- docs/icon/demo/type.md | 2 +- src/core/style/_icon.scss | 27 ++++++++++++++++++++++++++- src/icon/main.scss | 4 ++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.fusion b/.fusion index 11681593cc..9d9c7e883c 100644 --- a/.fusion +++ b/.fusion @@ -4,7 +4,7 @@ "class-prefix": ".next", "icon": { "iconfont-project-id": "515771", - "iconfont-path": "//at.alicdn.com/t/font_515771_7u6frotlpa6" + "iconfont-path": "//at.alicdn.com/t/font_515771_xjdbujl2iu" }, "import": { "sources": { diff --git a/docs/icon/demo/type.md b/docs/icon/demo/type.md index 6680b94a61..fd54bae2ce 100644 --- a/docs/icon/demo/type.md +++ b/docs/icon/demo/type.md @@ -29,7 +29,7 @@ const types = [ 'calendar', 'ashbin', 'upload', 'download', 'set', 'edit', 'refresh', 'filter', 'attachment', 'account', 'email', 'atm', 'copy', 'exit', 'eye', 'eye-close', 'toggle-left', 'toggle-right', - 'lock', 'unlock','chart-pie', 'chart-bar' + 'lock', 'unlock','chart-pie', 'chart-bar', 'form', 'detail', 'list', 'dashboard', ]; diff --git a/src/core/style/_icon.scss b/src/core/style/_icon.scss index e6bb22c153..13052cfa7b 100644 --- a/src/core/style/_icon.scss +++ b/src/core/style/_icon.scss @@ -8,7 +8,7 @@ // 根据 Alibaba Base DPL 设计实现 /// icon font path 字体路径 -$icon-font-path: "//at.alicdn.com/t/font_515771_7u6frotlpa6" !default; +$icon-font-path: "//at.alicdn.com/t/font_515771_xjdbujl2iu" !default; /// icon font name 自定义的icon font 名称 $icon-font-name: "icon" !default; @@ -372,4 +372,29 @@ $icon-content-chart-bar: "\e612" !default; /// @unconfigurable $icon-content-chart-pie: "\e613" !default; +/// icon-content-form +/// @group type +/// @export type +/// @unconfigurable +$icon-content-form: "\e7fb" !default; + +/// icon-content-detail +/// @group type +/// @export type +/// @unconfigurable +$icon-content-detail: "\e7f8" !default; + +/// icon-content-list +/// @group type +/// @export type +/// @unconfigurable +$icon-content-list: "\e7f9" !default; + +/// icon-content-dashboard +/// @group type +/// @export type +/// @unconfigurable +$icon-content-dashboard: "\e7fa" !default; + $icon-reset: "" !default; + diff --git a/src/icon/main.scss b/src/icon/main.scss index b8b0180623..f7973e6878 100644 --- a/src/icon/main.scss +++ b/src/icon/main.scss @@ -82,6 +82,10 @@ &-exit:before { content: $icon-content-exit; } &-chart-bar:before { content: $icon-content-chart-bar; } &-chart-pie:before { content: $icon-content-chart-pie; } + &-form:before { content: $icon-content-form; } + &-detail:before { content: $icon-content-detail; } + &-list:before { content: $icon-content-list; } + &-dashboard:before { content: $icon-content-dashboard; } } @keyframes loadingCircle { From f9302020d7f8dbb3589330a46f254f8709a37af5 Mon Sep 17 00:00:00 2001 From: aboutblank Date: Fri, 6 Mar 2020 18:05:34 +0800 Subject: [PATCH 47/53] feat(Select): make icons configurable (#1648) --- docs/select/theme/index.jsx | 23 ++++++++++++++++------- src/select/main.scss | 20 ++++++++++++++++++-- src/select/scss/variable.scss | 10 ++++++++++ src/select/select.jsx | 5 ++++- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/docs/select/theme/index.jsx b/docs/select/theme/index.jsx index 9f1815600a..4344a32f3d 100644 --- a/docs/select/theme/index.jsx +++ b/docs/select/theme/index.jsx @@ -71,10 +71,13 @@ class FunctionDemo extends React.Component { const comboboxSource = ['Canada', 'China', 'Colombia', 'Congo', 'Georgia', 'Germany', 'Greece', 'Grenada', 'Guam', 'Singapore', 'South Korea', 'Switzerland', 'Uganda', 'United Kingdom', 'United States']; + const iconsConfigHelper = (
+
+
); const selectProps = { dataSource, popupProps: {needAdjust: false}, - label: getValue('demo').label.value === 'true' ? 'Label' : undefined + label: getValue('demo').label.value === 'true' ? 'Label' : undefined, }; const comboboxProps = { @@ -101,12 +104,18 @@ class FunctionDemo extends React.Component { - +
+ + {iconsConfigHelper} +
+
+ diff --git a/src/select/main.scss b/src/select/main.scss index fdcf06a9b8..3d26a33ed4 100644 --- a/src/select/main.scss +++ b/src/select/main.scss @@ -289,11 +289,27 @@ } &.#{$css-prefix}active { - #{$select-prefix}-arrow .#{$css-prefix}icon-arrow-down { - transform: rotate(180deg); + @if $select-unfold-icon-content != $icon-reset { + #{$select-prefix}-symbol-fold::before { + content: $select-unfold-icon-content; + } + } @else { + #{$select-prefix}-arrow .#{$css-prefix}icon-arrow-down { + transform: rotate(180deg); + } } } + // --------- this is for config platform + #{$select-prefix}-unfold-icon::before { + content: $select-unfold-icon-content; + } + // --------- this is for config platform + + &-symbol-fold::before { + content: $select-fold-icon-content; + } + &-arrow { cursor: pointer; width: auto !important; diff --git a/src/select/scss/variable.scss b/src/select/scss/variable.scss index 921ba53dde..e67bc093f7 100644 --- a/src/select/scss/variable.scss +++ b/src/select/scss/variable.scss @@ -53,3 +53,13 @@ $select-tag-spacing-tb: 3px; $select-tag-padding-lr: $s-1; $select-menu-item-height: $s-5; $select-menu-icon-color: $color-brand1-6; + +/// fold icon +/// @namespace statement/normal +/// @type icon +$select-fold-icon-content: $icon-content-arrow-down !default; + +/// unfold icon +/// @namespace statement/normal +/// @type icon +$select-unfold-icon-content: $icon-reset !default; diff --git a/src/select/select.jsx b/src/select/select.jsx index c8a914a89d..e65bcff461 100644 --- a/src/select/select.jsx +++ b/src/select/select.jsx @@ -929,7 +929,10 @@ class Select extends Base { onClick={this.handleArrowClick} className={`${prefix}select-arrow`} > - + ); } From a40abfd6476ad2e7a4cd42e3a5542723350d417f Mon Sep 17 00:00:00 2001 From: "mark.ck" Date: Sun, 8 Mar 2020 03:24:56 +0800 Subject: [PATCH 48/53] feat(Transfer): make transfer simple move icon configurable --- src/transfer/main.scss | 5 +++++ src/transfer/scss/variable.scss | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/transfer/main.scss b/src/transfer/main.scss index 101118ba9b..87cc70a461 100644 --- a/src/transfer/main.scss +++ b/src/transfer/main.scss @@ -117,6 +117,11 @@ &-move.#{$css-prefix}icon { color: $transfer-simple-move-icon-color; + @if $transfer-simple-move-icon != $icon-reset { + &::before { + content: $transfer-simple-move-icon; + } + } } &-operation.#{$css-prefix}btn { diff --git a/src/transfer/scss/variable.scss b/src/transfer/scss/variable.scss index 83767ac119..1bd6ebf317 100644 --- a/src/transfer/scss/variable.scss +++ b/src/transfer/scss/variable.scss @@ -5,7 +5,7 @@ /// @family data-entry /// @varPrefix $transfer- /// @classPrefix {prefix}-transfer -/// @order {"size/move":10,"size/panel":11,"size/header":12,"size/search":13,"size/footer":14,"statement/normal":10,"statement/normal/move":100,"statement/normal/panel":101,"statement/normal/header":102,"statement/normal/item":103,"statement/normal/footer":104,"statement/hover":11,"statement/hover/item":110} +/// @order {"size/move":10,"size/panel":11,"size/header":12,"size/search":13,"size/footer":14,"size/list":15,"statement/normal":10,"statement/normal/move":100,"statement/normal/panel":101,"statement/normal/header":102,"statement/normal/item":103,"statement/normal/footer":104,"statement/hover":11,"statement/hover/item":110} //// // transfer variables @@ -78,6 +78,10 @@ $transfer-panel-footer-padding-left-right: $s-5 !default; /// icon /// @namespace statement/normal/move +$transfer-simple-move-icon: $icon-content-switch !default; + +/// icon color +/// @namespace statement/normal/move $transfer-simple-move-icon-color: $color-line1-3 !default; /// border color From b01f457de8bc0a5e97e08a381de9ddd43265352f Mon Sep 17 00:00:00 2001 From: aboutblank Date: Mon, 9 Mar 2020 10:23:53 +0800 Subject: [PATCH 49/53] fix(Overlay& Nav): wrong position when pinElement is fixed (#1617) * fix(Overlay): wrong position when pinElement is fixed * fix(Nav): close #1599 * Update custom.md --- docs/nav/demo/custom.md | 17 ++++++++-- docs/nav/demo/fixed.md | 31 ++++++++++++++++++ src/menu/view/popup-item.jsx | 1 + src/nav/sub-nav.jsx | 38 +++++++++++++++------- src/overlay/overlay.jsx | 5 +++ src/overlay/position.jsx | 3 ++ src/overlay/utils/position.js | 35 +++++++++++++------- test/nav/a11y-spec.js | 2 +- test/nav/index-spec.js | 61 +++++++++++++++++++++++++++++++++++ 9 files changed, 167 insertions(+), 26 deletions(-) create mode 100644 docs/nav/demo/fixed.md diff --git a/docs/nav/demo/custom.md b/docs/nav/demo/custom.md index e49595d34a..9595e9a465 100644 --- a/docs/nav/demo/custom.md +++ b/docs/nav/demo/custom.md @@ -25,7 +25,8 @@ class App extends React.Component { type: 'normal', direction: 'hoz', activeDirection: null, - triggerType: 'click' + triggerType: 'click', + mode: 'inline' } setValue(name, value) { @@ -40,8 +41,14 @@ class App extends React.Component { }); } + setModeType(mode) { + this.setState({ + mode + }); + } + render() { - const { type, direction, activeDirection, triggerType } = this.state; + const { type, direction, activeDirection, triggerType, mode } = this.state; return (
@@ -67,8 +74,12 @@ class App extends React.Component { triggerType="click" triggerType="hover" + + mode="inline" + mode="popup" +
-
- + - + @@ -122,5 +145,44 @@ ReactDOM.render(, mountNode); } .next-input-inner.next-before { margin-left: 8px; -} +}.fusion-demo-item { + margin: 15px 0; + } + .custom-node1 { + height: 100%; + width: 100%; + border-radius: 20%; + border: 1px dashed #3E71F1; + text-align: center; + } + .custom-node1 span { + font-size: 12px; + + position: absolute; + top: 50%; + text-align: center; + width: 100%; + left: 0; + transform: translateY(-50%); + } + .custom-node2 { + height: 100%; + width: 100%; + border-radius: 20%; + border: 1px dashed #3E71F1; + text-align: center; + background: #3E71F1; + color: #fff; + position: relative; + } + + .custom-node2 span, .custom-node2 i { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 100%; + text-align: center; + } + ```` diff --git a/src/step/scss/dot.scss b/src/step/scss/dot.scss index b19e69df2c..4b793a069c 100644 --- a/src/step/scss/dot.scss +++ b/src/step/scss/dot.scss @@ -8,7 +8,8 @@ vertical-align: middle; position: relative; padding: 0 $step-dot-item-dot-padding; - font-size: 0; + margin-top: -1px; + margin-bottom: -1px; #{$step-prefix}-item-node-placeholder { display: inline-block; diff --git a/src/step/view/step-item.jsx b/src/step/view/step-item.jsx index 47e7df2947..ce3aec5dc4 100644 --- a/src/step/view/step-item.jsx +++ b/src/step/view/step-item.jsx @@ -228,9 +228,12 @@ class StepItem extends Component { } = this.props; const { others, stepCls, overlayCls } = args; const nodeElement = this._getNode(); + const containerStyle = + (shape === 'dot' && { fontSize: 'initial' }) || {}; let finalNodeElement = (
+
{ const itemHeight = - getHeight(re) + + getHeight( + re.getElementsByClassName( + `${prefix}step-item-container` + )[0] + ) + getHeight( re.getElementsByClassName( `${prefix}step-item-body` From 31324439ab7baaf7e527a366951d7a535bb1bc86 Mon Sep 17 00:00:00 2001 From: hongxingshi Date: Tue, 10 Mar 2020 09:57:47 +0800 Subject: [PATCH 53/53] feat(Button): add icons for custom loading icon (#1624) * feat(Button): add icons for custom loading icon --- docs/button/demo/accessibility.md | 4 +-- docs/button/demo/component.md | 4 +-- docs/button/demo/custom-icons.md | 43 +++++++++++++++++++++++++++++++ docs/button/demo/disabled.md | 4 +-- docs/button/demo/ghost.md | 4 +-- docs/button/demo/group.md | 4 +-- docs/button/demo/loading.md | 2 +- docs/button/index.en-us.md | 1 + docs/button/index.md | 1 + src/button/main.scss | 5 ++++ src/button/scss/mixin.scss | 12 +++++++++ src/button/view/button.jsx | 34 +++++++++++++++++++++--- test/button/index-spec.js | 15 ++++++++++- types/button/index.d.ts | 5 +++- 14 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 docs/button/demo/custom-icons.md diff --git a/docs/button/demo/accessibility.md b/docs/button/demo/accessibility.md index 9aa901424d..271a58460e 100644 --- a/docs/button/demo/accessibility.md +++ b/docs/button/demo/accessibility.md @@ -1,13 +1,13 @@ # 无障碍 -- order: 8 +- order: 9 在使用不包含文本的icon Button组件时,我们需要添加`aria-label`对其进行描述,键盘操作请参考`ARIA and KeyBoard`。 :::lang=en-us # Accessibility -- order: 8 +- order: 9 When using icon Button component , we should add `aria-label` to describe it. Please refer to `ARIA and KeyBoard` for keyboard operation information. diff --git a/docs/button/demo/component.md b/docs/button/demo/component.md index dfd240394d..4e0b924397 100644 --- a/docs/button/demo/component.md +++ b/docs/button/demo/component.md @@ -1,6 +1,6 @@ # 自定义标签类型 -- order: 6 +- order: 7 默认情况下 Button 组件使用 `   + +
); + } +} + +ReactDOM.render(, mountNode); +```` diff --git a/docs/button/demo/disabled.md b/docs/button/demo/disabled.md index ddd09ed66c..0dd895e2d7 100644 --- a/docs/button/demo/disabled.md +++ b/docs/button/demo/disabled.md @@ -1,13 +1,13 @@ # 不可用状态 -- order: 5 +- order: 6 添加 `disabled` 属性即可让按钮处于不可用状态,同时按钮样式也会改变。 :::lang=en-us # Disabled -- order: 5 +- order: 6 Disable a Button by adding `disabled` attribute. diff --git a/docs/button/demo/ghost.md b/docs/button/demo/ghost.md index 69f9896c9d..b46be0b754 100644 --- a/docs/button/demo/ghost.md +++ b/docs/button/demo/ghost.md @@ -1,13 +1,13 @@ # 幽灵按钮 -- order: 4 +- order: 5 幽灵按钮通常用在有色背景下,可以使用 `ghost` 属性开启,此时 Button 为透明背景。对于浅色背景和深色背景,通过取值 `light`, `dark` 可以配置使用幽灵按钮的场景。 :::lang=en-us # Ghost -- order: 4 +- order: 5 Ghost button is usually used for colored backgrounds. Change a Button to ghost by adding `ghost` attribute, and set the attribute's value to `light` or `darked` based on the color depth. diff --git a/docs/button/demo/group.md b/docs/button/demo/group.md index 28020e1aed..32f6662956 100644 --- a/docs/button/demo/group.md +++ b/docs/button/demo/group.md @@ -1,13 +1,13 @@ # 按钮组 -- order: 7 +- order: 8 `Button.Group` 子组件用于将多个按钮组合在一个容器中。 :::lang=en-us # Button group -- order: 7 +- order: 8 `Button.Group` could be used to combine multiple Buttons. diff --git a/docs/button/demo/loading.md b/docs/button/demo/loading.md index 05fe463b8f..c2913155ee 100644 --- a/docs/button/demo/loading.md +++ b/docs/button/demo/loading.md @@ -16,7 +16,7 @@ Button has a inner state `loading` to control if a Button is in loading. It coul --- ````jsx -import { Button } from '@alifd/next'; +import { Button, Icon } from '@alifd/next'; class Demo extends React.Component { constructor(props, context) { diff --git a/docs/button/index.en-us.md b/docs/button/index.en-us.md index d7cfce572c..f302d812e1 100644 --- a/docs/button/index.en-us.md +++ b/docs/button/index.en-us.md @@ -23,6 +23,7 @@ Buttons are used for emphasizing important functions on your page. | --------- | ------------------------------------------------------------------------------------------------------------ | -------- | -------- | | size | Size of button

**return**:
'small', 'medium', 'large' | Enum | 'medium' | | type | Typeo of button

**return**:
'primary', 'secondary', 'normal' | Enum | 'normal' | +| icons | custom icons in button in the format { loading: } | Object | {} | | iconSize | Size of icon in button

**return**:
'xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl' | Enum | - | | htmlType | Original html type

**return**:
'submit', 'reset', 'button' | Enum | 'button' | | component | The html tag to be rendered

**return**:
'button', 'a', 'div', 'span' | Enum | 'button' | diff --git a/docs/button/index.md b/docs/button/index.md index 4e974082ef..78cd6146e3 100644 --- a/docs/button/index.md +++ b/docs/button/index.md @@ -23,6 +23,7 @@ | --------- | ------------------------------------------------------------------------------------------------------------ | -------- | -------- | | size | 按钮的尺寸

**可选值**:
'small', 'medium', 'large' | Enum | 'medium' | | type | 按钮的类型

**可选值**:
'primary', 'secondary', 'normal' | Enum | 'normal' | +| icons | 按钮中可配置的 Icon,格式为 { loading: } | Object | {} | | iconSize | 按钮中 Icon 的尺寸,用于替代 Icon 的默认大小

**可选值**:
'xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl' | Enum | - | | htmlType | 当 component = 'button' 时,设置 button 标签的 type 值

**可选值**:
'submit', 'reset', 'button' | Enum | 'button' | | component | 设置标签类型

**可选值**:
'button', 'a', 'div', 'span' | Enum | 'button' | diff --git a/src/button/main.scss b/src/button/main.scss index 01d9f5abe8..f69e5fd1e1 100644 --- a/src/button/main.scss +++ b/src/button/main.scss @@ -313,6 +313,11 @@ } } + /* custom loading */ + &-custom-loading { + pointer-events: none; + } + /* 幽灵按钮 */ &-ghost { box-shadow: none; diff --git a/src/button/scss/mixin.scss b/src/button/scss/mixin.scss index e41bee4f1b..3fb32ce001 100644 --- a/src/button/scss/mixin.scss +++ b/src/button/scss/mixin.scss @@ -40,6 +40,18 @@ display: none; } } + + & > #{$btn-prefix}-custom-loading-icon { + opacity: 0; + width: 0; + + &.show { + width: $icon-size; + margin-right: $icon-margin; + opacity: 1; + transition: all $motion-duration-immediately $motion-linear; + } + } } @keyframes loadingCircle { diff --git a/src/button/view/button.jsx b/src/button/view/button.jsx index 37594c25bd..3eae4042ad 100644 --- a/src/button/view/button.jsx +++ b/src/button/view/button.jsx @@ -26,6 +26,12 @@ export default class Button extends Component { * 按钮的尺寸 */ size: PropTypes.oneOf(['small', 'medium', 'large']), + /** + * 按钮中可配置的 Icon,格式为 { loading: } + */ + icons: PropTypes.shape({ + loading: PropTypes.node, + }), /** * 按钮中 Icon 的尺寸,用于替代 Icon 的默认大小 */ @@ -81,6 +87,7 @@ export default class Button extends Component { prefix: 'next-', type: 'normal', size: 'medium', + icons: {}, htmlType: 'button', component: 'button', loading: false, @@ -116,6 +123,7 @@ export default class Button extends Component { ghost, component, iconSize, + icons, disabled, onClick, children, @@ -125,7 +133,7 @@ export default class Button extends Component { const ghostType = ['light', 'dark'].indexOf(ghost) >= 0 ? ghost : 'dark'; - const btnCls = classNames({ + const btnClsObj = { [`${prefix}btn`]: true, [`${prefix}${size}`]: size, [`${prefix}btn-${type}`]: type && !ghost, @@ -135,7 +143,26 @@ export default class Button extends Component { [`${prefix}btn-ghost`]: ghost, [`${prefix}btn-${ghostType}`]: ghost, [className]: className, - }); + }; + + let loadingIcon = null; + + // 如果传入了 loading 的 icons,使用该节点来渲染 + if (icons && icons.loading && isValidElement(icons.loading)) { + if (loading) { + delete btnClsObj[`${prefix}btn-loading`]; + btnClsObj[`${prefix}btn-custom-loading`] = true; + } + + const loadingSize = iconSize || mapIconSize(size); + loadingIcon = React.cloneElement(icons.loading, { + className: classNames({ + [`${prefix}btn-custom-loading-icon`]: true, + show: loading, + }), + size: loadingSize, + }); + } const count = Children.count(children); const clonedChildren = Children.map(children, (child, index) => { @@ -182,7 +209,7 @@ export default class Button extends Component { type: htmlType, disabled: disabled, onClick: onClick, - className: btnCls, + className: classNames(btnClsObj), }; if (TagName !== 'button') { @@ -201,6 +228,7 @@ export default class Button extends Component { onMouseUp={this.onMouseUp} ref={this.buttonRefHandler} > + {loadingIcon} {clonedChildren} ); diff --git a/test/button/index-spec.js b/test/button/index-spec.js index 473288ca4d..dc6116234d 100644 --- a/test/button/index-spec.js +++ b/test/button/index-spec.js @@ -41,6 +41,19 @@ describe('Button', () => { assert(wrapper3.find('.next-btn-dark').length === 1); }); + it('should render loading button', () => { + const wrapper = mount(); + + assert(wrapper.find('.next-btn-loading').length === 1); + }); + + it('should render custom loading button', () => { + const wrapper = mount(); + + assert(wrapper.find('Icon.next-btn-custom-loading-icon').length === 1); + assert(wrapper.find('.next-btn-loading').length === 0); + }); + it('should render button with icon', () => { const wrapper = mount(