Repository: Tencent/tdesign-mobile-vue (ts)

Issue:
[Popover] 弹窗被遮挡以及弹窗箭头位置没对齐
### tdesign-mobile-vue 版本

1.0.5

### 重现链接

https://stackblitz.com/edit/b2lmx7-tzf1r6?file=src%2Fdemo.vue

### 重现步骤

1. 第一次点击时会出现弹窗内容被遮挡问题
<img width="536" alt="image" src="https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/aee979d1-507c-4ed0-9f8a-d5bd086e82bc">

2. 当文本较长时，箭头位置没有对齐
<img width="521" alt="image" src="https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/21cad3b1-28e4-4c60-978f-c2ee948565f4">


### 期望结果

1. 第一次点击时弹窗不被遮挡。
2. 箭头位置可以指向按钮

### 实际结果

1. 第一次点击时会出现弹窗被遮挡问题
2. 当文本较长时，箭头位置没有对齐

### 框架版本

Vue(3.2.0)

### 浏览器版本

Chrome(117.0.5938.149)

### 系统版本

MacOS

### Node版本

16.17.0

### 补充说明

_No response_
## IssueShoot
- 预估时长: 3
- 期望完成时间: 2023-10-23 00:00:00 +0000 UTC
- 开发难度: 中
- 参与人数: 1
- 需求对接人: anlyyao
- 验收标准: 实现期望改造效果，提 PR 并通过验收无误
- 备注: 最终激励以实际提交 `pull request` 并合并为准

