animate buttons in and out

This commit is contained in:
Nate Kelley 2025-02-03 11:42:51 -07:00
parent e6655554d0
commit 9c847ca6f1
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
13 changed files with 112 additions and 8 deletions

View File

@ -1,9 +1,11 @@
'use client';
import React, { useRef } from 'react';
import { useChatLayoutContextSelector } from '../../_layouts/ChatLayout';
import { AppSplitter, AppSplitterRef } from '@/components';
import { MetricFileView, useChatLayoutContextSelector } from '../../_layouts/ChatLayout';
import { AppSplitter, AppSplitterRef } from '@/components/layout/AppSplitter';
import { useMetricControllerLayout } from './useMetricControllerLayout';
import { MetricViewController } from './MetricViewController';
import { MetricEditController } from './MetricEditController';
const defaultLayout = ['auto', '0px'];
@ -12,6 +14,9 @@ export const MetricController: React.FC<{
}> = React.memo(({ metricId }) => {
const appSplitterRef = useRef<AppSplitterRef>(null);
const selectedFileView = useChatLayoutContextSelector(
(x) => x.selectedFileView
) as MetricFileView;
const selectedFileViewSecondary = useChatLayoutContextSelector(
(x) => x.selectedFileViewSecondary
);
@ -24,8 +29,8 @@ export const MetricController: React.FC<{
return (
<AppSplitter
ref={appSplitterRef}
leftChildren={<div>{metricId}</div>}
rightChildren={<div className="min-w-[230px]">right swag</div>}
leftChildren={<MetricViewController selectedFileView={selectedFileView} />}
rightChildren={<MetricEditController />}
rightHidden={!renderSecondary}
autoSaveId="metric-controller"
defaultLayout={defaultLayout}

View File

@ -0,0 +1,7 @@
import React from 'react';
export const MetricEditController: React.FC = React.memo(() => {
return <div>MetricEditController</div>;
});
MetricEditController.displayName = 'MetricEditController';

View File

@ -0,0 +1 @@
export * from './MetricEditController';

View File

@ -0,0 +1,7 @@
import React from 'react';
export const MetricViewChart: React.FC = React.memo(() => {
return <div>MetricViewChart</div>;
});
MetricViewChart.displayName = 'MetricViewChart';

View File

@ -0,0 +1,15 @@
import { MetricFileView } from '@appLayouts/ChatLayout/ChatLayoutContext';
import React from 'react';
import { MetricViewComponents } from './config';
export const MetricViewController: React.FC<{
selectedFileView: MetricFileView | undefined;
}> = React.memo(({ selectedFileView }) => {
if (!selectedFileView) return null;
const Component = MetricViewComponents[selectedFileView];
return <Component selectedFileView={selectedFileView} />;
});
MetricViewController.displayName = 'MetricViewController';

View File

@ -0,0 +1,7 @@
import React from 'react';
export const MetricViewFile: React.FC = React.memo(() => {
return <div>MetricViewFile</div>;
});
MetricViewFile.displayName = 'MetricViewFile';

View File

@ -0,0 +1,7 @@
import React from 'react';
export const MetricViewResults: React.FC = React.memo(() => {
return <div>MetricViewResults</div>;
});
MetricViewResults.displayName = 'MetricViewResults';

View File

@ -0,0 +1,14 @@
import type { MetricFileView } from '@/app/app/_layouts/ChatLayout';
import { MetricViewChart } from './MetricViewChart';
import { MetricViewFile } from './MetricViewFile';
import { MetricViewResults } from './MetricViewResults';
interface MetricViewProps {
selectedFileView: MetricFileView;
}
export const MetricViewComponents: Record<MetricFileView, React.FC<MetricViewProps>> = {
chart: MetricViewChart,
results: MetricViewResults,
file: MetricViewFile
};

View File

@ -0,0 +1 @@
export * from './MetricViewController';

View File

@ -1 +1,2 @@
export * from './ChatLayoutContext';
export type * from './useChatFileLayout';

View File

@ -0,0 +1,7 @@
import React from 'react';
export const FileButtonContainer: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
return <div className="flex items-center gap-1">{children}</div>;
};

View File

@ -0,0 +1,22 @@
import { AnimatePresence, motion } from 'framer-motion';
import React from 'react';
const displayAnimation = {
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
transition: { duration: 0.15 }
};
export const HideButtonContainer: React.FC<{
children: React.ReactNode;
show: boolean;
}> = React.memo(({ children, show }) => {
return (
<AnimatePresence mode="wait" initial={false}>
{show && <motion.div {...displayAnimation}>{children}</motion.div>}
</AnimatePresence>
);
});
HideButtonContainer.displayName = 'HideButtonContainer';

View File

@ -2,21 +2,31 @@ import React from 'react';
import { FileContainerButtonsProps } from './interfaces';
import { Button, ButtonProps } from 'antd';
import { AppMaterialIcons, AppTooltip } from '@/components';
import { useChatLayoutContextSelector } from '../../ChatLayoutContext';
import { type MetricFileView, useChatLayoutContextSelector } from '../../ChatLayoutContext';
import { useMemoizedFn } from 'ahooks';
import { SaveMetricToCollectionButton } from '@appComponents/Buttons/SaveMetricToCollectionButton';
import { SaveMetricToDashboardButton } from '@appComponents/Buttons/SaveMetricToDashboardButton';
import { ShareMetricButton } from '@appComponents/Buttons/ShareMetricButton';
import { useChatContextSelector } from '../../ChatContext';
import { HideButtonContainer } from './HideButtonContainer';
import { FileButtonContainer } from './FileButtonContainer';
export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(() => {
const selectedFileView = useChatLayoutContextSelector(
(x) => x.selectedFileView
) as MetricFileView;
const showEditChartButton = selectedFileView === 'chart';
return (
<div className="flex items-center gap-1">
<EditChartButton />
<FileButtonContainer>
<HideButtonContainer show={showEditChartButton}>
<EditChartButton />
</HideButtonContainer>
<SaveToCollectionButton />
<SaveToDashboardButton />
<ShareMetricButton />
</div>
</FileButtonContainer>
);
});