component.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import * as React from 'react';
  2. import { styleSingleton } from 'react-style-singleton';
  3. import { fullWidthClassName, zeroRightClassName, noScrollbarsClassName, removedBarSizeVariable } from './constants';
  4. import { getGapWidth } from './utils';
  5. var Style = styleSingleton();
  6. export var lockAttribute = 'data-scroll-locked';
  7. // important tip - once we measure scrollBar width and remove them
  8. // we could not repeat this operation
  9. // thus we are using style-singleton - only the first "yet correct" style will be applied.
  10. var getStyles = function (_a, allowRelative, gapMode, important) {
  11. var left = _a.left, top = _a.top, right = _a.right, gap = _a.gap;
  12. if (gapMode === void 0) { gapMode = 'margin'; }
  13. return "\n .".concat(noScrollbarsClassName, " {\n overflow: hidden ").concat(important, ";\n padding-right: ").concat(gap, "px ").concat(important, ";\n }\n body[").concat(lockAttribute, "] {\n overflow: hidden ").concat(important, ";\n overscroll-behavior: contain;\n ").concat([
  14. allowRelative && "position: relative ".concat(important, ";"),
  15. gapMode === 'margin' &&
  16. "\n padding-left: ".concat(left, "px;\n padding-top: ").concat(top, "px;\n padding-right: ").concat(right, "px;\n margin-left:0;\n margin-top:0;\n margin-right: ").concat(gap, "px ").concat(important, ";\n "),
  17. gapMode === 'padding' && "padding-right: ".concat(gap, "px ").concat(important, ";"),
  18. ]
  19. .filter(Boolean)
  20. .join(''), "\n }\n \n .").concat(zeroRightClassName, " {\n right: ").concat(gap, "px ").concat(important, ";\n }\n \n .").concat(fullWidthClassName, " {\n margin-right: ").concat(gap, "px ").concat(important, ";\n }\n \n .").concat(zeroRightClassName, " .").concat(zeroRightClassName, " {\n right: 0 ").concat(important, ";\n }\n \n .").concat(fullWidthClassName, " .").concat(fullWidthClassName, " {\n margin-right: 0 ").concat(important, ";\n }\n \n body[").concat(lockAttribute, "] {\n ").concat(removedBarSizeVariable, ": ").concat(gap, "px;\n }\n");
  21. };
  22. /**
  23. * Removes page scrollbar and blocks page scroll when mounted
  24. */
  25. export var RemoveScrollBar = function (props) {
  26. var noRelative = props.noRelative, noImportant = props.noImportant, _a = props.gapMode, gapMode = _a === void 0 ? 'margin' : _a;
  27. /*
  28. gap will be measured on every component mount
  29. however it will be used only by the "first" invocation
  30. due to singleton nature of <Style
  31. */
  32. var gap = React.useMemo(function () { return getGapWidth(gapMode); }, [gapMode]);
  33. React.useEffect(function () {
  34. document.body.setAttribute(lockAttribute, '');
  35. return function () {
  36. document.body.removeAttribute(lockAttribute);
  37. };
  38. }, []);
  39. return React.createElement(Style, { styles: getStyles(gap, !noRelative, gapMode, !noImportant ? '!important' : '') });
  40. };