Blame view

天文台pc/tianwentai-ui/node_modules/react-remove-scroll-bar/dist/es2019/component.js 2.75 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  import * as React from 'react';
  import { styleSingleton } from 'react-style-singleton';
  import { fullWidthClassName, zeroRightClassName, noScrollbarsClassName, removedBarSizeVariable } from './constants';
  import { getGapWidth } from './utils';
  const Style = styleSingleton();
  export const lockAttribute = 'data-scroll-locked';
  // important tip - once we measure scrollBar width and remove them
  // we could not repeat this operation
  // thus we are using style-singleton - only the first "yet correct" style will be applied.
  const getStyles = ({ left, top, right, gap }, allowRelative, gapMode = 'margin', important) => `
    .${noScrollbarsClassName} {
     overflow: hidden ${important};
     padding-right: ${gap}px ${important};
    }
    body[${lockAttribute}] {
      overflow: hidden ${important};
      overscroll-behavior: contain;
      ${[
      allowRelative && `position: relative ${important};`,
      gapMode === 'margin' &&
          `
      padding-left: ${left}px;
      padding-top: ${top}px;
      padding-right: ${right}px;
      margin-left:0;
      margin-top:0;
      margin-right: ${gap}px ${important};
      `,
      gapMode === 'padding' && `padding-right: ${gap}px ${important};`,
  ]
      .filter(Boolean)
      .join('')}
    }
    
    .${zeroRightClassName} {
      right: ${gap}px ${important};
    }
    
    .${fullWidthClassName} {
      margin-right: ${gap}px ${important};
    }
    
    .${zeroRightClassName} .${zeroRightClassName} {
      right: 0 ${important};
    }
    
    .${fullWidthClassName} .${fullWidthClassName} {
      margin-right: 0 ${important};
    }
    
    body[${lockAttribute}] {
      ${removedBarSizeVariable}: ${gap}px;
    }
  `;
  const getCurrentUseCounter = () => {
      const counter = parseInt(document.body.getAttribute(lockAttribute) || '0', 10);
      return isFinite(counter) ? counter : 0;
  };
  export const useLockAttribute = () => {
      React.useEffect(() => {
          document.body.setAttribute(lockAttribute, (getCurrentUseCounter() + 1).toString());
          return () => {
              const newCounter = getCurrentUseCounter() - 1;
              if (newCounter <= 0) {
                  document.body.removeAttribute(lockAttribute);
              }
              else {
                  document.body.setAttribute(lockAttribute, newCounter.toString());
              }
          };
      }, []);
  };
  /**
   * Removes page scrollbar and blocks page scroll when mounted
   */
  export const RemoveScrollBar = ({ noRelative, noImportant, gapMode = 'margin' }) => {
      useLockAttribute();
      /*
       gap will be measured on every component mount
       however it will be used only by the "first" invocation
       due to singleton nature of <Style
       */
      const gap = React.useMemo(() => getGapWidth(gapMode), [gapMode]);
      return React.createElement(Style, { styles: getStyles(gap, !noRelative, gapMode, !noImportant ? '!important' : '') });
  };