@douyinfe/semi-ui 2.9.1 → 2.10.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/banner/_story/banner.stories.js +62 -1
  2. package/banner/index.tsx +5 -5
  3. package/carousel/CarouselArrow.tsx +62 -0
  4. package/carousel/CarouselIndicator.tsx +84 -0
  5. package/carousel/__test__/carousel.test.js +159 -0
  6. package/carousel/_story/carousel.stories.js +486 -0
  7. package/carousel/index.tsx +294 -0
  8. package/carousel/interface.ts +64 -0
  9. package/cascader/index.tsx +1 -2
  10. package/dist/css/semi.css +342 -0
  11. package/dist/css/semi.min.css +1 -1
  12. package/dist/umd/semi-ui.js +884 -66
  13. package/dist/umd/semi-ui.js.map +1 -1
  14. package/dist/umd/semi-ui.min.js +1 -1
  15. package/dist/umd/semi-ui.min.js.map +1 -1
  16. package/index.ts +2 -0
  17. package/lib/cjs/banner/index.js +11 -5
  18. package/lib/cjs/carousel/CarouselArrow.d.ts +8 -0
  19. package/lib/cjs/carousel/CarouselArrow.js +91 -0
  20. package/lib/cjs/carousel/CarouselIndicator.d.ts +23 -0
  21. package/lib/cjs/carousel/CarouselIndicator.js +145 -0
  22. package/lib/cjs/carousel/index.d.ts +58 -0
  23. package/lib/cjs/carousel/index.js +345 -0
  24. package/lib/cjs/carousel/interface.d.ts +62 -0
  25. package/lib/cjs/carousel/interface.js +7 -0
  26. package/lib/cjs/cascader/index.js +1 -1
  27. package/lib/cjs/index.d.ts +1 -0
  28. package/lib/cjs/index.js +9 -0
  29. package/lib/cjs/switch/index.d.ts +3 -0
  30. package/lib/cjs/switch/index.js +26 -6
  31. package/lib/es/banner/index.js +11 -5
  32. package/lib/es/carousel/CarouselArrow.d.ts +8 -0
  33. package/lib/es/carousel/CarouselArrow.js +72 -0
  34. package/lib/es/carousel/CarouselIndicator.d.ts +23 -0
  35. package/lib/es/carousel/CarouselIndicator.js +125 -0
  36. package/lib/es/carousel/index.d.ts +58 -0
  37. package/lib/es/carousel/index.js +311 -0
  38. package/lib/es/carousel/interface.d.ts +62 -0
  39. package/lib/es/carousel/interface.js +1 -0
  40. package/lib/es/cascader/index.js +1 -1
  41. package/lib/es/index.d.ts +1 -0
  42. package/lib/es/index.js +1 -0
  43. package/lib/es/switch/index.d.ts +3 -0
  44. package/lib/es/switch/index.js +26 -6
  45. package/package.json +9 -9
  46. package/switch/index.tsx +20 -3
  47. package/tagInput/__test__/tagInput.test.js +11 -11
@@ -1,7 +1,9 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
 
3
3
  import Banner from '../index';
4
4
  import Button from '@douyinfe/semi-ui/button/index';
5
+ import { Layout } from '@douyinfe/semi-ui';
6
+
5
7
 
