Package detail

mui-message

liudichen104MIT1.1.0

Send messages (snackBar messages) as convenient as using antd when use MUI(@mui/material), without using hooks or creating Snackbar components frequently.

mui, material-ui, antd, snackbar

readme

mui-message

NPM version NPM downloads

English | 简体中文

使用MUI(@mui/material)时像antd一样方便地在应用里发送message(Snackbar消息),而无需频繁使用hooks或创建Snackbar组件。

本来是直接在本地应用使用,基本没问题,所以打下包发布下,后面方便直接引用。TypeScript不会用,参考着其他包添加了下类型。可能会存在一些问题。

安装

mui-message依赖于@mui/material(^5.0.0)notistack(^2.0.3),只是简单做了一点封装,改了一点默认props,相关props及message方法的第二个参数option可参考这2个库.或者直接查看notistack的文档.

基于hooks,所以需要react>=16.8.0.

采用如下命令安装:

npm i mui-message

使用

安装完毕后即可在项目里使用了,里面主要有4个导出的元素:messageRefmessageMessageBoxuseMessage

其中MessageBox是封装好的SnackbarProviderMessageProvider组件, 该组件需要放置到项目的较高层级(建议放在路由外边)。虽然其支持children,但实际可以不需要将其他组件作为它的子组件。如果其他组件作为子组件,则可在子组件中使用useMessage hook,可以获取到message实例,该实例与从mui-message直接导出的 message 是一致的。

message及其子方法(infosuccesserrorwarning)是发送消息的方法。 message.destroy方法可以用来销毁所有消息条。

也可以在此基础上进行一定的自定义。如果需要使用消息实例,如自定义action时,可以利用messageRef来获取。

注意: 同一应用只需要使用一次MessageBox组件即可。

使用时将MessageBox作为1个独立组件挂在较高层级即可,建议放在路由外层,这样就全局可以访问了.

如果你自定义了全局MUI主题,应该把该组件放在根ThemeProvider组件内部。

直接使用

在应用入口:

// App.js
import React from 'react'
import { MessageBox } from 'mui-message';

const App = () => {
    return (
      <>
        <MessageBox />
        <Router>
          // 其他内容
        </Router>
      <>
    );
}

在需要发送消息的地方,可以这样使用:

// anywhere.js
import { message } from 'mui-message'

const AnyFuncOrComponent = () => {

  // send message like:
  message('some default snackbar message');
  message.info('some info snackbar message');
  message.error('some error snackbar message');
  message.success('some success snackbar message');
  message.warning('some warning snackbar message');

  // or destroy all message:
  message.destroy();
}

使用useMessage Hook

在应用入口:

// App.js
import React from 'react'
import { MessageBox } from 'mui-message';

const App = () => {
    return (
      <>
        <MessageBox >
        <Router>
          // 其他内容
        </Router>
        </MessageBox>
      <>
    );
}

在需要发送消息的地方(应处于MessagBox内部),可以这样使用:

// anyComponet inside MessageBox.js
import { useMessage } from 'mui-message'

const AnySubComponent = () => {
  const message = useMessage();
  // send message like:
  message('some default snackbar message');
  message.info('some info snackbar message');

  // or destroy all message:
  message.destroy();
}

方法参数

messagemessage.info(及error/warning/success子方法)方法实际调用的是notistack里的enqueueSnackbarmessage.destroy调用的是closeSnackbar,所以其参数完全相同.

messagemessage.infomessage.errormessage.successmessage.warning 为生成一条snackbar消息的方法,如果当前总数量超出maxSnack数量,会进入队列。

接受2个参数:第1个参数为消息内容。第2个参数为可选的,可以用来指定variantanchorOrigin(消息位置)、autoHideDuration(自动关闭等待时间)等参数。以上几个方法实际都只是指定了相应的variant, 其中message对应 variant='default',其他方法为variant=其方法名:

  // interface:
 (message: string | ReactNode, option?: OptionsObject) => SnackbarKey;

  // use:
  message('this is a variant=default message');
  message.info('this is a variant=info message and before autohide its duration is 5 seconds',{autoHideDuration:5000});

message.destroy方法无参数,可销毁所有snackbar消息:

  // interface:
  () => void;

  // use:
  message.destroy();

MessageBox的props 及 message的option 可配置项见下面.

Props及option

MessageBox的props 及 message及其子方法的option参数与notistack相同,可以参考notistack的文档

MessageBox默认props

MessageBox的默认props如下,你可以通过props传递进行覆盖。

MessageBox.defaultProps = {
  maxSnack:3,
  autoHideDuration: 2000,
  dense: isMobile,  // 来自react-device-detect,用来判断是否为移动设备
  anchorOrigin:{
    vertical: 'top',
    horizontal: 'center',
  },
  action: (key) => {
    return (
        <IconButton key='close' aria-label='Close' color='inherit' onClick={() => {
          messageRef.current?.closeSnackbar(key);
        }}>
          <CloseIcon style={{ fontSize: '20px' }} />
        </IconButton>
    );
  },
};

props及option可配置项

MessageBox及 message的option参数支持的props或配置项(除了responsive和breapoint,这2个是自定义的,只能用于props)均与notistack相同。

