fix styles

This commit is contained in:
Red Adaya 2024-10-20 22:17:08 +08:00
parent 601533566e
commit b985b445e7
3 changed files with 45 additions and 43 deletions

View File

@ -1,25 +1,22 @@
.chat-group { .chat-group {
display: flex; display: flex;
align-items: stretch; /* Make both textarea and palette stretch equally */ align-items: stretch;
border-radius: 6px; border-radius: 6px;
position: relative; position: relative;
width: 100%; width: 100%;
border: 2px solid var(--form-element-border-color); border: 2px solid var(--form-element-border-color);
background: var(--form-element-bg-color); background: var(--form-element-bg-color);
padding: 5px; padding: 5px;
gap: 5px; gap: 10px;
/* Focus style */
&.focused { &.focused {
border-color: var(--form-element-primary-color); border-color: var(--form-element-primary-color);
} }
/* Error state */
&.error { &.error {
border-color: var(--form-element-error-color); border-color: var(--form-element-error-color);
} }
/* Disabled state */
&.disabled { &.disabled {
opacity: 0.75; opacity: 0.75;
} }
@ -36,31 +33,32 @@
justify-content: center; justify-content: center;
} }
/* Textarea */
.chat-textarea { .chat-textarea {
flex-grow: 1; /* Textarea should take up remaining space */ flex-grow: 1;
margin: 0; margin: 0;
padding: 5px;
border: none; border: none;
box-shadow: none; box-shadow: none;
box-sizing: border-box;
background-color: transparent; background-color: transparent;
resize: none; resize: none;
overflow-y: auto; /* Only scroll when the max height is reached */ overflow-y: auto;
line-height: 1.5; line-height: 1.4;
color: var(--form-element-text-color); color: var(--form-element-text-color);
min-height: 24px; vertical-align: top;
height: auto;
padding: 0;
&:focus-visible { &:focus-visible {
outline: none; outline: none;
} }
} }
/* Emoji palette container, stays at the bottom */ .emoji-palette-wrapper {
.emoji-palette {
display: flex; display: flex;
align-items: flex-end; /* Aligns the emoji palette button to the bottom */ align-items: flex-end;
justify-content: center;
height: 100%; /* Ensure full height */ button {
min-width: 40px; /* Set a minimum width for the emoji button area */ padding: 3px 4px;
}
} }
} }

View File

@ -98,7 +98,7 @@ export const ChatInputWithLongText: Story = {
}, },
args: { args: {
placeholder: "Type a long message...", placeholder: "Type a long message...",
rows: 2, rows: 1,
maxRows: 10, maxRows: 10,
}, },
}; };

View File

@ -1,6 +1,3 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import clsx from "clsx"; import clsx from "clsx";
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { EmojiPalette } from "./emojipalette"; import { EmojiPalette } from "./emojipalette";
@ -47,16 +44,35 @@ const ChatInput = ({
const [internalValue, setInternalValue] = useState(defaultValue); const [internalValue, setInternalValue] = useState(defaultValue);
const [lineHeight, setLineHeight] = useState(24); // Default line height fallback of 24px const [lineHeight, setLineHeight] = useState(24); // Default line height fallback of 24px
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { // Function to count the number of lines in the textarea value
if (textareaRef.current) { const countLines = (text: string) => {
textareaRef.current.style.height = "auto"; // Reset height return text.split("\n").length;
const maxHeight = maxRows * lineHeight; // Calculate max height };
const newHeight = Math.min(textareaRef.current.scrollHeight, maxHeight);
textareaRef.current.style.height = `${newHeight}px`; // Set height dynamically
}
const adjustTextareaHeight = () => {
if (textareaRef.current) {
textareaRef.current.style.height = "auto"; // Reset height to auto first
const maxHeight = maxRows * lineHeight; // Max height based on maxRows
const currentLines = countLines(textareaRef.current.value); // Count the number of lines
const newHeight = Math.min(textareaRef.current.scrollHeight, maxHeight); // Calculate new height
// If the number of lines is less than or equal to maxRows, set height accordingly
const calculatedHeight = currentLines <= maxRows ? `${lineHeight * currentLines}px` : `${newHeight}px`;
textareaRef.current.style.height = calculatedHeight; // Set new height based on lines or scrollHeight
if (actionWrapperRef.current) {
actionWrapperRef.current.style.height = calculatedHeight; // Adjust emoji palette wrapper height
}
}
};
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInternalValue(e.target.value); setInternalValue(e.target.value);
onChange && onChange(e.target.value); onChange && onChange(e.target.value);
// Adjust the height of the textarea after text change
adjustTextareaHeight();
}; };
const handleFocus = () => { const handleFocus = () => {
@ -73,25 +89,13 @@ const ChatInput = ({
if (textareaRef.current) { if (textareaRef.current) {
const computedStyle = window.getComputedStyle(textareaRef.current); const computedStyle = window.getComputedStyle(textareaRef.current);
let lineHeightValue = computedStyle.lineHeight; let lineHeightValue = computedStyle.lineHeight;
if (lineHeightValue === "normal") {
const fontSize = parseFloat(computedStyle.fontSize);
lineHeightValue = `${fontSize * 1.2}px`; // Fallback to 1.2 ratio of font size
}
const detectedLineHeight = parseFloat(lineHeightValue); const detectedLineHeight = parseFloat(lineHeightValue);
setLineHeight(detectedLineHeight || 24); // Fallback if detection fails setLineHeight(detectedLineHeight);
} }
}, [textareaRef]); }, [textareaRef]);
useEffect(() => { useEffect(() => {
if (textareaRef.current) { adjustTextareaHeight(); // Adjust the height when the component mounts or value changes
textareaRef.current.style.height = "auto";
const maxHeight = maxRows * lineHeight;
const newHeight = Math.min(textareaRef.current.scrollHeight, maxHeight);
textareaRef.current.style.height = `${newHeight}px`;
actionWrapperRef.current.style.height = `${newHeight}px`;
}
}, [value, maxRows, lineHeight]); }, [value, maxRows, lineHeight]);
const inputValue = value ?? internalValue; const inputValue = value ?? internalValue;
@ -118,7 +122,7 @@ const ChatInput = ({
: "hidden", : "hidden",
}} }}
/> />
<div ref={actionWrapperRef}> <div ref={actionWrapperRef} className="emoji-palette-wrapper">
<EmojiPalette placement="top-end" /> <EmojiPalette placement="top-end" />
</div> </div>
</div> </div>