Create shared PanelHeading and CollapsibleFileList components (#22995)

GitOrigin-RevId: ffe524cc0ddf6a1cf532a50f37900b1747b2afee
This commit is contained in:
Alf Eaton
2025-01-22 09:39:21 +00:00
committed by Copybot
parent 8d39ed16ef
commit 3295bd20ec
9 changed files with 126 additions and 88 deletions

View File

@@ -2,11 +2,10 @@ import { FC, memo, useState } from 'react'
import { ReviewPanelResolvedThreadsButton } from './review-panel-resolved-threads-button'
import { ReviewPanelTrackChangesMenu } from './review-panel-track-changes-menu'
import ReviewPanelTrackChangesMenuButton from './review-panel-track-changes-menu-button'
import MaterialIcon from '@/shared/components/material-icon'
import { useLayoutContext } from '@/shared/context/layout-context'
import SplitTestBadge from '@/shared/components/split-test-badge'
import { useTranslation } from 'react-i18next'
import getMeta from '@/utils/meta'
import { PanelHeading } from '@/shared/components/panel-heading'
const isReviewerRoleEnabled = getMeta('ol-isReviewerRoleEnabled')
@@ -18,25 +17,13 @@ const ReviewPanelHeader: FC = () => {
return (
<div className="review-panel-header">
<div className="review-panel-heading">
<div className="review-panel-label">
{t('review')}
<span className="review-panel-split-test-badge">
<SplitTestBadge
splitTestName="review-panel-redesign"
displayOnVariants={['enabled']}
/>
</span>
</div>
<PanelHeading
title={t('review')}
handleClose={() => setReviewPanelOpen(false)}
splitTestName="review-panel-redesign"
>
{isReviewerRoleEnabled && <ReviewPanelResolvedThreadsButton />}
<button
type="button"
className="btn review-panel-close-button"
onClick={() => setReviewPanelOpen(false)}
>
<MaterialIcon type="close" />
</button>
</div>
</PanelHeading>
{!isReviewerRoleEnabled && (
<div className="review-panel-tools">
<ReviewPanelResolvedThreadsButton />

View File

@@ -16,9 +16,9 @@ import {
} from '../../../../../types/change'
import { canAggregate } from '../utils/can-aggregate'
import MaterialIcon from '@/shared/components/material-icon'
import useOverviewFileCollapsed from '../hooks/use-overview-file-collapsed'
import { useThreadsContext } from '../context/threads-context'
import { CollapsibleFileHeader } from '@/shared/components/collapsible-file-header'
export const ReviewPanelOverviewFile: FC<{
doc: MainDocument
@@ -64,19 +64,12 @@ export const ReviewPanelOverviewFile: FC<{
return (
<>
<div>
<button
type="button"
className="review-panel-overview-file-header"
onClick={toggleCollapsed}
>
<MaterialIcon
type={collapsed ? 'keyboard_arrow_right' : 'keyboard_arrow_down'}
/>
{doc.doc.name}
<div className="review-panel-overview-file-entry-count">
{entries.length}
</div>
</button>
<CollapsibleFileHeader
name={doc.doc.name}
count={entries.length}
collapsed={collapsed}
toggleCollapsed={toggleCollapsed}
/>
{!collapsed && (
<div className="review-panel-overview-file-entries">

View File

@@ -0,0 +1,21 @@
import MaterialIcon from '@/shared/components/material-icon'
import { Dispatch, FC, SetStateAction } from 'react'
export const CollapsibleFileHeader: FC<{
name: string
count: number
collapsed: boolean
toggleCollapsed: Dispatch<SetStateAction<any>>
}> = ({ name, count, collapsed, toggleCollapsed }) => (
<button
type="button"
className="collapsible-file-header"
onClick={toggleCollapsed}
>
<MaterialIcon
type={collapsed ? 'keyboard_arrow_right' : 'keyboard_arrow_down'}
/>
{name}
<div className="collapsible-file-header-count">{count}</div>
</button>
)

View File

@@ -0,0 +1,38 @@
import { FC } from 'react'
import SplitTestBadge from '@/shared/components/split-test-badge'
import MaterialIcon from '@/shared/components/material-icon'
import { useTranslation } from 'react-i18next'
export const PanelHeading: FC<{
title: string
splitTestName?: string
children?: React.ReactNode
handleClose(): void
}> = ({ title, splitTestName, children, handleClose }) => {
const { t } = useTranslation()
return (
<div className="panel-heading">
<div className="panel-heading-label">
<span>{title}</span>
{splitTestName && (
<SplitTestBadge
splitTestName={splitTestName}
displayOnVariants={['enabled']}
/>
)}
</div>
{children}
<button
type="button"
className="btn panel-heading-close-button"
aria-label={t('close')}
onClick={handleClose}
>
<MaterialIcon type="close" />
</button>
</div>
)
}

View File

@@ -498,7 +498,7 @@
}
}
.review-panel-overview-file-header {
.collapsible-file-header {
all: unset;
padding: 6px 8px;
font-size: 14px;
@@ -524,7 +524,7 @@
padding-bottom: 6px;
}
.review-panel-overview-file-entry-count {
.collapsible-file-header-count {
background-color: @neutral-20;
padding: 2px 4px;
margin-left: auto;

View File

@@ -34,3 +34,5 @@
@import 'recurly';
@import 'dev-toolbar';
@import 'tos';
@import 'collapsible-file-header';
@import 'panel-heading';

View File

@@ -0,0 +1,18 @@
.collapsible-file-header {
all: unset;
padding: var(--spacing-03) var(--spacing-04);
font-size: var(--font-size-02);
cursor: pointer;
display: flex;
align-items: center;
gap: var(--spacing-04);
box-sizing: border-box;
width: 100%;
}
.collapsible-file-header-count {
background-color: var(--neutral-20);
padding: var(--spacing-01) var(--spacing-02);
margin-left: auto;
border-radius: var(--border-radius-base);
}

View File

@@ -0,0 +1,31 @@
.panel-heading {
display: flex;
align-items: center;
padding: var(--spacing-03) var(--spacing-02);
gap: 2px;
}
.panel-heading-label {
font-size: var(--font-size-02);
font-weight: bold;
margin: 0;
flex: 1;
text-align: start;
display: flex;
align-items: center;
gap: var(--spacing-02);
}
.panel-heading-close-button {
display: flex;
align-items: center;
border: none;
background-color: transparent;
color: var(--content-primary);
padding: var(--spacing-01);
&:hover,
&:focus {
background-color: var(--neutral-20);
}
}

View File

@@ -253,39 +253,6 @@
}
}
.review-panel-heading {
display: flex;
align-items: center;
padding: var(--spacing-03) var(--spacing-02);
gap: 2px;
.review-panel-label {
font-size: var(--font-size-02);
font-weight: bold;
margin: 0;
flex: 1;
text-align: start;
}
.review-panel-split-test-badge {
margin-left: var(--spacing-02);
}
.review-panel-close-button {
display: flex;
align-items: center;
border: none;
background-color: transparent;
color: var(--content-primary);
padding: var(--spacing-01);
&:hover,
&:focus {
background-color: var(--neutral-20);
}
}
}
&.review-panel-resolved-comments {
--bs-popover-border-width: 1px;
--bs-popover-bg: var(--bg-light-secondary);
@@ -505,18 +472,6 @@
}
}
.review-panel-overview-file-header {
all: unset;
padding: var(--spacing-03) var(--spacing-04);
font-size: var(--font-size-02);
cursor: pointer;
display: flex;
align-items: center;
gap: var(--spacing-04);
box-sizing: border-box;
width: 100%;
}
.review-panel-overfile-divider {
border-bottom: 1px solid var(--border-divider);
margin: var(--spacing-01) 0;
@@ -531,13 +486,6 @@
padding-bottom: var(--spacing-03);
}
.review-panel-overview-file-entry-count {
background-color: var(--neutral-20);
padding: var(--spacing-01) var(--spacing-02);
margin-left: auto;
border-radius: var(--border-radius-base);
}
.review-panel-footer {
position: fixed;
height: 60px;