mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-02 12:53:10 +00:00
feat: make comment window height resizable
This commit is contained in:
parent
89b70c758e
commit
8cc956682c
11
package-lock.json
generated
11
package-lock.json
generated
@ -53,6 +53,7 @@
|
||||
"lucide-react": "^0.462.0",
|
||||
"next-themes": "^0.3.0",
|
||||
"ordiscan": "^1.3.0",
|
||||
"re-resizable": "6.11.2",
|
||||
"react": "^18.3.1",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@ -13403,6 +13404,16 @@
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/re-resizable": {
|
||||
"version": "6.11.2",
|
||||
"resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.11.2.tgz",
|
||||
"integrity": "sha512-2xI2P3OHs5qw7K0Ud1aLILK6MQxW50TcO+DetD9eIV58j84TqYeHoZcL9H4GXFXXIh7afhH8mv5iUCXII7OW7A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||
|
||||
@ -60,6 +60,7 @@
|
||||
"lucide-react": "^0.462.0",
|
||||
"next-themes": "^0.3.0",
|
||||
"ordiscan": "^1.3.0",
|
||||
"re-resizable": "6.11.2",
|
||||
"react": "^18.3.1",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@ -9,7 +9,8 @@ import {
|
||||
usePostBookmark,
|
||||
} from '@/hooks';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
//
|
||||
import ResizableTextarea from '@/components/ui/resizable-textarea';
|
||||
import {
|
||||
ArrowLeft,
|
||||
ArrowUp,
|
||||
@ -276,12 +277,15 @@ const PostDetail = () => {
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
Add a comment
|
||||
</h2>
|
||||
<Textarea
|
||||
<ResizableTextarea
|
||||
placeholder="What are your thoughts?"
|
||||
value={newComment}
|
||||
onChange={e => setNewComment(e.target.value)}
|
||||
className="mb-3 resize-none"
|
||||
className="bg-cyber-muted/50 border-cyber-muted"
|
||||
disabled={isCreatingComment}
|
||||
minHeight={100}
|
||||
initialHeight={140}
|
||||
maxHeight={600}
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
|
||||
75
src/components/ui/resizable-textarea.tsx
Normal file
75
src/components/ui/resizable-textarea.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import * as React from 'react';
|
||||
import { Resizable } from 're-resizable';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
|
||||
type ResizableTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
||||
initialHeight?: number;
|
||||
minHeight?: number;
|
||||
maxHeight?: number;
|
||||
};
|
||||
|
||||
export const ResizableTextarea = React.forwardRef<
|
||||
HTMLTextAreaElement,
|
||||
ResizableTextareaProps
|
||||
>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
initialHeight = 120,
|
||||
minHeight = 80,
|
||||
maxHeight = 800,
|
||||
...textareaProps
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const [height, setHeight] = React.useState<number>(initialHeight);
|
||||
|
||||
const isDisabled = Boolean(textareaProps.disabled);
|
||||
|
||||
return (
|
||||
<Resizable
|
||||
size={{ width: '100%', height }}
|
||||
enable={{
|
||||
top: false,
|
||||
right: false,
|
||||
bottom: !isDisabled,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight: false,
|
||||
bottomLeft: false,
|
||||
topLeft: false,
|
||||
}}
|
||||
minHeight={minHeight}
|
||||
maxHeight={maxHeight}
|
||||
onResizeStop={(_event, _dir, _elementRef, delta) => {
|
||||
setHeight(current => Math.max(minHeight, Math.min(maxHeight, current + delta.height)));
|
||||
}}
|
||||
handleComponent={{
|
||||
bottom: (
|
||||
<div
|
||||
className="w-full h-2 cursor-row-resize bg-border/40 hover:bg-border rounded-b-[3px]"
|
||||
aria-label="Resize textarea"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
handleStyles={{ bottom: { bottom: 0 } }}
|
||||
className="mb-3"
|
||||
>
|
||||
<Textarea
|
||||
ref={ref}
|
||||
{...textareaProps}
|
||||
className={cn('h-full resize-none', className)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
</Resizable>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
ResizableTextarea.displayName = 'ResizableTextarea';
|
||||
|
||||
export default ResizableTextarea;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user