Moving the input box down to the lower portion of the screen

My goal is to create an interactive input box that glides smoothly to the bottom of the screen when clicked by the user. However, the current implementation causes the input box to move too far down, requiring the user to scroll down in order to see it.

Here is the code for the page:

'use client';
import { useState, useRef, useEffect } from 'react';
import Header from '@/components/Header';
import SendChatButton from '@/components/buttons/SendChatButton';

export default function Home() {
  const [isInputFocused, setInputFocused] = useState(false);
  const formRef = useRef(null);
  const [formHeight, setFormHeight] = useState(0);

  useEffect(() => {
    if (formRef.current) {
      setFormHeight(formRef.current.offsetHeight);
    }
  }, []);

  const formStyle = isInputFocused
    ? { transform: `translateY(calc(100vh - ${formHeight}px))` }
    : {};

  return (
    <main>
      <section className='p-4 pt-32'>
        <div>
          <h1 className='text-6xl font-bold'>
            Your very own<br /> personal designer
          </h1>
          <h2 className='text-xl mt-6'>Makes finding outfits so much easier</h2>
        </div>
        <form 
          ref={formRef}
          style={formStyle}
          className="mt-6 flex shadow-md transition-transform duration-1000 ease-in-out"
        >
          <input
            type="text"
            placeholder='Message your personal designer...'
            className="p-2 border border-gray-300 rounded-md block w-full text-sm outline-none"
            onFocus={() => setInputFocused(true)}
            onBlur={() => setInputFocused(false)}
          />
          <SendChatButton />
        </form>
      </section>
    </main>
  );
}


Answer №1

One issue arises when trying to calculate the new form height using `100vh` as it doesn't account for other elements on the page. If your page only consists of the form, this approach would work fine. However, since there are other elements present, the calculation `100vh - ${formHeight}px` is done from the current position of the form instead of the top of the entire page. I hope this explanation clarifies things.

A clever workaround involves setting the initial `section` height to occupy the full `100vh`. Then, adjust the form's height to fill the remaining space within the `section`. When the form is focused, change its height to a specific value (using `auto` won't provide the desired animation effect).

Here's a solution I've devised:

'use client';
import { useState, useRef, useEffect } from 'react';
import Header from '@/components/Header';
import SendChatButton from '@/components/buttons/SendChatButton';

export default function Home() {
  const [isInputFocused, setInputFocused] = useState(false);
  const formRef = useRef(null);
  const [formHeight, setFormHeight] = useState(0);

  useEffect(() => {
    if (formRef.current) {
      setFormHeight(formRef.current.offsetHeight);
    }
  }, []);

  //   added this to make the form grow when focused
  const formStyle = isInputFocused ? { height: '3rem' } : {};

  return (
    <main>
      {/* added flex and justify-between to make the form stick to the bottom */}
      <section className="p-4 pt-32 bg-red-300 h-screen flex flex-col justify-between">
        <div>
          <h1 className="text-6xl font-bold">
            Your very own
            <br /> personal designer
          </h1>
          <h2 className="text-xl mt-6">Makes finding outfits so much easier</h2>
        </div>
        <form
          ref={formRef}
          style={formStyle}
          // and added transition to make it smooth, with h-full, which will be overridden by the formStyle
          className="mt-6 flex shadow-md duration-1000 ease-in-out bg-green-300 transition-all h-full"
        >
          <input
            type="text"
            placeholder="Message your personal designer..."
            className="p-2 border border-gray-300 rounded-md block w-full text-sm outline-none h-min"
            onFocus={() => setInputFocused(true)}
            onBlur={() => setInputFocused(false)}
          />
          <SendChatButton />
        </form>
      </section>
    </main>
  );
}

I trust this solution proves helpful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sticky header/navigation bar implementation in React Native for consistent navigation across views

Currently, I am working on creating a consistent navbar/header for my React Native app. At the moment, when I switch between views in my code, the entire interface changes. It functions properly, but the navbar/header scrolls along with the view, making i ...

Error encountered in Next.js when using GetStaticPaths

I'm encountering an issue with the getStaticPaths function in Next.JS: TypeError: cias.map is not a function https://i.stack.imgur.com/IVZDp.png Could anyone assist me with resolving this problem? Here's the code snippet: import React from &ap ...

Issue with retrieving POST body from Ajax call in Play Framework

