1. import React,{PropTypes} from 'react';
  2. import Component from '../utils/Component';
  3. import classnames from 'classnames';
  4. import {setPhoenixPrefix} from '../utils/Tool';
  5.  
  6. import Animate from '../Animate';
  7. import Icon from '../Icon';
  8.  
  9. /**
  10. * 菜单内容组件<br/>
  11. * - 通过placement设置菜单出现的位置和类型, 可选 [top,left,right,left-full,right-full,full-screen]。
  12. * - 可通过width设置侧边菜单的宽度, 当前placement为top和full-screen不生效。
  13. * - 可通过closeButton来配置菜单主体右上角X按钮是否显示。
  14. *
  15. * 主要属性和接口:
  16. * - placement:菜单出现的位置和类型, 默认top。
  17. * - width:侧边菜单的宽度, 当前placement为top和full-screen不生效。
  18. * - closeButton:菜单主体右上角X按钮是否显示, 默认不显示。<br/>
  19. * 如:
  20. * ```code
  21. * <Menu>
  22. * <Menu.Header>
  23. * 标题一
  24. * </Menu.Header>
  25. * <Menu.Body width={60} placement="left" closeButton>
  26. * ...
  27. * </Menu.Body>
  28. * </Menu>
  29. * ```
  30. *
  31. * @class MenuBody
  32. * @module 菜单组件
  33. * @extends Component
  34. * @constructor
  35. * @since 1.3.0
  36. * @demo menu|menu.js {展示}
  37. * @show true
  38. * */
  39. export default class MenuBody extends Component{
  40. static propTypes = {
  41. /**
  42. * 样式前缀
  43. * @property classPrefix
  44. * @type String
  45. * @default 'menu-body'
  46. * */
  47. classPrefix: PropTypes.string,
  48. /**
  49. * 菜单位置, 可选[top,left,right,left-full,right-full,full-screen], 默认top
  50. * @property placement
  51. * @type String
  52. * @default 'top'
  53. * */
  54. placement: PropTypes.string,
  55. /**
  56. * 自定义菜单宽度百分比(限左右)
  57. * @property width
  58. * @type Number
  59. * @default 50
  60. * */
  61. width: PropTypes.number,
  62. // closeMode: PropTypes.string,
  63. /**
  64. * 右上角按钮是否可见, 默认不可见
  65. * @property closeButton
  66. * @type Boolean
  67. * */
  68. closeButton: PropTypes.bool,
  69. };
  70.  
  71. static defaultProps = {
  72. width: 50,
  73. classPrefix:'menu-body',
  74. placement: 'top',
  75. classMapping : {
  76. 'top':'top',
  77. 'left':'left',
  78. 'right':'right',
  79. 'left-full':'left-full',
  80. 'right-full':'right-full',
  81. 'full-screen':'full-screen'
  82. }
  83. };
  84.  
  85. constructor(props, context) {
  86. super(props, context);
  87. }
  88.  
  89. componentDidMount(){
  90. this.setSize();
  91. }
  92.  
  93. componentDidUpdate(){
  94. this.setSize();
  95. }
  96.  
  97. setSize(){
  98. let {visible, placement, width} = this.props;
  99.  
  100. // if(placement=="top") this.menuBodyParent.style.height = visible? this.menuBody.offsetHeight+'px' : 0;
  101.  
  102. if(this.props.visible && width){
  103. if(placement=="top") return;
  104. if(placement=="full-screen") width = 100;
  105. this.menuBodyParent.style.width = width +'%';
  106. }
  107. }
  108.  
  109. renderAnimation(){
  110. let {visible,children,className} = this.props;
  111.  
  112. if(visible){
  113. return (
  114. <div {...this.props} className={classnames(this.getProperty(true),className, 'animated')}
  115. ref={(menuBodyParent)=>{this.menuBodyParent = menuBodyParent;}}>
  116. {this.renderCloseButton()}
  117. {children}
  118. </div>
  119. );
  120. }else{
  121. return '';
  122. }
  123. }
  124.  
  125. renderCloseButton(){
  126. let {closeButton} = this.props;
  127.  
  128. if(closeButton){
  129. return <Icon phIcon="close" className={classnames(setPhoenixPrefix('menu-close-button'))} onClick={::this.onChange} />;
  130. }else{
  131. return '';
  132. }
  133. }
  134.  
  135. onChange(){
  136. this.props.changeVisible();
  137. }
  138.  
  139. render(){
  140. let {placement} = this.props;
  141. let animateName = `slide-${this.props.placement}`;
  142.  
  143. if(placement=="full-screen") animateName = "fade";
  144.  
  145. return (
  146. <Animate transitionName={animateName}>
  147. {this.renderAnimation()}
  148. </Animate>
  149. );
  150. }
  151. }