Просмотр исходного кода

style(replay): fix PanelTable border styles (#68036)

Fixing a couple style issues with the replay table:

## 1. Weird hover behavior was happening on the first replay in the
table

Resulting from leftover behavior from issue details inline player on the
replay tab.


https://github.com/getsentry/sentry/assets/56095982/ea844520-737a-487f-9913-685e16dabd04

Fixed by applying separate styles if the `referrerLocation ===
'replay'`:


https://github.com/getsentry/sentry/assets/56095982/dfc7f8bd-7021-4543-b981-156875eb8597

## 2. The `PanelTable` wasn't filling out the `border-bottom` on header
completely

Was happening on replay index & issues too. Notice also the double
border at the bottom of both tables.

<img width="1261" alt="SCR-20240401-lxqw"
src="https://github.com/getsentry/sentry/assets/56095982/9f8ac8d5-541e-48a6-bd01-918e94f58e25">

<img width="1253" alt="SCR-20240401-mmpt"
src="https://github.com/getsentry/sentry/assets/56095982/de2760c7-6430-4dad-9570-d36ab1bc353b">

Something weird was happening with the `nth-last-child(n + ...)` style
inside `PanelTable`. It seems to work for all other `PanelTable` uses
throughout Sentry, so I'm thinking it's something to do with the new
styles applied from the inline player on the replay table.

Rather than messing with these styles, I decided to fix this by adding a
prop to `PanelTable` that allows disabling the header bottom border.
Then in our replay table `<Row>` style we apply a `border-top` instead.
This also gets rid of the double border that was showing up on the
bottom of the replay tables up until now.
 
<img width="1274" alt="SCR-20240401-mqkp"
src="https://github.com/getsentry/sentry/assets/56095982/95ca14a4-d9c4-418d-97a2-f11f240734f9">



<img width="1271" alt="SCR-20240401-mmkg"
src="https://github.com/getsentry/sentry/assets/56095982/9c87eda5-997e-4f61-9922-b0fa1ac05f10">
Michelle Zhang 11 месяцев назад
Родитель
Сommit
f92d9f4465

+ 13 - 3
static/app/components/panels/panelTable.tsx

@@ -20,6 +20,10 @@ type PanelTableProps = {
    */
   children?: React.ReactNode | (() => React.ReactNode);
   className?: string;
+  /**
+   * If true, disables the border-bottom on the header
+   */
+  disableHeaderBorderBottom?: boolean;
   /**
    * Renders without predefined padding on the header and body cells
    */
@@ -77,6 +81,7 @@ const PanelTable = forwardRef<HTMLDivElement, PanelTableProps>(function PanelTab
     emptyAction,
     loader,
     stickyHeaders = false,
+    disableHeaderBorderBottom = false,
     ...props
   }: PanelTableProps,
   ref: React.Ref<HTMLDivElement>
@@ -92,6 +97,7 @@ const PanelTable = forwardRef<HTMLDivElement, PanelTableProps>(function PanelTab
       disablePadding={disablePadding}
       className={className}
       hasRows={shouldShowContent}
+      disableHeaderBorderBottom={disableHeaderBorderBottom}
       {...props}
     >
       {headers.map((header, i) => (
@@ -129,6 +135,7 @@ type WrapperProps = {
    * The number of columns the table will have, this is derived from the headers list
    */
   columns: number;
+  disableHeaderBorderBottom: boolean;
   disablePadding: PanelTableProps['disablePadding'];
   hasRows: boolean;
 };
@@ -146,9 +153,12 @@ const Wrapper = styled(Panel, {
   > * {
     ${p => (p.disablePadding ? '' : `padding: ${space(2)};`)}
 
-    &:nth-last-child(n + ${p => (p.hasRows ? p.columns + 1 : 0)}) {
-      border-bottom: 1px solid ${p => p.theme.border};
-    }
+    ${p =>
+      p.disableHeaderBorderBottom
+        ? ''
+        : `&:nth-last-child(n + ${p.hasRows ? p.columns + 1 : 0}) {
+      border-bottom: 1px solid ${p.theme.border};
+    }`}
   }
 
   > ${TableEmptyStateWarning}, > ${LoadingWrapper} {

+ 19 - 7
static/app/views/replays/replayTable/index.tsx

@@ -107,6 +107,7 @@ const ReplayTable = memo(
         emptyMessage={emptyMessage}
         gridRows={isFetching ? undefined : gridRows}
         loader={<LoadingIndicator style={{margin: '54px auto'}} />}
+        disableHeaderBorderBottom
       >
         {replays?.map(
           (replay: ReplayListRecord | ReplayListRecordWithTx, index: number) => {
@@ -116,6 +117,7 @@ const ReplayTable = memo(
                 isPlaying={index === selectedReplayIndex && referrerLocation !== 'replay'}
                 onClick={() => onClickPlay?.(index)}
                 showCursor={onClickPlay !== undefined}
+                referrerLocation={referrerLocation}
               >
                 {visibleColumns.map(column => {
                   switch (column) {
@@ -248,16 +250,26 @@ const StyledAlert = styled(Alert)`
   margin-bottom: 0;
 `;
 
-const Row = styled('div')<{isPlaying?: boolean; showCursor?: boolean}>`
-  display: contents;
+const Row = styled('div')<{
+  isPlaying?: boolean;
+  referrerLocation?: string;
+  showCursor?: boolean;
+}>`
+  ${p =>
+    p.referrerLocation === 'replay'
+      ? `display: contents;
+         & > * {
+          border-top: 1px solid ${p.theme.border};
+          }`
+      : `display: contents;
   & > * {
-    background-color: ${p => (p.isPlaying ? p.theme.translucentInnerBorder : 'inherit')};
-    border-bottom: 1px solid ${p => p.theme.border};
-    cursor: ${p => (p.showCursor ? 'pointer' : 'default')};
+    background-color: ${p.isPlaying ? p.theme.translucentInnerBorder : 'inherit'};
+    border-top: 1px solid ${p.theme.border};
+    cursor: ${p.showCursor ? 'pointer' : 'default'};
   }
   :hover {
-    background-color: ${p => (p.showCursor ? p.theme.translucentInnerBorder : 'inherit')};
-  }
+    background-color: ${p.showCursor ? p.theme.translucentInnerBorder : 'inherit'};
+  }`}
 `;
 
 export default ReplayTable;