123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /* eslint-disable max-len */
- import React from 'react';
- import cls from 'classnames';
- import PropTypes from 'prop-types';
- import Button from '../iconButton';
- import { strings, cssClasses } from '@douyinfe/semi-foundation/banner/constants';
- import BannerFoundation, { BannerAdapter } from '@douyinfe/semi-foundation/banner/foundation';
- import '@douyinfe/semi-foundation/banner/banner.scss';
- import Typography from '../typography';
- import { IconClose, IconAlertTriangle, IconInfoCircle, IconTickCircle, IconAlertCircle } from '@douyinfe/semi-icons';
- import warning from '@douyinfe/semi-foundation/utils/warning';
- import BaseComponent from '../_base/baseComponent';
- const prefixCls = cssClasses.PREFIX;
- const types = strings.TYPE;
- export type Type = 'info' | 'danger' | 'warning' | 'success';
- export interface BannerProps {
- type?: Type;
- className?: string;
- children?: React.ReactNode | undefined;
- fullMode?: boolean;
- title?: React.ReactNode;
- description?: React.ReactNode;
- icon?: string | React.ReactNode;
- closeIcon?: string | React.ReactNode;
- style?: React.CSSProperties;
- bordered?: boolean;
- onClose?: (e: React.MouseEvent) => void;
- }
- export interface BannerState {
- visible: boolean;
- }
- export default class Banner extends BaseComponent<BannerProps, BannerState> {
- static propTypes = {
- // target: PropTypes.func,
- fullMode: PropTypes.bool,
- // insertAfter: PropTypes.func,
- type: PropTypes.oneOf(types),
- title: PropTypes.node,
- description: PropTypes.node,
- icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
- closeIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
- children: PropTypes.node,
- style: PropTypes.object,
- className: PropTypes.string,
- onClose: PropTypes.func,
- bordered: PropTypes.bool,
- };
- static defaultProps = {
- // eslint-disable-next-line @typescript-eslint/no-empty-function
- onClose: () => { },
- type: 'info',
- fullMode: true,
- };
- foundation: BannerFoundation;
- constructor(props: BannerProps) {
- super(props);
- this.state = {
- visible: true,
- };
- warning(
- 'target' in this.props,
- '[Semi Banner] \'target\' has been deprecated, please write JSX directly instead.'
- );
- }
- get adapter(): BannerAdapter<BannerProps, BannerState> {
- return {
- ...super.adapter,
- setVisible: () => {
- this.setState({ visible: false });
- },
- notifyClose: (e: React.MouseEvent) => {
- const { onClose } = this.props;
- onClose(e);
- },
- };
- }
- componentDidMount() {
- this.foundation = new BannerFoundation(this.adapter);
- this.foundation.init();
- }
- componentWillUnmount() {
- this.foundation.destroy();
- }
- remove: React.MouseEventHandler = e => {
- e && e.stopPropagation();
- this.foundation.removeBanner(e);
- };
- renderCloser() {
- const { closeIcon } = this.props;
- if (closeIcon === null) {
- return closeIcon;
- }
- const closer = (
- <Button
- className={`${prefixCls}-close`}
- onClick={this.remove}
- icon={closeIcon || <IconClose />}
- theme="borderless"
- size="small"
- type="tertiary"
- aria-label='Close'
- />
- );
- return closer;
- }
- renderIcon() {
- const { type, icon } = this.props;
- const iconMap = {
- warning: <IconAlertTriangle size="large" />,
- success: <IconTickCircle size="large" />,
- info: <IconInfoCircle size="large" />,
- danger: <IconAlertCircle size="large" />
- };
- let iconType: React.ReactNode = iconMap[type];
- const iconCls = cls({
- [`${prefixCls }-icon`]: true,
- // [prefixCls + '-' + type]: true,
- });
- if (typeof icon !== 'undefined') {
- iconType = icon;
- }
- if (iconType) {
- return (
- <div className={iconCls}>
- {iconType}
- </div>
- );
- }
- return null;
- }
- render() {
- const { children, type, className, style, bordered, title, description, fullMode } = this.props;
- const { visible } = this.state;
- const wrapper = cls(prefixCls, className, {
- [`${prefixCls}-${type}`]: type,
- [`${prefixCls}-full`]: fullMode,
- [`${prefixCls}-in-container`]: !fullMode,
- [`${prefixCls}-bordered`]: !fullMode && bordered,
- });
- const banner = visible ? (
- <div className={wrapper} style={style} role="alert">
- <div className={`${prefixCls}-content-wrapper`}>
- <div className={`${prefixCls}-content`}>
- {this.renderIcon()}
- <div className={`${prefixCls}-content-body`}>
- {title ? <Typography.Title heading={5} className={`${prefixCls}-title`} component="div">{title}</Typography.Title> : null}
- {description ? <Typography.Paragraph className={`${prefixCls}-description`} component="div">{description}</Typography.Paragraph> : null}
- </div>
- </div>
- {this.renderCloser()}
- </div>
- {children ? <div className={`${prefixCls}-extra`}>{children}</div> : null}
- </div>
- ) : null;
- return banner;
- }
- }
|