SideSheetTransition.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // @ts-ignore Currently there is no types definition for semi-animation-react;
  2. import { Transition } from '@douyinfe/semi-animation-react';
  3. import React, { CSSProperties } from 'react';
  4. import { Motion } from '../_base/base';
  5. export interface SideSheetTransitionProps{
  6. children?: React.ReactChildren | React.JSXElementConstructor<any>;
  7. motion?: Motion<SideSheetTransitionProps>;
  8. controlled?: boolean;
  9. visible?: boolean;
  10. placement?: 'left' | 'top' | 'right' | 'bottom';
  11. }
  12. // eslint-disable-next-line max-len
  13. const formatStyles = function formatStyles(styles: CSSProperties = {}, props: SideSheetTransitionProps = {}): CSSProperties {
  14. const { placement } = props;
  15. const { translate } = styles;
  16. const { opacity } = styles;
  17. let transform = '';
  18. switch (placement) {
  19. case 'left':
  20. transform = `translateX(-${translate}%)`;
  21. break;
  22. case 'top':
  23. transform = `translateY(-${translate}%)`;
  24. break;
  25. case 'right':
  26. transform = `translateX(${translate}%)`;
  27. break;
  28. case 'bottom':
  29. transform = `translateY(${translate}%)`;
  30. break;
  31. default:
  32. break;
  33. }
  34. return {
  35. transform,
  36. opacity,
  37. };
  38. };
  39. export default class SideSheetTransition extends React.PureComponent<SideSheetTransitionProps> {
  40. render() {
  41. let { motion = {} } = this.props;
  42. const {
  43. children,
  44. controlled = false,
  45. visible,
  46. } = this.props;
  47. if (typeof motion === 'function') {
  48. motion = motion(this.props);
  49. } else if (!motion || typeof motion !== 'object') {
  50. motion = {};
  51. }
  52. let extra = {};
  53. if (controlled) {
  54. extra = {
  55. state: visible ? 'enter' : 'leave',
  56. };
  57. }
  58. return (
  59. <Transition
  60. config={{
  61. tension: 170,
  62. friction: 14,
  63. easing: 'linear',
  64. duration: 200,
  65. }}
  66. from={{
  67. translate: 100,
  68. opacity: {
  69. val: 0,
  70. duration: 180,
  71. },
  72. }}
  73. enter={{
  74. translate: 0,
  75. opacity: {
  76. val: 1,
  77. duration: 180,
  78. },
  79. } as any}
  80. leave={{
  81. translate: 100,
  82. opacity: {
  83. val: 0,
  84. duration: 180,
  85. },
  86. } as any}
  87. {...extra}
  88. {...motion}
  89. >
  90. {/* eslint-disable-next-line max-len */}
  91. {typeof children === 'function' ? (styles: CSSProperties) => (children as (styles: CSSProperties) => any)(formatStyles(styles, this.props)) : children}
  92. </Transition>
  93. );
  94. }
  95. }