6
8
  export default {
7
9
  title: 'Banner',
@@ -43,3 +45,62 @@ export const InContainerAndBordered = () => (
43
45
  <Button onClick={e => e.stopPropagation()}>test</Button>
44
46
  </Banner>
45
47
  );
48
+
49
+ export const ShowAndHideBanner = () => {
50
+ const [visible, setVisible] = useState(false);
51
+ const changeVisible = () => {
52
+ setVisible(!visible);
53
+ };
54
+ const { Header, Footer, Content } = Layout;
55
+ const banner = (
56
+ <Banner
57
+ onClose={changeVisible}
58
+ description="A pre-released version is available"
59
+ />
60
+ );
61
+
62
+ return (
63
+ <>
64
+ <Layout>
65
+ <Header>Header</Header>
66
+ {visible? banner : null}
67
+ <Content>Content</Content>
68
+ <Footer>Footer</Footer>
69
+ </Layout>
70
+ <Button
71
+ onClick={changeVisible}
72
+ style={{
73
+ display: 'block',
74
+ width: '120px',
75
+ margin: '0 auto'
76
+ }}
77
+ >
78
+ { visible ? 'Hide Banner' : 'Show Banner' }
79
+ </Button>
80
+ </>
81
+ );
82
+ };
83
+
84
+ export const MultiTypeBanner = () => (
85
+ <>
86
+ <Banner
87
+ type="info"
88
+ description="A pre-released version is available."
89
+ />
90
+ <br/>
91
+ <Banner
92
+ type="warning"
93
+ description="This version of the document is going to expire after 4 days."
94
+ />
95
+ <br/>
96
+ <Banner
97
+ type="danger"
98
+ description="This document was deprecated since Jan 1, 2019."
99
+ />
100
+ <br/>
101
+ <Banner
102
+ type="success"
103
+ description="You are viewing the latest version of this document."
104
+ />
105
+ </>
106
+ );
package/banner/index.tsx CHANGED
@@ -109,7 +109,7 @@ export default class Banner extends BaseComponent<BannerProps, BannerState> {
109
109
  <Button
110
110
  className={`${prefixCls}-close`}
111
111
  onClick={this.remove}
112
- icon={closeIcon || <IconClose />}
112
+ icon={closeIcon || <IconClose aria-hidden={true}/>}
113
113
  theme="borderless"
114
114
  size="small"
115
115
  type="tertiary"
@@ -122,10 +122,10 @@ export default class Banner extends BaseComponent<BannerProps, BannerState> {
122
122
  renderIcon() {
123
123
  const { type, icon } = this.props;
124
124
  const iconMap = {
125
- warning: <IconAlertTriangle size="large" />,
126
- success: <IconTickCircle size="large" />,
127
- info: <IconInfoCircle size="large" />,
128
- danger: <IconAlertCircle size="large" />
125
+ warning: <IconAlertTriangle size="large" aria-label='warning'/>,
126
+ success: <IconTickCircle size="large" aria-label='success'/>,
127
+ info: <IconInfoCircle size="large" aria-label='info'/>,
128
+ danger: <IconAlertCircle size="large" aria-label='danger'/>
129
129
  };
130
130
  let iconType: React.ReactNode = iconMap[type];
131
131
  const iconCls = cls({
@@ -0,0 +1,62 @@
1
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
2
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
3
+ import React, { ReactNode } from "react";
4
+ import cls from 'classnames';
5
+ import { cssClasses } from '@douyinfe/semi-foundation/carousel/constants';
6
+ import { CarouselArrowProps } from "./interface";
7
+ import { IconChevronLeft, IconChevronRight } from "@douyinfe/semi-icons";
8
+ import { get, throttle } from 'lodash';
9
+
10
+ class CarouselArrow extends React.PureComponent<CarouselArrowProps> {
11
+ renderLeftIcon = () => {
12
+ return get(this.props, 'arrowProps.leftArrow.children', <IconChevronLeft aria-label="Previous index" size="inherit"/>);
13
+ }
14
+
15
+ renderRightIcon = () => {
16
+ return get(this.props, 'arrowProps.rightArrow.children', <IconChevronRight aria-label="Next index" size="inherit"/>);
17
+ }
18
+
19
+ render(): ReactNode {
20
+ const { type, theme, prev, next, timing } = this.props;
21
+ const classNames = cls( {
22
+ [cssClasses.CAROUSEL_ARROW]: true,
23
+ [`${cssClasses.CAROUSEL_ARROW}-${theme}`]: theme,
24
+ [`${cssClasses.CAROUSEL_ARROW}-hover`]: type === 'hover',
25
+ });
26
+
27
+ const leftClassNames = cls( {
28
+ [`${cssClasses.CAROUSEL_ARROW}-prev`]: true,
29
+ [`${cssClasses.CAROUSEL_ARROW}-${theme}`]: theme,
30
+ });
31
+
32
+ const rightClassNames = cls( {
33
+ [`${cssClasses.CAROUSEL_ARROW}-next`]: true,
34
+ [`${cssClasses.CAROUSEL_ARROW}-${theme}`]: theme,
35
+ });
36
+
37
+ return (
38
+ <div className={classNames}>
39
+ <div
40
+ // role='button'
41
+ className={leftClassNames}
42
+ onClick={throttle(prev, timing)}
43
+ {...get(this.props, 'arrowProps.leftArrow.props')}
44
+ >
45
+ {this.renderLeftIcon()}
46
+ </div>
47
+ <div
48
+ // role='button'
49
+ // tabIndex={0}
50
+ className={rightClassNames}
51
+ onClick={throttle(next, timing)}
52
+ {...get(this.props, 'arrowProps.rightArrow.props')}
53
+ >
54
+ {this.renderRightIcon()}
55
+ </div>
56
+ </div>
57
+ );
58
+ }
59
+
60
+ }
61
+
62
+ export default CarouselArrow;
@@ -0,0 +1,84 @@
1
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
2
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
3
+ import React, { ReactNode } from "react";
4
+ import cls from 'classnames';
5
+ import PropTypes from 'prop-types';
6
+ import { cssClasses, strings } from '@douyinfe/semi-foundation/carousel/constants';
7
+ import { CarouselIndicatorProps } from "./interface";
8
+ import getDataAttr from "@douyinfe/semi-foundation/utils/getDataAttr";
9
+ import { throttle } from 'lodash';
10
+
11
+ class CarouselIndicator extends React.PureComponent<CarouselIndicatorProps> {
12
+ static propTypes = {
13
+ activeKey: PropTypes.number,
14
+ className: PropTypes.string,
15
+ position: PropTypes.oneOf(strings.POSITION_MAP),
16
+ size: PropTypes.oneOf(strings.SIZE),
17
+ style: PropTypes.object,
18
+ theme: PropTypes.oneOf(strings.THEME_MAP),
19
+ total: PropTypes.number,
20
+ onIndicatorChange: PropTypes.func,
21
+ type: PropTypes.oneOf(strings.TYPE_MAP),
22
+ trigger: PropTypes.oneOf(strings.TRIGGER)
23
+ };
24
+
25
+ onIndicatorChange = (activeIndex: number): void => {
26
+ this.props.onIndicatorChange(activeIndex);
27
+ };
28
+
29
+ handleIndicatorClick = (activeIndex: number): void => {
30
+ const { trigger } = this.props;
31
+ if (trigger === 'click'){
32
+ this.onIndicatorChange(activeIndex);
33
+ }
34
+ }
35
+
36
+ handleIndicatorHover = (activeIndex: number): void => {
37
+ const { trigger } = this.props;
38
+ if (trigger === 'hover'){
39
+ this.onIndicatorChange(activeIndex);
40
+ }
41
+ }
42
+
43
+ renderIndicatorContent(): ReactNode {
44
+ const { total, theme, size, activeIndex } = this.props;
45
+ const indicatorContent: ReactNode[] = [];
46
+ for (let i = 0; i < total; i++) {
47
+ indicatorContent.push(
48
+ <span
49
+ // role='none'
50
+ key={i}
51
+ data-index={i}
52
+ className={cls([`${cssClasses.CAROUSEL_INDICATOR}-item`], {
53
+ [`${cssClasses.CAROUSEL_INDICATOR}-item-active`]: i === activeIndex,
54
+ [`${cssClasses.CAROUSEL_INDICATOR}-item-${theme}`]: theme,
55
+ [`${cssClasses.CAROUSEL_INDICATOR}-item-${size}`]: size,
56
+ })}
57
+ onClick={()=>this.handleIndicatorClick(i)}
58
+ onMouseEnter={()=>this.handleIndicatorHover(i)}
59
+ ></span>
60
+ );
61
+ }
62
+ return indicatorContent;
63
+ }
64
+
65
+ render(): ReactNode {
66
+ const { type, size, theme, style, className, position, ...restProps } = this.props;
67
+ const classNames = cls(className, {
68
+ [cssClasses.CAROUSEL_INDICATOR]: true,
69
+ [`${cssClasses.CAROUSEL_INDICATOR}-${type}`]: type,
70
+ [`${cssClasses.CAROUSEL_INDICATOR}-${position}`]: position,
71
+ });
72
+
73
+ const indicatorContent = this.renderIndicatorContent();
74
+
75
+ return (
76
+ <div className={classNames} style={style} {...getDataAttr(restProps)}>
77
+ {indicatorContent}
78
+ </div>
79
+ );
80
+ }
81
+
82
+ }
83
+
84
+ export default CarouselIndicator;
@@ -0,0 +1,159 @@
1
+ import { Carousel } from '../../index';
2
+ import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
3
+
4
+
5
+ function getCarousel(carouselProps) {
6
+ const contentStyle = {
7
+ display:'flex',
8
+ justifyContent: 'center',
9
+ alignItems: 'center',
10
+ color: '#fff',
11
+ background: 'lightBlue',
12
+ };
13
+
14
+ return <Carousel style={{ width: '600px', height: '240px'}} {...carouselProps}>
15
+ <div style={contentStyle}>
16
+ <h3>index0</h3>
17
+ </div>
18
+ <div style={contentStyle}>
19
+ <h3>index1</h3>
20
+ </div>
21
+ <div style={contentStyle}>
22
+ <h3>index2</h3>
23
+ </div>
24
+ </Carousel>
25
+ }
26
+
27
+ function getSingleCarousel(carouselProps) {
28
+ const contentStyle = {
29
+ display:'flex',
30
+ justifyContent: 'center',
31
+ alignItems: 'center',
32
+ color: '#fff',
33
+ background: 'lightBlue',
34
+ };
35
+
36
+ return <Carousel style={{ width: '600px', height: '240px'}} {...carouselProps}>
37
+ <div style={contentStyle}>
38
+ <h3>index0</h3>
39
+ </div>
40
+ </Carousel>
41
+ }
42
+
43
+ describe('Carousel', () => {
44
+
45
+ it('Carousel render basicly', () => {
46
+ let props = {};
47
+ const carousel = mount(getCarousel(props))
48
+ expect(carousel.find(`.${BASE_CLASS_PREFIX}-carousel-content`).children().length).toEqual(3);
49
+ expect(carousel.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text()).toEqual('index0');
50
+ carousel.unmount();
51
+ });
52
+
53
+ it('Carousel with custom className & style', () => {
54
+ let props = {
55
+ className: 'test',
56
+ style: {
57
+ color: 'red'
58
+ }
59
+ };
60
+ const carousel = shallow(getCarousel(props));
61
+ expect(carousel.exists('.test')).toEqual(true);
62
+ expect(carousel.find('div.test')).toHaveStyle('color', 'red');
63
+ });
64
+
65
+ it('Carousel with defaultActiveIndex', () => {
66
+ let props = {
67
+ defaultActiveIndex: 2
68
+ };
69
+ const carousel = mount(getCarousel(props));
70
+ const carouselContent = carousel.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text();
71
+ expect(carouselContent).toEqual('index2');
72
+ });
73
+
74
+ it('different theme', () => {
75
+ let primary = mount(getCarousel({ theme: 'primary' }));
76
+ let light = mount(getCarousel({ theme: 'light' }));
77
+ let dark = mount(getCarousel({ theme: 'dark' }));
78
+ expect(primary.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow-primary`)).toEqual(true);
79
+ expect(primary.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-primary`)).toEqual(true);
80
+ expect(light.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow-light`)).toEqual(true);
81
+ expect(light.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-light`)).toEqual(true);
82
+ expect(dark.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow-dark`)).toEqual(true);
83
+ expect(dark.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-dark`)).toEqual(true);
84
+ });
85
+
86
+ it('different indicator type', () => {
87
+ let dot = mount(getCarousel({ indicatorType: 'dot' }));
88
+ let line = mount(getCarousel({ indicatorType: 'line' }));
89
+ let columnar = mount(getCarousel({ indicatorType: 'columnar' }));
90
+ expect(dot.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-dot`)).toEqual(true);
91
+ expect(dot.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-line`)).toEqual(false);
92
+ expect(line.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-line`)).toEqual(true);
93
+ expect(line.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-columnar`)).toEqual(false);
94
+ expect(columnar.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-columnar`)).toEqual(true);
95
+ expect(columnar.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-dot`)).toEqual(false);
96
+ });
97
+
98
+ it('different indicator position', () => {
99
+ let left = mount(getCarousel({ indicatorPosition: 'left' }));
100
+ let center = mount(getCarousel({ indicatorPosition: 'center' }));
101
+ let right = mount(getCarousel({ indicatorPosition: 'right' }));
102
+ expect(left.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-left`)).toEqual(true);
103
+ expect(left.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-center`)).toEqual(false);
104
+ expect(center.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-center`)).toEqual(true);
105
+ expect(center.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-right`)).toEqual(false);
106
+ expect(right.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-right`)).toEqual(true);
107
+ expect(right.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-left`)).toEqual(false);
108
+ });
109
+
110
+ it('different indicator size', () => {
111
+ let small = mount(getCarousel({ indicatorSize: 'small' }));
112
+ let medium = mount(getCarousel({ indicatorSize: 'medium' }));
113
+ expect(small.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-small`)).toEqual(true);
114
+ expect(small.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-medium`)).toEqual(false);
115
+ expect(medium.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-medium`)).toEqual(true);
116
+ expect(medium.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator-item-small`)).toEqual(false);
117
+ });
118
+
119
+ it('show arrow and arrow change', () => {
120
+ let spyOnChange = sinon.spy(() => {})
121
+ let show = mount(getCarousel({ onChange: spyOnChange }));
122
+ let hide = mount(getCarousel({ showArrow: false }));
123
+ let hover = mount(getCarousel({ arrowType: 'hover' }));
124
+
125
+ expect(show.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow`)).toEqual(true);
126
+ expect(hide.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow`)).toEqual(false);
127
+ expect(hover.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow-hover`)).toEqual(true);
128
+
129
+ show.find(`.${BASE_CLASS_PREFIX}-carousel-arrow-prev`).simulate('click');
130
+ expect(spyOnChange.calledOnce).toBe(true);
131
+ expect(show.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text()).toEqual('index2');
132
+
133
+ show.find(`.${BASE_CLASS_PREFIX}-carousel-arrow-next`).simulate('click');
134
+ expect(show.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text()).toEqual('index0');
135
+
136
+ });
137
+
138
+ it('indicator change with click or trigger', () => {
139
+ let spyOnChange = sinon.spy(() => {})
140
+ let carousel = mount(getCarousel({ onChange: spyOnChange }));
141
+ carousel.find(`.${BASE_CLASS_PREFIX}-carousel-indicator-item`).at(2).simulate('click');
142
+ expect(spyOnChange.calledOnce).toBe(true);
143
+ expect(carousel.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text()).toEqual('index2');
144
+
145
+ let spyOnChangeHover = sinon.spy(() => {})
146
+ let carouselHover = mount(getCarousel({ onChange: spyOnChangeHover, trigger: 'hover' }));
147
+ carouselHover.find(`.${BASE_CLASS_PREFIX}-carousel-indicator-item`).at(2).simulate('mouseEnter', {});
148
+ expect(spyOnChangeHover.calledOnce).toBe(true);
149
+ expect(carouselHover.find(`.${BASE_CLASS_PREFIX}-carousel-content-item-active`).text()).toEqual('index2');
150
+ });
151
+
152
+ it('single index', () => {
153
+ let carousel = mount(getSingleCarousel({}));
154
+ expect(carousel.exists(`.${BASE_CLASS_PREFIX}-carousel-indicator`)).toEqual(false);
155
+ expect(carousel.exists(`.${BASE_CLASS_PREFIX}-carousel-arrow`)).toEqual(false);
156
+ carousel.unmount();
157
+ });
158
+
159
+ })