feat(editablecells): add auto-resize functionality for editableCell component's textarea and update globals.css to reflect changes

This commit is contained in:
ryan 2025-07-17 15:47:31 +03:00
parent a695b2bb7e
commit 770b6e84bb
2 changed files with 47 additions and 16 deletions

View file

@ -67,7 +67,6 @@ table td {
vertical-align: top; vertical-align: top;
position: relative; position: relative;
min-width: 120px; min-width: 120px;
min-height: 2.5rem;
background-color: transparent; background-color: transparent;
} }
@ -149,12 +148,13 @@ table th {
/* Spreadsheet-like cell styling */ /* Spreadsheet-like cell styling */
.editable-cell { .editable-cell {
width: 100%; width: 100%;
height: 100%;
min-height: 2.5rem; min-height: 2.5rem;
max-height: 12rem;
display: flex; display: flex;
align-items: center; align-items: flex-start;
padding: 0.5rem; padding: 0.5rem;
position: relative; position: relative;
overflow: hidden;
} }
.editable-cell input, .editable-cell input,
@ -172,16 +172,6 @@ table th {
resize: none; resize: none;
} }
/* Subtle focus state for the entire cell */
.editable-cell:focus-within {
background-color: rgba(59, 130, 246, 0.05); /* Very subtle blue tint */
}
/* Dark mode focus state */
.dark .editable-cell:focus-within {
background-color: rgba(59, 130, 246, 0.1);
}
/* ================================= /* =================================
TYPEAHEAD STYLES TYPEAHEAD STYLES

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback, useRef } from 'react'; import React, { useState, useEffect, useCallback, useRef, useLayoutEffect } from 'react';
interface EditableCellProps { interface EditableCellProps {
value: string; value: string;
@ -63,6 +63,40 @@ export function EditableCell({
} }
}, [focusedCell, cellKey, inputType]); }, [focusedCell, cellKey, inputType]);
// Auto-resize textarea based on content
const autoResize = useCallback(() => {
if (inputType === 'textarea' && textareaRef.current) {
const textarea = textareaRef.current;
// Reset height to auto to get the correct scrollHeight
textarea.style.height = 'auto';
// Calculate the required height
const scrollHeight = textarea.scrollHeight;
const minHeight = 40; // 2.5rem = 40px
const maxHeight = 192; // 12rem = 192px
// Set height within bounds
const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight);
textarea.style.height = `${newHeight}px`;
// Enable scrolling if content exceeds max height
textarea.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden';
}
}, [inputType]);
// Auto-resize on content change
useLayoutEffect(() => {
autoResize();
}, [localValue, autoResize]);
// Auto-resize on focus (in case content was updated externally)
useEffect(() => {
if (focusedCell === cellKey) {
autoResize();
}
}, [focusedCell, cellKey, autoResize]);
const handleInput = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const handleInput = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const newValue = e.target.value; const newValue = e.target.value;
console.log('Input event for cell:', cellKey, newValue); console.log('Input event for cell:', cellKey, newValue);
@ -105,6 +139,7 @@ export function EditableCell({
w-full h-full bg-transparent text-inherit w-full h-full bg-transparent text-inherit
border-none outline-none focus:outline-none resize-none border-none outline-none focus:outline-none resize-none
placeholder:text-gray-400 dark:placeholder:text-gray-500 placeholder:text-gray-400 dark:placeholder:text-gray-500
leading-relaxed
${className} ${className}
`.trim(); `.trim();
@ -118,9 +153,15 @@ export function EditableCell({
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
onInput={autoResize}
placeholder={placeholder} placeholder={placeholder}
className={baseClassName} className={baseClassName}
style={{ minHeight: '2.5rem' }} style={{
minHeight: '2.5rem',
resize: 'none',
overflow: 'hidden'
}}
rows={1} // Start with single row
/> />
</div> </div>
); );