Skip to content

Commit

Permalink
Merge pull request #5 from ali-h-kudeir/feature/dynamic-accordion-max…
Browse files Browse the repository at this point in the history
…-height

adjust accordion's max-height based on dynamic content height
  • Loading branch information
ali-h-kudeir committed Jun 10, 2023
2 parents 25bf3cf + 74401c4 commit e535323
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/content-script/ChatGPTCard.tsx
@@ -1,4 +1,5 @@
import { useState } from 'preact/hooks';
import { useId } from 'react';
import { Language, UserConfig } from '../config';
import Accordion from './accordion';
import ChatGPTQuery from './ChatGPTQuery';
Expand All @@ -11,6 +12,9 @@ interface Props {

function ChatGPTCard({ question, userConfig }: Props) {
const [prompt, setPrompt] = useState('');

const id = useId();

const [includeCurrentCell, setIncludeCurrentCell] = useState(true);

const [closed, setClosed] = useState(false);
Expand Down Expand Up @@ -61,13 +65,13 @@ function ChatGPTCard({ question, userConfig }: Props) {
</button>
<div className="flex items-center">
<input
id="default-checkbox"
id={'default-checkbox-' + id}
type="checkbox"
onChange={() => setIncludeCurrentCell(!includeCurrentCell)}
checked={includeCurrentCell}
className="w-3 h-3 text-blue-400 focus:border-2 colab-border rounded focus:ring-blue-400 dark:focus:ring-blue-400 dark:ring-offset-gray-800 focus:ring-2"
/>
<label htmlFor="default-checkbox" className="ml-1.5 colab-text text-xs">
<label htmlFor={'default-checkbox-' + id} className="ml-1.5 colab-text text-xs">
Include code
</label>
</div>
Expand Down
9 changes: 7 additions & 2 deletions src/content-script/accordion.tsx
@@ -1,6 +1,7 @@
import { ChevronUpIcon } from '@primer/octicons-react';
import { useEffect, useState } from 'preact/hooks';
import { ReactNode } from 'react';
import useDynamicMaxHeight from './use-dynamic-max-height';

type Props = {
children: ReactNode;
Expand All @@ -14,6 +15,8 @@ export default function Accordion({ children, visible }: Props) {
if (typeof visible === 'boolean') setIsVisible(visible);
}, [visible]);

const { ref, contentHeight } = useDynamicMaxHeight();

return (
<>
<button
Expand All @@ -32,9 +35,11 @@ export default function Accordion({ children, visible }: Props) {
</div>
</button>
<div
className={`${isVisible ? 'visible max-h-[1000px]' : 'overflow-hidden max-h-0'} mb-2`}
ref={ref}
className={`${isVisible ? `visible` : 'overflow-hidden max-h-0'} mb-2`}
style={{
transition: 'max-height 300ms ease-in-out',
transition: 'max-height 200ms ease-in-out',
maxHeight: isVisible ? `${Math.max(contentHeight ?? 0, 1000)}px` : 0,
}}
>
{children}
Expand Down
30 changes: 30 additions & 0 deletions src/content-script/use-dynamic-max-height.ts
@@ -0,0 +1,30 @@
import { useEffect, useRef, useState } from 'react';

const useDynamicMaxHeight = () => {
const ref = useRef<HTMLDivElement>(null);
const [contentHeight, setContentHeight] = useState<number | null>(0);

useEffect(() => {
const element = ref.current;
if (!element) return;

const updateMaxHeight = () => {
const height = element.scrollHeight;
setContentHeight(height);
};

updateMaxHeight();

// Re-calculate max height when the content changes
const observer = new MutationObserver(updateMaxHeight);
observer.observe(element, { childList: true, subtree: true });

return () => {
observer.disconnect();
};
}, []);

return { ref, contentHeight };
};

export default useDynamicMaxHeight;

0 comments on commit e535323

Please sign in to comment.