Pull request description:
fix(popover): popover首次弹窗被遮挡和箭头优化
<!--
首先，感谢你的贡献！😄
请阅读并遵循 [TDesign 贡献指南](https://github.com/Tencent/tdesign/blob/main/docs/contributing.md)，填写以下 pull request 的信息。
PR 在维护者审核通过后会合并，谢谢！
-->

### 🤔 这个 PR 的性质是？

- [x] 日常 bug 修复
- [ ] 新特性提交
- [ ] 文档改进
- [ ] 演示代码改进
- [ ] 组件样式/交互改进
- [ ] CI/CD 改进
- [ ] 重构
- [ ] 代码风格优化
- [ ] 测试用例
- [ ] 分支合并
- [ ] 其他

### 🔗 相关 Issue

fix #1127 

<!--
1. 描述相关需求的来源，如相关的 issue 讨论链接。
-->

### 💡 需求背景和解决方案

<!--
1. 要解决的具体问题。
2. 列出最终的 API 实现和用法。
3. 涉及UI/交互变动需要有截图或 GIF。
-->

1. popover首次弹窗被遮挡： updatePopper 增加 currentVisible的判断
2. 箭头优化：
    使用popperjs的arrow配置，由popperjs来处理arrow位置： https://popper.js.org/docs/v2/modifiers/arrow/

    popperjs的arrow，默认是居中显示， 所以在配置top/left/right/bottom, 直接使用popperjs默认的配置。文本较长时，箭头是居中显示：
   
![image](https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/d9417bb9-1950-4bed-85fd-24454cb92849)

   其他方向使用padding配置偏移。

    right-top/right-bottom/left-top/left-bottom，纵向偏移配置top和bottom, 是相对popper高度偏移
![image](https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/af5c59c2-a81f-4c69-84d0-36752c983cc7)

    top-left/top-right/bottom-left/bottom-right，横向偏移配置left和right, 是相对popper宽度偏移， 同时考虑超过空间的情况
![image](https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/75e473b7-d697-47e6-8caa-aa495a004f56)

 
![image](https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/f3a0d0b9-0650-4362-9fc9-8423526e8212)

![image](https://github.com/Tencent/tdesign-mobile-vue/assets/13745660/97dd7117-c68c-47c3-95f5-44d6d70f7b36)

### 📝 更新日志

<!--
从用户角度描述具体变化，以及可能的 breaking change 和其他风险。
-->

- fix(Popover): 修复气泡首次弹出被遮挡的问题以及优化箭头

- [ ] 本条 PR 不需要纳入 Changelog

### ☑️ 请求合并前的自查清单

⚠️ 请自检并全部**勾选全部选项**。⚠️

- [x] 文档已补充或无须补充
- [x] 代码演示已提供或无须提供
- [x] TypeScript 定义已补充或无须补充
- [x] Changelog 已提供或无须提供



Patch:
diff --git a/src/popover/popover.vue b/src/popover/popover.vue
index aa835992..8498405d 100644
--- a/src/popover/popover.vue
+++ b/src/popover/popover.vue
@@ -7,7 +7,7 @@
     <div v-show="currentVisible" ref="popoverRef" data-popper-placement :class="[`${name}`]">
       <div :class="contentClasses">
         <t-node :content="content"></t-node>
-        <div v-if="showArrow" :class="`${name}__arrow`" />
+        <div v-if="showArrow" :class="`${name}__arrow`" data-popper-arrow />
       </div>
     </div>
   </Transition>
@@ -53,11 +53,72 @@ export default defineComponent({
 
     const getPopoverOptions = () => ({
       placement: getPopperPlacement(props.placement),
+      modifiers: [
+        {
+          name: 'arrow',
+          options: {
+            padding: placementPadding,
+          },
+        },
+      ],
     });
 
+    const placementPadding = ({
+      popper,
+      reference,
+      placement,
+    }: {
+      popper: {
+        width: number;
+        height: number;
+        x: number;
+        y: number;
+      };
+      reference: {
+        width: number;
+        height: number;
+        x: number;
+        y: number;
+      };
+      placement: String;
+    }) => {
+      const horizontal = ['top', 'bottom'];
+      const vertical = ['left', 'right'];
+      const isBase = [...horizontal, ...vertical].find((item) => item === placement);
+      if (isBase) {
+        return 0;
+      }
+
+      const { width, x } = reference;
+      const { width: popperWidth, height: popperHeight } = popper;
+      const { width: windowWidth } = window.screen;
+
+      const isHorizontal = horizontal.find((item) => placement.includes(item));
+      const isEnd = placement.includes('end');
+      const small = (a: number, b: number) => {
+        return a < b ? a : b;
+      };
+
+      if (isHorizontal) {
+        const padding = isEnd ? small(width + x, popperWidth) : small(windowWidth - x, popperWidth);
+        return {
+          // border-radius: 6, arrow width: 16;
+          [isEnd ? 'left' : 'right']: padding - 22,
+        };
+      }
+
+      const isVertical = vertical.find((item) => placement.includes(item));
+      if (isVertical) {
+        return {
+          // border-radius: 6, arrow height: 16;
+          [isEnd ? 'top' : 'bottom']: popperHeight - 22,
+        };
+      }
+    };
+
     // @ts-ignore
     const updatePopper = () => {
-      if (referenceRef.value && popoverRef.value) {
+      if (currentVisible.value && referenceRef.value && popoverRef.value) {
         popper = createPopper(referenceRef.value, popoverRef.value, getPopoverOptions());
       }
       return null;
diff --git a/src/popup/demos/base.vue b/src/popup/demos/base.vue
index a6d52696..888b1e3d 100644
--- a/src/popup/demos/base.vue
+++ b/src/popup/demos/base.vue
@@ -34,4 +34,3 @@ const onClick = (item: any) => {
   }
 }
 </style>
->
diff --git a/src/popup/demos/custom-close.vue b/src/popup/demos/custom-close.vue
index 7aefec39..8a379dfa 100644
--- a/src/popup/demos/custom-close.vue
+++ b/src/popup/demos/custom-close.vue
@@ -34,4 +34,3 @@ const onClose = () => (visible.value = false);
   display: block;
 }
 </style>
->
diff --git a/src/popup/demos/with-title.vue b/src/popup/demos/with-title.vue
index b559f2ad..ade6b46d 100644
--- a/src/popup/demos/with-title.vue
+++ b/src/popup/demos/with-title.vue
@@ -52,4 +52,3 @@ const onHide = () => (visible.value = false);
   color: #0052d9;
 }
 </style>
->
diff --git a/src/table/base-table.vue b/src/table/base-table.vue
index caa2f850..e948dec9 100644
--- a/src/table/base-table.vue
+++ b/src/table/base-table.vue
@@ -39,39 +39,39 @@
           </tr>
         </thead>
         <tbody :class="tbodyClasses">
-          <tr v-if="renderContentEmpty" :class="tableBaseClass.emptyRow">
+          <tr v-if="!data?.length && renderContentEmpty" :class="tableBaseClass.emptyRow">
             <td :colspan="columns?.length">
               <div :class="tableBaseClass.empty">
                 <t-node :content="renderContentEmpty"></t-node>
               </div>
             </td>
           </tr>
-          <tr
-            v-for="(tr_item, tr_index) in data"
-            v-else
-            :key="tr_index"
-            @click="handleRowClick(tr_item, tr_index, $event)"
-          >
-            <td
-              v-for="(td_item, td_index) in columns"
-              :key="td_index"
-              :class="[
-                {
-                  [tdEllipsisClass]: td_item.ellipsis,
-                  [tdAlignClasses[`${td_item.align}`]]: td_item.align && td_item.align !== 'left',
-                },
-              ]"
-              @click="handleCellClick(tr_item, td_item, tr_index, td_index, $event)"
-            >
-              <div :class="td_item.ellipsis && ellipsisClasses">
-                <t-node
-                  :content="
-                    renderCell({ row: tr_item, col: td_item, rowIndex: tr_index, colIndex: td_index }, cellEmptyContent)
-                  "
-                ></t-node>
-              </div>
-            </td>
-          </tr>
+          <template v-else-if="data?.length">
+            <tr v-for="(tr_item, tr_index) in data" :key="tr_index" @click="handleRowClick(tr_item, tr_index, $event)">
+              <td
+                v-for="(td_item, td_index) in columns"
+                :key="td_index"
+                :class="[
+                  {
+                    [tdEllipsisClass]: td_item.ellipsis,
+                    [tdAlignClasses[`${td_item.align}`]]: td_item.align && td_item.align !== 'left',
+                  },
+                ]"
+                @click="handleCellClick(tr_item, td_item, tr_index, td_index, $event)"
+              >
+                <div :class="td_item.ellipsis && ellipsisClasses">
+                  <t-node
+                    :content="
+                      renderCell(
+                        { row: tr_item, col: td_item, rowIndex: tr_index, colIndex: td_index },
+                        cellEmptyContent,
+                      )
+                    "
+                  ></t-node>
+                </div>
+              </td>
+            </tr>
+          </template>
         </tbody>
       </table>
       <div v-if="loadingContent" :class="loadingClasses">


Test patch:
diff --git a/src/popover/__test__/__snapshots__/demo.test.jsx.snap b/src/popover/__test__/__snapshots__/demo.test.jsx.snap
index 871492cf..d16728c1 100644
--- a/src/popover/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/popover/__test__/__snapshots__/demo.test.jsx.snap
@@ -85,6 +85,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -219,6 +220,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -291,6 +293,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -335,6 +338,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -379,6 +383,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -428,6 +433,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -472,6 +478,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -516,6 +523,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
               弹出气泡内容
               <div
                 class="t-popover__arrow"
+                data-popper-arrow=""
               />
             </div>
           </div>
@@ -589,6 +597,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -633,6 +642,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -677,6 +687,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -737,6 +748,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -781,6 +793,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -825,6 +838,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 弹出气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -885,6 +899,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -929,6 +944,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -973,6 +989,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -1033,6 +1050,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -1077,6 +1095,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -1121,6 +1140,7 @@ exports[`Popover > Popover mobileVue demo works fine 1`] = `
                 气泡内容
                 <div
                   class="t-popover__arrow"
+                  data-popper-arrow=""
                 />
               </div>
             </div>
@@ -1193,6 +1213,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1237,6 +1258,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1281,6 +1303,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1341,6 +1364,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1385,6 +1409,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1429,6 +1454,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             弹出气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1489,6 +1515,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1533,6 +1560,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1577,6 +1605,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1637,6 +1666,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1681,6 +1711,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1725,6 +1756,7 @@ exports[`Popover > Popover placementVue demo works fine 1`] = `
             气泡内容
             <div
               class="t-popover__arrow"
+              data-popper-arrow=""
             />
           </div>
         </div>
@@ -1784,6 +1816,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -1828,6 +1861,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -1872,6 +1906,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -1921,6 +1956,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -1965,6 +2001,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -2009,6 +2046,7 @@ exports[`Popover > Popover themeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -2073,6 +2111,7 @@ exports[`Popover > Popover typeVue demo works fine 1`] = `
           弹出气泡内容
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>
@@ -2207,6 +2246,7 @@ exports[`Popover > Popover typeVue demo works fine 1`] = `
           
           <div
             class="t-popover__arrow"
+            data-popper-arrow=""
           />
         </div>
       </div>