Skip to content

Commit e535323

Browse files
authored
Merge pull request #5 from ali-h-kudeir/feature/dynamic-accordion-max-height
adjust accordion's max-height based on dynamic content height
2 parents 25bf3cf + 74401c4 commit e535323

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

src/content-script/ChatGPTCard.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState } from 'preact/hooks';
2+
import { useId } from 'react';
23
import { Language, UserConfig } from '../config';
34
import Accordion from './accordion';
45
import ChatGPTQuery from './ChatGPTQuery';
@@ -11,6 +12,9 @@ interface Props {
1112

1213
function ChatGPTCard({ question, userConfig }: Props) {
1314
const [prompt, setPrompt] = useState('');
15+
16+
const id = useId();
17+
1418
const [includeCurrentCell, setIncludeCurrentCell] = useState(true);
1519

1620
const [closed, setClosed] = useState(false);
@@ -61,13 +65,13 @@ function ChatGPTCard({ question, userConfig }: Props) {
6165
</button>
6266
<div className="flex items-center">
6367
<input
64-
id="default-checkbox"
68+
id={'default-checkbox-' + id}
6569
type="checkbox"
6670
onChange={() => setIncludeCurrentCell(!includeCurrentCell)}
6771
checked={includeCurrentCell}
6872
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"
6973
/>
70-
<label htmlFor="default-checkbox" className="ml-1.5 colab-text text-xs">
74+
<label htmlFor={'default-checkbox-' + id} className="ml-1.5 colab-text text-xs">
7175
Include code
7276
</label>
7377
</div>

src/content-script/accordion.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ChevronUpIcon } from '@primer/octicons-react';
22
import { useEffect, useState } from 'preact/hooks';
33
import { ReactNode } from 'react';
4+
import useDynamicMaxHeight from './use-dynamic-max-height';
45

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

18+
const { ref, contentHeight } = useDynamicMaxHeight();
19+
1720
return (
1821
<>
1922
<button
@@ -32,9 +35,11 @@ export default function Accordion({ children, visible }: Props) {
3235
</div>
3336
</button>
3437
<div
35-
className={`${isVisible ? 'visible max-h-[1000px]' : 'overflow-hidden max-h-0'} mb-2`}
38+
ref={ref}
39+
className={`${isVisible ? `visible` : 'overflow-hidden max-h-0'} mb-2`}
3640
style={{
37-
transition: 'max-height 300ms ease-in-out',
41+
transition: 'max-height 200ms ease-in-out',
42+
maxHeight: isVisible ? `${Math.max(contentHeight ?? 0, 1000)}px` : 0,
3843
}}
3944
>
4045
{children}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect, useRef, useState } from 'react';
2+
3+
const useDynamicMaxHeight = () => {
4+
const ref = useRef<HTMLDivElement>(null);
5+
const [contentHeight, setContentHeight] = useState<number | null>(0);
6+
7+
useEffect(() => {
8+
const element = ref.current;
9+
if (!element) return;
10+
11+
const updateMaxHeight = () => {
12+
const height = element.scrollHeight;
13+
setContentHeight(height);
14+
};
15+
16+
updateMaxHeight();
17+
18+
// Re-calculate max height when the content changes
19+
const observer = new MutationObserver(updateMaxHeight);
20+
observer.observe(element, { childList: true, subtree: true });
21+
22+
return () => {
23+
observer.disconnect();
24+
};
25+
}, []);
26+
27+
return { ref, contentHeight };
28+
};
29+
30+
export default useDynamicMaxHeight;

0 commit comments

Comments
 (0)