Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

functions.web.ts 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. const LEFT_RIGHT_OFFSET = 25;
  2. const TOP_BOTTOM_OFFSET = 20;
  3. const getLeftAlignedStyle = (bounds: DOMRect) => {
  4. return {
  5. position: 'fixed',
  6. right: `${window.innerWidth - bounds.x + LEFT_RIGHT_OFFSET}px`
  7. };
  8. };
  9. const getRightAlignedStyle = (bounds: DOMRect) => {
  10. return {
  11. position: 'fixed',
  12. left: `${bounds.x + bounds.width + LEFT_RIGHT_OFFSET}px`
  13. };
  14. };
  15. const getTopAlignedStyle = (bounds: DOMRect) => {
  16. return {
  17. position: 'fixed',
  18. bottom: `${window.innerHeight - bounds.y + TOP_BOTTOM_OFFSET}px`
  19. };
  20. };
  21. const getBottomAlignedStyle = (bounds: DOMRect) => {
  22. return {
  23. position: 'fixed',
  24. top: `${bounds.y + bounds.height + TOP_BOTTOM_OFFSET}px`
  25. };
  26. };
  27. const getLeftRightStartAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
  28. return {
  29. top: `${Math.min(bounds.y + 15, window.innerHeight - size.height - 20)}px`
  30. };
  31. };
  32. const getLeftRightMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
  33. return {
  34. bottom: `${window.innerHeight - bounds.y - bounds.height - (size.height / 2)}px`
  35. };
  36. };
  37. const getLeftRightEndAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
  38. return {
  39. bottom: `${Math.min(window.innerHeight - bounds.y - bounds.height, window.innerHeight - size.height)}px`
  40. };
  41. };
  42. const getTopBotStartAlign = (bounds: DOMRect) => {
  43. return {
  44. right: `${window.innerWidth - bounds.x + 10}px`
  45. };
  46. };
  47. const getTopBotMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
  48. return {
  49. right: `${window.innerWidth - bounds.x - (size.width / 2)}px`
  50. };
  51. };
  52. const getTopBotEndAlign = (bounds: DOMRect) => {
  53. return {
  54. left: `${bounds.x + bounds.width + 10}px`
  55. };
  56. };
  57. /**
  58. * Gets the trigger element's and the context menu's bounds/size info and
  59. * computes the style to apply to the context menu to positioning it correctly
  60. * in regards to the given position info.
  61. *
  62. * @param {DOMRect} triggerBounds -The bounds info of the trigger html element.
  63. * @param {DOMRectReadOnly} dialogSize - The size info of the context menu.
  64. * @param {string} position - The position of the context menu in regards to the trigger element.
  65. *
  66. * @returns {Object} = The style to apply to context menu for positioning it correctly.
  67. */
  68. export const getContextMenuStyle = (triggerBounds: DOMRect,
  69. dialogSize: DOMRectReadOnly,
  70. position: string) => {
  71. const parsed = position.split('-');
  72. switch (parsed[0]) {
  73. case 'top': {
  74. let alignmentStyle = {};
  75. if (parsed[1]) {
  76. alignmentStyle = parsed[1] === 'start'
  77. ? getTopBotStartAlign(triggerBounds)
  78. : getTopBotEndAlign(triggerBounds);
  79. } else {
  80. alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
  81. }
  82. return {
  83. ...getTopAlignedStyle(triggerBounds),
  84. ...alignmentStyle
  85. };
  86. }
  87. case 'bottom': {
  88. let alignmentStyle = {};
  89. if (parsed[1]) {
  90. alignmentStyle = parsed[1] === 'start'
  91. ? getTopBotStartAlign(triggerBounds)
  92. : getTopBotEndAlign(triggerBounds);
  93. } else {
  94. alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
  95. }
  96. return {
  97. ...getBottomAlignedStyle(triggerBounds),
  98. ...alignmentStyle
  99. };
  100. }
  101. case 'left': {
  102. let alignmentStyle = {};
  103. if (parsed[1]) {
  104. alignmentStyle = parsed[1] === 'start'
  105. ? getLeftRightStartAlign(triggerBounds, dialogSize)
  106. : getLeftRightEndAlign(triggerBounds, dialogSize);
  107. } else {
  108. alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
  109. }
  110. return {
  111. ...getLeftAlignedStyle(triggerBounds),
  112. ...alignmentStyle
  113. };
  114. }
  115. case 'right': {
  116. let alignmentStyle = {};
  117. if (parsed[1]) {
  118. alignmentStyle = parsed[1] === 'start'
  119. ? getLeftRightStartAlign(triggerBounds, dialogSize)
  120. : getLeftRightEndAlign(triggerBounds, dialogSize);
  121. } else {
  122. alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
  123. }
  124. return {
  125. ...getRightAlignedStyle(triggerBounds),
  126. ...alignmentStyle
  127. };
  128. }
  129. default: {
  130. return {
  131. ...getLeftAlignedStyle(triggerBounds),
  132. ...getLeftRightEndAlign(triggerBounds, dialogSize)
  133. };
  134. }
  135. }
  136. };