index.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  2. import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
  3. import _extends from 'babel-runtime/helpers/extends';
  4. import classnames from 'classnames';
  5. import omit from 'omit.js';
  6. import VcDrawer from '../vc-drawer/src';
  7. import PropTypes from '../_util/vue-types';
  8. import BaseMixin from '../_util/BaseMixin';
  9. import Icon from '../icon';
  10. import { getComponentFromProp, getOptionProps, getListeners } from '../_util/props-util';
  11. import { ConfigConsumerProps } from '../config-provider/configConsumerProps';
  12. import Base from '../base';
  13. var Drawer = {
  14. name: 'ADrawer',
  15. props: {
  16. closable: PropTypes.bool.def(true),
  17. destroyOnClose: PropTypes.bool,
  18. getContainer: PropTypes.any,
  19. maskClosable: PropTypes.bool.def(true),
  20. mask: PropTypes.bool.def(true),
  21. maskStyle: PropTypes.object,
  22. wrapStyle: PropTypes.object,
  23. bodyStyle: PropTypes.object,
  24. headerStyle: PropTypes.object,
  25. drawerStyle: PropTypes.object,
  26. title: PropTypes.any,
  27. visible: PropTypes.bool,
  28. width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).def(256),
  29. height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).def(256),
  30. zIndex: PropTypes.number,
  31. prefixCls: PropTypes.string,
  32. placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']).def('right'),
  33. level: PropTypes.any.def(null),
  34. wrapClassName: PropTypes.string, // not use class like react, vue will add class to root dom
  35. handle: PropTypes.any,
  36. afterVisibleChange: PropTypes.func,
  37. keyboard: PropTypes.bool.def(true)
  38. },
  39. mixins: [BaseMixin],
  40. data: function data() {
  41. this.destroyClose = false;
  42. this.preVisible = this.$props.visible;
  43. return {
  44. _push: false
  45. };
  46. },
  47. inject: {
  48. parentDrawer: {
  49. 'default': function _default() {
  50. return null;
  51. }
  52. },
  53. configProvider: { 'default': function _default() {
  54. return ConfigConsumerProps;
  55. } }
  56. },
  57. provide: function provide() {
  58. return {
  59. parentDrawer: this
  60. };
  61. },
  62. mounted: function mounted() {
  63. // fix: delete drawer in child and re-render, no push started.
  64. // <Drawer>{show && <Drawer />}</Drawer>
  65. var visible = this.visible;
  66. if (visible && this.parentDrawer) {
  67. this.parentDrawer.push();
  68. }
  69. },
  70. updated: function updated() {
  71. var _this = this;
  72. this.$nextTick(function () {
  73. if (_this.preVisible !== _this.visible && _this.parentDrawer) {
  74. if (_this.visible) {
  75. _this.parentDrawer.push();
  76. } else {
  77. _this.parentDrawer.pull();
  78. }
  79. }
  80. _this.preVisible = _this.visible;
  81. });
  82. },
  83. beforeDestroy: function beforeDestroy() {
  84. // unmount drawer in child, clear push.
  85. if (this.parentDrawer) {
  86. this.parentDrawer.pull();
  87. }
  88. },
  89. methods: {
  90. domFocus: function domFocus() {
  91. if (this.$refs.vcDrawer) {
  92. this.$refs.vcDrawer.domFocus();
  93. }
  94. },
  95. close: function close(e) {
  96. this.$emit('close', e);
  97. },
  98. // onMaskClick(e) {
  99. // if (!this.maskClosable) {
  100. // return;
  101. // }
  102. // this.close(e);
  103. // },
  104. push: function push() {
  105. this.setState({
  106. _push: true
  107. });
  108. },
  109. pull: function pull() {
  110. var _this2 = this;
  111. this.setState({
  112. _push: false
  113. }, function () {
  114. _this2.domFocus();
  115. });
  116. },
  117. onDestroyTransitionEnd: function onDestroyTransitionEnd() {
  118. var isDestroyOnClose = this.getDestroyOnClose();
  119. if (!isDestroyOnClose) {
  120. return;
  121. }
  122. if (!this.visible) {
  123. this.destroyClose = true;
  124. this.$forceUpdate();
  125. }
  126. },
  127. getDestroyOnClose: function getDestroyOnClose() {
  128. return this.destroyOnClose && !this.visible;
  129. },
  130. // get drawar push width or height
  131. getPushTransform: function getPushTransform(placement) {
  132. if (placement === 'left' || placement === 'right') {
  133. return 'translateX(' + (placement === 'left' ? 180 : -180) + 'px)';
  134. }
  135. if (placement === 'top' || placement === 'bottom') {
  136. return 'translateY(' + (placement === 'top' ? 180 : -180) + 'px)';
  137. }
  138. },
  139. getRcDrawerStyle: function getRcDrawerStyle() {
  140. var _$props = this.$props,
  141. zIndex = _$props.zIndex,
  142. placement = _$props.placement,
  143. wrapStyle = _$props.wrapStyle;
  144. var push = this.$data._push;
  145. return _extends({
  146. zIndex: zIndex,
  147. transform: push ? this.getPushTransform(placement) : undefined
  148. }, wrapStyle);
  149. },
  150. renderHeader: function renderHeader(prefixCls) {
  151. var h = this.$createElement;
  152. var _$props2 = this.$props,
  153. closable = _$props2.closable,
  154. headerStyle = _$props2.headerStyle;
  155. var title = getComponentFromProp(this, 'title');
  156. if (!title && !closable) {
  157. return null;
  158. }
  159. var headerClassName = title ? prefixCls + '-header' : prefixCls + '-header-no-title';
  160. return h(
  161. 'div',
  162. { 'class': headerClassName, style: headerStyle },
  163. [title && h(
  164. 'div',
  165. { 'class': prefixCls + '-title' },
  166. [title]
  167. ), closable ? this.renderCloseIcon(prefixCls) : null]
  168. );
  169. },
  170. renderCloseIcon: function renderCloseIcon(prefixCls) {
  171. var h = this.$createElement;
  172. var closable = this.closable;
  173. return closable && h(
  174. 'button',
  175. { key: 'closer', on: {
  176. 'click': this.close
  177. },
  178. attrs: { 'aria-label': 'Close' },
  179. 'class': prefixCls + '-close' },
  180. [h(Icon, {
  181. attrs: { type: 'close' }
  182. })]
  183. );
  184. },
  185. // render drawer body dom
  186. renderBody: function renderBody(prefixCls) {
  187. var h = this.$createElement;
  188. if (this.destroyClose && !this.visible) {
  189. return null;
  190. }
  191. this.destroyClose = false;
  192. var _$props3 = this.$props,
  193. bodyStyle = _$props3.bodyStyle,
  194. drawerStyle = _$props3.drawerStyle;
  195. var containerStyle = {};
  196. var isDestroyOnClose = this.getDestroyOnClose();
  197. if (isDestroyOnClose) {
  198. // Increase the opacity transition, delete children after closing.
  199. containerStyle.opacity = 0;
  200. containerStyle.transition = 'opacity .3s';
  201. }
  202. return h(
  203. 'div',
  204. {
  205. 'class': prefixCls + '-wrapper-body',
  206. style: _extends({}, containerStyle, drawerStyle),
  207. on: {
  208. 'transitionend': this.onDestroyTransitionEnd
  209. }
  210. },
  211. [this.renderHeader(prefixCls), h(
  212. 'div',
  213. { key: 'body', 'class': prefixCls + '-body', style: bodyStyle },
  214. [this.$slots['default']]
  215. )]
  216. );
  217. }
  218. },
  219. render: function render() {
  220. var _classnames;
  221. var h = arguments[0];
  222. var props = getOptionProps(this);
  223. var customizePrefixCls = props.prefixCls,
  224. width = props.width,
  225. height = props.height,
  226. visible = props.visible,
  227. placement = props.placement,
  228. wrapClassName = props.wrapClassName,
  229. mask = props.mask,
  230. rest = _objectWithoutProperties(props, ['prefixCls', 'width', 'height', 'visible', 'placement', 'wrapClassName', 'mask']);
  231. var haveMask = mask ? '' : 'no-mask';
  232. var offsetStyle = {};
  233. if (placement === 'left' || placement === 'right') {
  234. offsetStyle.width = typeof width === 'number' ? width + 'px' : width;
  235. } else {
  236. offsetStyle.height = typeof height === 'number' ? height + 'px' : height;
  237. }
  238. var handler = getComponentFromProp(this, 'handle') || false;
  239. var getPrefixCls = this.configProvider.getPrefixCls;
  240. var prefixCls = getPrefixCls('drawer', customizePrefixCls);
  241. var vcDrawerProps = {
  242. ref: 'vcDrawer',
  243. props: _extends({}, omit(rest, ['closable', 'destroyOnClose', 'drawerStyle', 'headerStyle', 'bodyStyle', 'title', 'push', 'visible', 'getPopupContainer', 'rootPrefixCls', 'getPrefixCls', 'renderEmpty', 'csp', 'pageHeader', 'autoInsertSpaceInButton']), {
  244. handler: handler
  245. }, offsetStyle, {
  246. prefixCls: prefixCls,
  247. open: visible,
  248. showMask: mask,
  249. placement: placement,
  250. className: classnames((_classnames = {}, _defineProperty(_classnames, wrapClassName, !!wrapClassName), _defineProperty(_classnames, haveMask, !!haveMask), _classnames)),
  251. wrapStyle: this.getRcDrawerStyle()
  252. }),
  253. on: _extends({}, getListeners(this))
  254. };
  255. return h(
  256. VcDrawer,
  257. vcDrawerProps,
  258. [this.renderBody(prefixCls)]
  259. );
  260. }
  261. };
  262. /* istanbul ignore next */
  263. Drawer.install = function (Vue) {
  264. Vue.use(Base);
  265. Vue.component(Drawer.name, Drawer);
  266. };
  267. export default Drawer;