Merge pull request #45 from ravixalgorithm/main
feat: implement expandable TradingView widgets with immersive full-screen mode, fixing issue #44
This commit is contained in:
commit
719d2df4dd
|
|
@ -39,6 +39,7 @@ export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
config={CANDLE_CHART_WIDGET_CONFIG(symbol)}
|
config={CANDLE_CHART_WIDGET_CONFIG(symbol)}
|
||||||
className="custom-chart"
|
className="custom-chart"
|
||||||
height={600}
|
height={600}
|
||||||
|
allowExpand={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
|
|
@ -46,6 +47,7 @@ export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
config={BASELINE_WIDGET_CONFIG(symbol)}
|
config={BASELINE_WIDGET_CONFIG(symbol)}
|
||||||
className="custom-chart"
|
className="custom-chart"
|
||||||
height={600}
|
height={600}
|
||||||
|
allowExpand={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { memo } from 'react';
|
import React, { memo, useState, useEffect } from 'react';
|
||||||
import useTradingViewWidget from "@/hooks/useTradingViewWidget";
|
import useTradingViewWidget from "@/hooks/useTradingViewWidget";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Maximize2, Minimize2 } from 'lucide-react';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
||||||
interface TradingViewWidgetProps {
|
interface TradingViewWidgetProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
@ -10,16 +12,60 @@ interface TradingViewWidgetProps {
|
||||||
config: Record<string, unknown>;
|
config: Record<string, unknown>;
|
||||||
height?: number;
|
height?: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
allowExpand?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TradingViewWidget = ({ title, scriptUrl, config, height = 600, className }: TradingViewWidgetProps) => {
|
const TradingViewWidget = ({ title, scriptUrl, config, height = 600, className, allowExpand = false }: TradingViewWidgetProps) => {
|
||||||
const containerRef = useTradingViewWidget(scriptUrl, config, height);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
const [windowHeight, setWindowHeight] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
setWindowHeight(window.innerHeight);
|
||||||
|
const handleResize = () => setWindowHeight(window.innerHeight);
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
return () => window.removeEventListener('resize', handleResize);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const currentHeight = isExpanded ? windowHeight : height;
|
||||||
|
|
||||||
|
const widgetConfig = {
|
||||||
|
...config,
|
||||||
|
height: currentHeight,
|
||||||
|
width: "100%",
|
||||||
|
autosize: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const containerRef = useTradingViewWidget(scriptUrl, widgetConfig, currentHeight);
|
||||||
|
|
||||||
|
const toggleExpand = () => {
|
||||||
|
setIsExpanded(!isExpanded);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className={cn("w-full transition-all duration-300", isExpanded && "fixed inset-0 z-[9999] bg-background")}>
|
||||||
{title && <h3 className="font-semibold text-2xl text-gray-100 mb-5">{title}</h3>}
|
<div className={cn("w-full relative group", isExpanded && "h-full w-full")}>
|
||||||
<div className={cn('tradingview-widget-container', className)} ref={containerRef}>
|
{title && !isExpanded && <h3 className="font-semibold text-2xl text-gray-100 mb-5">{title}</h3>}
|
||||||
<div className="tradingview-widget-container__widget" style={{ height, width: "100%" }} />
|
|
||||||
|
{allowExpand && (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={toggleExpand}
|
||||||
|
className={cn(
|
||||||
|
"absolute top-2 right-2 z-10 hover:bg-background/50 text-muted-foreground hover:text-foreground transition-all duration-200",
|
||||||
|
!isExpanded ? "opacity-0 group-hover:opacity-100" : "bg-background/20"
|
||||||
|
)}
|
||||||
|
title={isExpanded ? "Minimize" : "Click to expand"}
|
||||||
|
>
|
||||||
|
{isExpanded ? <Minimize2 className="h-6 w-6" /> : <Maximize2 className="h-6 w-6" />}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={cn('tradingview-widget-container', className, isExpanded && "h-full")} ref={containerRef}>
|
||||||
|
<div className="tradingview-widget-container__widget" style={{ height: currentHeight, width: "100%" }} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue