Merge pull request #23082 from overleaf/dp-file-outline-typescript

Convert outline components to typescript

GitOrigin-RevId: 9fd057f70d9de7b9b209697a5d33ea72d5d64daa
This commit is contained in:
David
2025-01-27 10:02:39 +00:00
committed by Copybot
parent 8acbafcb05
commit f3077599bc
5 changed files with 42 additions and 42 deletions

View File

@@ -0,0 +1,8 @@
export type OutlineItemData = {
line: number
title: string
level?: number
children?: OutlineItemData[]
from?: number
to?: number
}

View File

@@ -1,9 +1,9 @@
import { useState, useEffect, useRef, memo } from 'react'
import PropTypes from 'prop-types'
import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed'
import classNames from 'classnames'
import OutlineList from './outline-list'
import { OutlineItemToggleButton } from '@/features/outline/components/outline-item-toggle-button'
import { OutlineItemData } from '@/features/ide-react/types/outline'
const OutlineItem = memo(function OutlineItem({
outlineItem,
@@ -11,10 +11,16 @@ const OutlineItem = memo(function OutlineItem({
highlightedLine,
matchesHighlightedLine,
containsHighlightedLine,
}: {
outlineItem: OutlineItemData
jumpToLine: (line: number, syncToPdf: boolean) => void
highlightedLine?: number | null
matchesHighlightedLine?: boolean
containsHighlightedLine?: boolean
}) {
const [expanded, setExpanded] = useState(true)
const titleElementRef = useRef()
const isHighlightedRef = useRef(false)
const titleElementRef = useRef<HTMLButtonElement>(null)
const isHighlightedRef = useRef<boolean>(false)
const mainItemClasses = classNames('outline-item', {
'outline-item-no-children': !outlineItem.children,
@@ -27,16 +33,16 @@ const OutlineItem = memo(function OutlineItem({
'outline-item-link-highlight': isHighlighted,
})
function handleOutlineItemLinkClick(event) {
function handleOutlineItemLinkClick(event: React.MouseEvent) {
const syncToPdf = event.detail === 2 // double-click = sync to PDF
jumpToLine(outlineItem.line, syncToPdf)
}
useEffect(() => {
const wasHighlighted = isHighlightedRef.current
isHighlightedRef.current = isHighlighted
isHighlightedRef.current = !!isHighlighted
if (!wasHighlighted && isHighlighted) {
if (!wasHighlighted && isHighlighted && titleElementRef.current) {
scrollIntoViewIfNeeded(titleElementRef.current, {
scrollMode: 'if-needed',
block: 'center',
@@ -89,20 +95,4 @@ const OutlineItem = memo(function OutlineItem({
)
})
OutlineItem.propTypes = {
outlineItem: PropTypes.exact({
line: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
level: PropTypes.number,
children: PropTypes.array,
// Used for caching in CM6
from: PropTypes.number,
to: PropTypes.number,
}).isRequired,
jumpToLine: PropTypes.func.isRequired,
highlightedLine: PropTypes.number,
matchesHighlightedLine: PropTypes.bool,
containsHighlightedLine: PropTypes.bool,
}
export default OutlineItem

View File

@@ -1,9 +1,9 @@
import PropTypes from 'prop-types'
import classNames from 'classnames'
import OutlineItem from './outline-item'
import { memo } from 'react'
import { OutlineItemData } from '@/features/ide-react/types/outline'
function getChildrenLines(children) {
function getChildrenLines(children?: OutlineItemData[]): number[] {
return (children || [])
.map(child => {
return getChildrenLines(child.children).concat(child.line)
@@ -17,6 +17,12 @@ const OutlineList = memo(function OutlineList({
isRoot,
highlightedLine,
containsHighlightedLine,
}: {
outline: OutlineItemData[]
jumpToLine: (line: number, syncToPdf: boolean) => void
isRoot?: boolean
highlightedLine?: number | null
containsHighlightedLine?: boolean
}) {
const listClasses = classNames('outline-item-list', {
'outline-item-list-root': isRoot,
@@ -27,6 +33,8 @@ const OutlineList = memo(function OutlineList({
const matchesHighlightedLine =
containsHighlightedLine && highlightedLine === outlineItem.line
const itemContainsHighlightedLine =
highlightedLine !== undefined &&
highlightedLine !== null &&
containsHighlightedLine &&
getChildrenLines(outlineItem.children).includes(highlightedLine)
@@ -53,12 +61,4 @@ const OutlineList = memo(function OutlineList({
)
})
OutlineList.propTypes = {
outline: PropTypes.array.isRequired,
jumpToLine: PropTypes.func.isRequired,
isRoot: PropTypes.bool,
highlightedLine: PropTypes.number,
containsHighlightedLine: PropTypes.bool,
}
export default OutlineList

View File

@@ -4,10 +4,11 @@ import classNames from 'classnames'
import OutlineRoot from './outline-root'
import withErrorBoundary from '../../../infrastructure/error-boundary'
import { OutlineToggleButton } from '@/features/outline/components/outline-toggle-button'
import { OutlineItemData } from '@/features/ide-react/types/outline'
const OutlinePane = React.memo<{
isTexFile: boolean
outline: any[]
outline: OutlineItemData[]
jumpToLine(line: number): void
onToggle(value: boolean): void
eventTracking: any

View File

@@ -1,9 +1,16 @@
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import OutlineList from './outline-list'
import { OutlineItemData } from '@/features/ide-react/types/outline'
function OutlineRoot({ outline, jumpToLine, highlightedLine }) {
function OutlineRoot({
outline,
jumpToLine,
highlightedLine,
}: {
outline: OutlineItemData[]
jumpToLine: (line: number, syncToPdf: boolean) => void
highlightedLine?: number
}) {
const { t } = useTranslation()
return (
@@ -33,10 +40,4 @@ function OutlineRoot({ outline, jumpToLine, highlightedLine }) {
)
}
OutlineRoot.propTypes = {
outline: PropTypes.array.isRequired,
jumpToLine: PropTypes.func.isRequired,
highlightedLine: PropTypes.number,
}
export default OutlineRoot