|
1 | 1 | 'use client';
|
2 | 2 |
|
3 |
| -import { useEffect, useState } from 'react'; |
| 3 | +import { memo, useDeferredValue, useEffect, useState } from 'react'; |
4 | 4 |
|
5 | 5 | import { MaterialSymbolsProgressActivity } from '@/components/icons/Progress';
|
6 | 6 | import { MotionButtonBase } from '@/components/ui/button';
|
@@ -35,21 +35,27 @@ export const ReadIndicator = () => {
|
35 | 35 | }, [Element]);
|
36 | 36 |
|
37 | 37 | return (
|
38 |
| - <div className="text-gray-800 dark:text-neutral-300"> |
| 38 | + <div className="text-gray-800 dark:text-neutral-300 gap-4"> |
39 | 39 | <div className="flex items-center gap-2">
|
40 | 40 | <MaterialSymbolsProgressActivity progress={readPercent} />
|
41 | 41 | {readPercent}%<br />
|
42 | 42 | </div>
|
43 |
| - <MotionButtonBase |
44 |
| - onClick={springScrollToTop} |
45 |
| - className={cn( |
46 |
| - 'mt-1 flex flex-nowrap items-center gap-2 opacity-50 transition-all duration-500 hover:opacity-100', |
47 |
| - readPercent > 10 ? '' : 'pointer-events-none opacity-0', |
48 |
| - )} |
49 |
| - > |
50 |
| - <i className="i-mingcute-arrow-up-circle-line" /> |
51 |
| - <span className="whitespace-nowrap">回到顶部</span> |
52 |
| - </MotionButtonBase> |
| 43 | + <BackToTop readPercent={useDeferredValue(readPercent)} /> |
53 | 44 | </div>
|
54 | 45 | );
|
55 | 46 | };
|
| 47 | + |
| 48 | +const BackToTop = memo(({ readPercent }: { readPercent: number }) => { |
| 49 | + return ( |
| 50 | + <MotionButtonBase |
| 51 | + onClick={springScrollToTop} |
| 52 | + className={cn( |
| 53 | + 'mt-1 flex flex-nowrap items-center gap-2 opacity-50 transition-all duration-500 hover:opacity-100', |
| 54 | + readPercent > 10 ? '' : 'pointer-events-none opacity-0', |
| 55 | + )} |
| 56 | + > |
| 57 | + <i className="i-mingcute-arrow-up-circle-line" /> |
| 58 | + <span className="whitespace-nowrap">回到顶部</span> |
| 59 | + </MotionButtonBase> |
| 60 | + ); |
| 61 | +}); |
0 commit comments