I am currently attempting to send a POST request to my backend using JSON data. The frontend call appears like this: function register() { var user = $("#form_reg_username").val(); var pass = $("#form_reg_password").val(); var referal = $("#form_reg ...

Tips for updating the URL in the browser address bar after loading content using AJAX with angular.js

When developing a web application using angular.js, the communication within the app is done through AJAX. This means that when the application requests web resources, the URL in the browser address bar does not change. For instance, my app displays build ...

Issue with React not displaying JSX when onClick Button is triggered

I've recently started learning React and I'm facing a problem that I can't seem to figure out. I have a basic button, and when it's clicked, I want to add another text or HTML element. While the console log statement is working fine, th ...

Having trouble with the onLoadingComplete props in the Next.js Image component?

Is there a way to properly retrieve the naturalWidth and naturalHeight using the onLoadingComplete props? I tried following the documentation on https://nextjs.org/docs/api-reference/next/image#onloadingcomplete but it doesn't seem to be working. Am I ...

Converting JSON-style data into a string with the power of node mysql

Just a quick note - I'm a total newbie in the world of web development, so I might be missing an obvious solution here. My challenge is to insert a dataset into a MySQL database using nodejs/expressjs/mysql. I've managed to establish a connecti ...

The specified type 'IterableIterator<number>' does not belong to either an array type or a string type

Encountering an error while attempting to generate a dynamic range of numbers. Error: Type 'IterableIterator<number>' is not recognized as an array or string type. Use the compiler option '--downlevelIteration' to enable iteratio ...

Preventing responsive elements from loading with HTML scripts

Currently, I am utilizing the Gumby framework which can be found here. Everything appears to be running smoothly. My goal is to incorporate a mobile navigation list where the links are grouped under a single button, as outlined here. Initially, this funct ...

Creating a dynamic user interface in Angular 6 that successfully tracks changes without reliance on the parent

As I delve into the world of Angular, I am faced with a challenge in creating a reusable component that will be bundled into an npm module. The issue lies in the UI change detection aspect. In order for the component to function properly, the application ...

Tips for automatically closing one element when another is clicked

My goal is to create a menu that displays when I click on a link, and if another menu is already open, it should close before displaying the new one. Essentially, I want to achieve an accordion menu where only one menu is open at a time. However, despite m ...

What is the best way to sort my API responses to display only users who are either currently online or offline?

Hi everyone, I've made great progress on my project so far without any assistance (pretty proud of myself), but now I could use some help. I'm working on creating a tabbed menu that filters the results of my API calls to display: All users, Onlin ...

Tips and tricks for storing and retrieving form state using local storage with jQuery in JavaScript

I'm trying to save the form state in localstorage, I am able to save it successfully but I'm encountering an issue where I am unable to save the input typed data Desired outcome: If I type doggy inside the input box, I want that value to be ret ...

Having trouble with the react event handler for the renderedValue component in Material UI?

I am facing an issue while trying to utilize the onDelete event handler within the chip component using Material UI in the code snippet below. Upon clicking on the chip, it triggers the Select behavior which opens a dropdown menu. Is there a way to modif ...

How can you check the boolean value of a checkbox using jQuery?

I have a checkbox on my webpage. <input id="new-consultation-open" type="checkbox" /> My goal is to store the state of this checkbox in a variable as a boolean value. consultation.save({ open: $("#new-consultation-open").val() }); Unfortunate ...

The Ajax request is not passing the values of the submit button as expected

In my current setup, I am using ajax code to send name/email/message parameters to a "messageaction.cfm" template and then display those same 3 parameters on the original submission page. The code works fine in achieving this functionality: <script ...

The addition of input fields on keyup creates problems in the initial field of each row

I am currently working with a table and attempting to calculate the sums as follows: td(1) + td(2) + td(3) = td(4), td(5) + td(6) + td(7) = td(8), td(9) + td(10) + td(11) = td(12). This is the code I have implemented: $(document).ready(function () { ...

JavaScript's ASYNC forEach function not following the expected sequence

I'm really struggling to understand the workings of async and await in this scenario. I want the forEach function to run before the console.log and res.json, but no matter what I do with async and await, it always ends up being the last thing executed ...

Is there a way for me to determine if a domain has been registered by the client?

I'm interested in creating a Web app that allows users to enter a domain name and then uses JavaScript to check its availability. I'm wondering if there's a method to do this without relying on my own hosting server. Is it possible to send a ...

Using multiple main.js files with RequireJs in Play Framework 2.1.1 Java: A step-by-step guide

While working on a single-page app with AngularJs + RequireJs in Play Framework 2.1.1, I encountered an issue regarding the structure of my application. The project consists of two main sections - an admin dashboard and a normal website - both housed withi ...