/** * Download box container that wraps a chart * @author Gabe Abrams * @author Jackson Parsells */ // Import React import React, { useReducer } from 'react'; // Import DownloadButton import DownloadButton from './DownloadButton'; /*------------------------------------------------------------------------*/ /* Style */ /*------------------------------------------------------------------------*/ const style = ` .DownloadBox-download { position: absolute; top: 0; right: 15px; cursor: pointer; } .DownloadBox-no-outline { border: 1px solid transparent; } .DownloadBox-outlined { border: 1px solid #007bff; } `; /*------------------------------------------------------------------------*/ /* Types */ /*------------------------------------------------------------------------*/ // Props definition type Props = { // Title of the chart title: string, // Chart Data for papa parse chartData: { [k: string]: string | number }[], // Chart element to show children: React.ReactNode, }; /*------------------------------------------------------------------------*/ /* State */ /*------------------------------------------------------------------------*/ /* -------- State Definition -------- */ type State = { // True if user is hovering over the chart hovering: boolean, }; /* ------------- Actions ------------ */ // Types of actions enum ActionType { // Start hovering StartHovering = 'start-hovering', // Stop hovering StopHovering = 'stop-hovering', } // Action definitions type Action = ( | { // Action type type: ( | ActionType.StartHovering | ActionType.StopHovering ), } ); /** * Reducer that executes actions * @author Gabe Abrams * @param state current state * @param action action to execute */ const reducer = (state: State, action: Action): State => { switch (action.type) { case ActionType.StartHovering: { return { ...state, hovering: true, }; } case ActionType.StopHovering: { return { ...state, hovering: false, }; } default: { return state; } } }; /*------------------------------------------------------------------------*/ /* Component */ /*------------------------------------------------------------------------*/ const DownloadBox: React.FC = (props) => { /*------------------------------------------------------------------------*/ /* Setup */ /*------------------------------------------------------------------------*/ /* -------------- Props ------------- */ // Destructure all props const { title, chartData, children, } = props; /* -------------- State ------------- */ // Initial state const initialState: State = { hovering: false, }; // Initialize state const [state, dispatch] = useReducer(reducer, initialState); // Destructure common state const { hovering, } = state; /*------------------------------------------------------------------------*/ /* Render */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* Main UI */ /*----------------------------------------*/ return (
{ dispatch({ type: ActionType.StartHovering }); }} onFocus={() => { dispatch({ type: ActionType.StartHovering }); }} onMouseLeave={() => { dispatch({ type: ActionType.StopHovering }); }} onBlur={() => { dispatch({ type: ActionType.StopHovering }); }} > {/* Style */} {/* Chart */} {children} {/* Download Button */}
); }; /*------------------------------------------------------------------------*/ /* Wrap Up */ /*------------------------------------------------------------------------*/ // Export component export default DownloadBox;