-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Summary card report * Apply suggestions from code rabbit * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * MORE CODE RABBIT SUGGESTIONS * typecheck fix * change view form the details page * added privacy filter * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * debounce * removed binary search and changed the summary page to not use the card component * Update packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix on recommended code rabbit commit * added some padding to number so it fits the window better for big numbers * accept infinite * feedback fixes * Update packages/desktop-client/src/components/reports/reports/SummaryCard.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * translations * fix on the save, linter and changed "include summary date range" to "all time divisor" * changed MD from enhancements to feature * typo * change card * typecheck * Update packages/desktop-client/src/components/reports/SummaryNumber.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * typecheck * changes to fit the number better * small fix * fix on filters * code review * revert code to check for height --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Loading branch information
1 parent
f523d25
commit c626fc2
Showing
14 changed files
with
1,298 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
packages/desktop-client/src/components/reports/SummaryNumber.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import React, { type Ref, useRef, useState } from 'react'; | ||
|
||
import { debounce } from 'debounce'; | ||
|
||
import { amountToCurrency } from 'loot-core/shared/util'; | ||
|
||
import { useMergedRefs } from '../../hooks/useMergedRefs'; | ||
import { useResizeObserver } from '../../hooks/useResizeObserver'; | ||
import { View } from '../common/View'; | ||
import { PrivacyFilter } from '../PrivacyFilter'; | ||
|
||
import { chartTheme } from './chart-theme'; | ||
import { LoadingIndicator } from './LoadingIndicator'; | ||
|
||
const FONT_SIZE_SCALE_FACTOR = 0.9; | ||
const MAX_RECURSION_DEPTH = 10; | ||
|
||
type SummaryNumberProps = { | ||
value: number; | ||
animate?: boolean; | ||
suffix?: string; | ||
loading?: boolean; | ||
initialFontSize?: number; | ||
fontSizeChanged?: (fontSize: number) => void; | ||
}; | ||
|
||
export function SummaryNumber({ | ||
value, | ||
animate = false, | ||
suffix = '', | ||
loading = true, | ||
initialFontSize = 14, | ||
fontSizeChanged, | ||
}: SummaryNumberProps) { | ||
const [fontSize, setFontSize] = useState<number>(0); | ||
const refDiv = useRef<HTMLDivElement>(null); | ||
const offScreenRef = useRef<HTMLDivElement>(null); | ||
|
||
const adjustFontSizeBinary = (minFontSize: number, maxFontSize: number) => { | ||
if (!offScreenRef.current || !refDiv.current) return; | ||
|
||
const offScreenDiv = offScreenRef.current; | ||
const refDivCurrent = refDiv.current; | ||
|
||
const binarySearchFontSize = ( | ||
min: number, | ||
max: number, | ||
depth: number = 0, | ||
) => { | ||
if (depth >= MAX_RECURSION_DEPTH) { | ||
setFontSize(min); | ||
return; | ||
} | ||
|
||
const testFontSize = (min + max) / 2; | ||
offScreenDiv.style.fontSize = `${testFontSize}px`; | ||
|
||
requestAnimationFrame(() => { | ||
const isOverflowing = | ||
offScreenDiv.scrollWidth > refDivCurrent.clientWidth || | ||
offScreenDiv.scrollHeight > refDivCurrent.clientHeight; | ||
|
||
if (isOverflowing) { | ||
binarySearchFontSize(min, testFontSize, depth + 1); | ||
} else { | ||
const isUnderflowing = | ||
offScreenDiv.scrollWidth <= | ||
refDivCurrent.clientWidth * FONT_SIZE_SCALE_FACTOR || | ||
offScreenDiv.scrollHeight <= | ||
refDivCurrent.clientHeight * FONT_SIZE_SCALE_FACTOR; | ||
|
||
if (isUnderflowing && testFontSize < max) { | ||
binarySearchFontSize(testFontSize, max, depth + 1); | ||
} else { | ||
setFontSize(testFontSize); | ||
if (initialFontSize !== testFontSize && fontSizeChanged) { | ||
fontSizeChanged(testFontSize); | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
|
||
binarySearchFontSize(minFontSize, maxFontSize); | ||
}; | ||
|
||
const handleResize = debounce(() => { | ||
adjustFontSizeBinary(14, 200); | ||
}, 250); | ||
|
||
const ref = useResizeObserver(handleResize); | ||
const mergedRef = useMergedRefs(ref, refDiv); | ||
|
||
return ( | ||
<> | ||
{loading && <LoadingIndicator />} | ||
{!loading && ( | ||
<> | ||
<div | ||
ref={offScreenRef} | ||
style={{ | ||
position: 'fixed', | ||
left: '-999px', | ||
top: '-999px', | ||
fontSize: `${initialFontSize}px`, | ||
lineHeight: 1, | ||
visibility: 'hidden', | ||
whiteSpace: 'nowrap', | ||
padding: 8, | ||
}} | ||
> | ||
<PrivacyFilter> | ||
{amountToCurrency(Math.abs(value))} | ||
{suffix} | ||
</PrivacyFilter> | ||
</div> | ||
|
||
<View | ||
ref={mergedRef as Ref<HTMLDivElement>} | ||
role="text" | ||
aria-label={`${value < 0 ? 'Negative' : 'Positive'} amount: ${amountToCurrency(Math.abs(value))}${suffix}`} | ||
style={{ | ||
alignItems: 'center', | ||
flexGrow: 1, | ||
flexShrink: 1, | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '100%', | ||
fontSize: `${fontSize}px`, | ||
lineHeight: 1, | ||
padding: 8, | ||
justifyContent: 'center', | ||
transition: animate ? 'font-size 0.3s ease' : '', | ||
color: value < 0 ? chartTheme.colors.red : chartTheme.colors.blue, | ||
}} | ||
> | ||
<span aria-hidden="true"> | ||
<PrivacyFilter> | ||
{amountToCurrency(Math.abs(value))} | ||
{suffix} | ||
</PrivacyFilter> | ||
</span> | ||
</View> | ||
</> | ||
)} | ||
</> | ||
); | ||
} |
Oops, something went wrong.