<summary>可配置项部分如下:</summary> javascript MessageBox.propTypes = { /** responsive for dense?根据宽度响应式设置dense属性?与breakpoint配合使用 * @default true */ responsive: PropTypes.boolean, /** breakpoint of responsive for dense * @default 'md' */ breakpoint: Proptypes.oneOfType([ PropTypes.oneOf(['xs' , 'sm' , 'md' , 'lg' , 'xl']), PropTypes.number, ]), /** * Denser margins for snackbars. Recommended to be used on mobile devices. */ dense: PropTypes.bool, /** * Maximum snackbars that can be stacked on top of one another. * @default 3 */ maxSnack: PropTypes.number, /** * Hides iconVariant if set to `true`. * @default false */ hideIconVariant: PropTypes.bool, /** * Valid and exist HTML Node element, used to target `ReactDOM.createPortal` */ domRoot: PropTypes.elementType, /** * Override or extend the styles applied to the container component or Snackbars. */ classes: PropTypes.object, /** * The action to display. It renders after the message, at the end of the snackbar. */ action: PropTypes.oneOfType([PropTypes.node,PropTypes.func]), /** * The anchor of the `Snackbar`. * On smaller screens, the component grows to occupy all the available width, * the horizontal alignment is ignored. * @default { vertical: 'top', horizontal: 'center' } */ anchorOrigin: PropTypes.shape({ horizontal: PropTypes.oneOf(['center', 'left', 'right']).isRequired, vertical: PropTypes.oneOf(['bottom', 'top']).isRequired, }), /** * The number of milliseconds to wait before automatically calling the * `onClose` function. `onClose` should then set the state of the `open` * prop to hide the Snackbar. This behavior is disabled by default with * the `null` value. * @default 2000 */ autoHideDuration: PropTypes.number, /** * Props applied to the `ClickAwayListener` element. */ ClickAwayListenerProps: PropTypes.object, /** * If `true`, the `autoHideDuration` timer will expire even if the window is not focused. * @default false */ disableWindowBlurListener: PropTypes.bool, /** * The number of milliseconds to wait before dismissing after user interaction. * If `autoHideDuration` property isn't specified, it does nothing. * If `autoHideDuration` property is specified but `resumeHideDuration` isn't, * we use the default value. * @default autoHideDuration / 2 ms. */ resumeHideDuration:PropTypes.number, /** * The component used for the transition. (e.g. Slide, Grow, Zoom, etc.) * @default Slide */ TransitionComponent: PropTypes.elementType, /** * The duration for the transition, in milliseconds. * You may specify a single timeout for all transitions, or individually with an object. * @default { * enter: 225, * exit: 195, * } */ transitionDuration: PropTypes.oneOfType([ PropTypes.number, PropTypes.shape({ appear: PropTypes.number, enter: PropTypes.number, exit: PropTypes.number, }), ]), /** * Props applied to the transition element. * By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition/) component. * @default {} */ TransitionProps: PropTypes.object, /** * Callback fired before snackbar requests to get closed. The `reason` parameter can optionally be used to control the response to `onClose`. */ onClose: PropTypes.func, /** * Callback fired before the transition is entering. */ onEnter: PropTypes.func, /** * Callback fired when the transition has entered. */ onEntered: PropTypes.func, /** * Callback fired when the transition is entering */ onEntering: PropTypes.func, /** * Callback fired before the transition is exiting */ onExit: PropTypes.func, /** * Callback fired when the transition has exited */ onExited: PropTypes.func, /** * Callback fired when the transition is exiting. */ onExiting: PropTypes.func, /** * Ignores displaying multiple snackbars with the same `message` * @default false */ preventDuplicate: PropTypes.bool, /** * Used to easily display different variant of snackbars. When passed to `SnackbarProvider` all snackbars inherit the `variant`, unless you override it in `enqueueSnackbar` options. * @default default */ variant: PropTypes.oneOf(['default','error','warning','success','info']), };

自定义

消息的默认配置可以直接通过给MessageBox组件传递相关props来直接配置:

通过MessagBox进行全局配置

通过MessageBox的props可以进行全局配置,如:

  <MessageBox
    maxSnack={4}  // customize max count of messages that can show  at the same time
    { ...otherProps }
  />

如果需要使用SnackbarContext实例(比如自定义action时),可通过messageRef获取。

option临时配置

也可在使用message、message.info等方法的option临时配置一条消息.

  message.error('something is error',{ autoHideDuration:5000, });

使用Ref

在需自定义action prop 等需要使用snackbar实例时可以通过导出的messageRef获取,可以获取到closeSnackbarenqueueSnackbar等来自notistack的一些方法和属性:

  import ( messageRef, MessagBox ) from 'mui-message'
  const action = (key) => {
    return (
        <IconButton key='close' aria-label='Close' color='inherit' onClick={() => {
          messageRef.current?.closeSnackbar(key);
        }}>
          <CloseIcon style={{ fontSize: '20px' }} />
        </IconButton>
    );
  };

  const App = () => {
    return (
      <>
        <MessageBox
          action={action}
        />
        <RouterOrSomething>
          // app content
        </RouterOrSomething>
      </>
    );
  };