OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.26k stars 170 forks source link

Populating text input box programmatically #126

Closed K-Jadeja closed 4 months ago

K-Jadeja commented 4 months ago

Hey @OvidijusParsiunas Thanks for all the help with deep-chat!

I need advice regarding referencing and adding text to the input box. I want to make it so that on pressing any button, the text from that button populates the text-input box. This way the user can modify the prompt further.

Currently, pressing a button would submit the prompt from the button as is

import {DeepChat as DeepChatCore} from 'deep-chat';
import {DeepChat} from 'deep-chat-react';
import React from 'react';

function App() {
  const ref = React.useRef<HTMLDivElement>(null);

  return (
    <div className="App" ref={ref}>
      <DeepChat
        demo={true}
        htmlClassUtilities={{
          'custom-button': {
            events: {
              click: (event) => {
                const component = ref.current?.children[0] as DeepChatCore;
                if (component) {
                  const text = ((event.target as HTMLElement).children[0] as HTMLElement).innerText;
                  component.submitUserMessage({text}); // This is where I need help
                }
              },
            },
            styles: {
              default: {
                cursor: 'pointer',
                textAlign: 'center',
                backgroundColor: '#555',
                color: 'white',
                padding: '10px 20px',
                border: '1px solid #666',
                borderRadius: '10px',
                fontSize: '16px',
                marginBottom: '10px',
              },
            },
          },
          'custom-button-text': {styles: {default: {pointerEvents: 'none'}}},
          'custom-container': {
            styles: {
              default: {
                width: '140px',
                marginTop: '-10px',
              },
            },
          },
        }}
      >
        <div style={{display: 'none'}}>
          <div className="custom-container">
            <button className="custom-button">
              <div className="custom-button-text">Pre prompt 1</div>
            </button>
            <button className="custom-button">
              <div className="custom-button-text">Pre prompt 2</div>
            </button>
            <button className="custom-button">
              <div className="custom-button-text">Pre prompt 3</div>
            </button>
          </div>
        </div>
      </DeepChat>
    </div>
  );
}

export default App;

Appreciate any guidance you can provide here

OvidijusParsiunas commented 4 months ago

Hi @K-Jadeja. Programmatically changing the input text is something that we don't consider as one of the primary chat use-cases and is more in the edge case category. We may add a method for this in the future if the interest increases, but for now you will have to take the hacky route and change the placeholder programmatically. So in your code - the click event should have the following code:

click: (event) => {
  const component = ref.current?.children[0] as DeepChatCore;
  if (component) {
    const text = ((event.target as HTMLElement).children[0] as HTMLElement).innerText;
    const inputElement = component.shadowRoot?.getElementById('text-input') as HTMLElement;
    inputElement.classList.remove('text-input-placeholder');
    inputElement.innerText = text;
  }
},

Here we find the text-input element programmatically, remove the 'text-input-placeholder' class so that Deep Chat will automatically change its font and not remove it once the user clicks on it, and then add the text to innerText. As I mentioned - this is hacky as the class names may change in the future, so please use this example with caution.

K-Jadeja commented 4 months ago

Thanks @OvidijusParsiunas! Where would I find the new class name if it does change in the future?

OvidijusParsiunas commented 4 months ago

Links to ids/classes = text-input, text-input-placeholder.

As code evolves - these identifiers can change and be moved to different classes/files, hence the links above should not be treated as absolute - especially that they are permalinks to the latest repo version when this comment was made. If things stop working, I would instead recommend inspecting the dom elements and changing how const inputElement is set accordingly. E.g:

image
K-Jadeja commented 4 months ago

Ahh gotcha! Thanks