dayCol.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* eslint-disable max-len */
  2. import React from 'react';
  3. import cls from 'classnames';
  4. import PropTypes from 'prop-types';
  5. import CalendarFoundation, { CalendarAdapter } from '@douyinfe/semi-foundation/calendar/foundation';
  6. import { cssClasses } from '@douyinfe/semi-foundation/calendar/constants';
  7. import BaseComponent from '../_base/baseComponent';
  8. import localeContext from '../locale/context';
  9. import { DayColProps } from './interface';
  10. import '@douyinfe/semi-foundation/calendar/calendar.scss';
  11. const prefixCls = `${cssClasses.PREFIX}-grid`;
  12. function pad(d: number) {
  13. return (d < 10) ? `0${ d.toString()}` : d.toString();
  14. }
  15. export interface DayColState {
  16. currPos: number;
  17. showCurrTime: boolean;
  18. }
  19. export default class DayCol extends BaseComponent<DayColProps, DayColState> {
  20. static propTypes = {
  21. events: PropTypes.array,
  22. displayValue: PropTypes.instanceOf(Date),
  23. showCurrTime: PropTypes.bool,
  24. scrollHeight: PropTypes.number,
  25. currPos: PropTypes.number,
  26. handleClick: PropTypes.func,
  27. mode: PropTypes.string,
  28. isWeekend: PropTypes.bool,
  29. dateGridRender: PropTypes.func,
  30. };
  31. static defaultProps = {
  32. events: [] as DayColProps['events'],
  33. showCurrTime: true,
  34. scrollHeight: 0,
  35. currPos: 0,
  36. mode: 'dayCol'
  37. };
  38. static contextType = localeContext;
  39. foundation: CalendarFoundation;
  40. constructor(props: DayColProps) {
  41. super(props);
  42. this.state = {
  43. currPos: 0,
  44. showCurrTime: false,
  45. };
  46. this.foundation = new CalendarFoundation(this.adapter);
  47. }
  48. componentDidMount() {
  49. this.foundation.init();
  50. this.foundation.initCurrTime();
  51. }
  52. componentWillUnmount() {
  53. this.foundation.destroy();
  54. }
  55. get adapter(): CalendarAdapter<DayColProps, DayColState> {
  56. return {
  57. ...super.adapter,
  58. updateCurrPos: currPos => {
  59. this.setState({ currPos });
  60. },
  61. updateShowCurrTime: () => {
  62. this.setState({ showCurrTime: true });
  63. },
  64. };
  65. }
  66. renderEvents = () => {
  67. const { events, scrollHeight } = this.props;
  68. const list = events.map((event, ind) => {
  69. const { startPos, endPos, children, key } = event;
  70. const top = startPos * scrollHeight;
  71. const height = (endPos - startPos) * scrollHeight;
  72. if (!height) {
  73. return undefined;
  74. }
  75. const style = {
  76. top: `${top}px`,
  77. height: `${height}px`,
  78. };
  79. return (
  80. <li className={`${cssClasses.PREFIX}-event-item ${cssClasses.PREFIX}-event-day`} style={style} key={key || `${top}-${ind}`}>
  81. {children}
  82. </li>
  83. );
  84. });
  85. return list;
  86. };
  87. renderCurrTime = () => {
  88. const { currPos } = this.state;
  89. const { scrollHeight } = this.props;
  90. const key = currPos;
  91. const top = currPos * scrollHeight;
  92. const style = { top };
  93. const circle = (<div className={`${prefixCls}-curr-circle`} style={style} />);
  94. const line = (<div className={`${prefixCls}-curr-line`} style={style} />);
  95. return (
  96. <React.Fragment key={key}>
  97. {circle}
  98. {line}
  99. </React.Fragment>
  100. );
  101. };
  102. handleClick: DayColProps['handleClick'] = (e, val) => {
  103. this.props.handleClick(e, val);
  104. };
  105. renderGrid = () => {
  106. const showCurrTime = this.props.showCurrTime ? this.state.showCurrTime : false;
  107. const { displayValue, isWeekend, dateGridRender } = this.props;
  108. const skCls = cls(`${prefixCls}-skeleton`, {
  109. [`${cssClasses.PREFIX}-weekend`]: isWeekend,
  110. });
  111. return (
  112. <div className={`${prefixCls}`} role="presentation">
  113. <div role="gridcell" className={`${prefixCls}-content`}>
  114. {showCurrTime ? this.renderCurrTime() : null}
  115. <ul role="row" className={skCls}>
  116. {[...Array(25).keys()].map(item => {
  117. const line = cls({
  118. [`${prefixCls}-skeleton-row-line`]: true,
  119. });
  120. return (
  121. <React.Fragment key={`${item}-daycol`}>
  122. <li data-time={`${pad(item)}:00:00`} className={line} onClick={e => this.handleClick(e, [displayValue, item, 0, 0])} />
  123. <li data-time={`${pad(item)}:30:00`} onClick={e => this.handleClick(e, [displayValue, item, 30, 0])} />
  124. </React.Fragment>
  125. );
  126. })}
  127. </ul>
  128. {dateGridRender && dateGridRender(displayValue.toString(), displayValue)}
  129. <ul className={`${cssClasses.PREFIX}-event-items`}>
  130. {this.renderEvents()}
  131. </ul>
  132. </div>
  133. </div>
  134. );
  135. };
  136. render() {
  137. const grid = this.renderGrid();
  138. return grid;
  139. }
  140. }