diff --git a/component/src/deepChat.css b/component/src/deepChat.css index 105a1eda8..5bf5b7b67 100644 --- a/component/src/deepChat.css +++ b/component/src/deepChat.css @@ -13,5 +13,7 @@ #container { height: inherit; + /* this is required for text input container not to go beyond its boundaries when typing a long word */ + width: inherit; overflow: hidden; } diff --git a/component/src/utils/data/objectUtils.ts b/component/src/utils/data/objectUtils.ts index 29a14435a..6db27b9d7 100644 --- a/component/src/utils/data/objectUtils.ts +++ b/component/src/utils/data/objectUtils.ts @@ -1,12 +1,40 @@ export class ObjectUtils { - public static setPropertyValueIfDoesNotExist(object: T, keys: string[], value: unknown) { - const propertyKey = keys[0] as keyof T; - if (keys.length === 1) { + public static setPropertyValueIfDoesNotExist(object: T, nestedKeys: string[], value: unknown) { + const propertyKey = nestedKeys[0] as keyof T; + if (nestedKeys.length === 1) { object[propertyKey] ??= value as T[keyof T]; } else { object[propertyKey] ??= {} as T[keyof T]; - keys.shift(); - ObjectUtils.setPropertyValueIfDoesNotExist(object[propertyKey], keys, value); + nestedKeys.shift(); + ObjectUtils.setPropertyValueIfDoesNotExist(object[propertyKey], nestedKeys, value); + } + } + + public static setPropertyValue(object: T, nestedKeys: string[], value: unknown) { + const propertyKey = nestedKeys[0] as keyof T; + if (nestedKeys.length === 1) { + object[propertyKey] = value as T[keyof T]; + } else { + object[propertyKey] ??= {} as T[keyof T]; + nestedKeys.shift(); + ObjectUtils.setPropertyValue(object[propertyKey], nestedKeys, value); + } + } + + public static getObjectValue(object: T, nestedKeys: string[]): object | undefined { + const propertyKey = nestedKeys[0] as keyof T; + const currentValue = object[propertyKey]; + if (currentValue === undefined || nestedKeys.length === 1) { + return currentValue as object | undefined; + } + return ObjectUtils.getObjectValue(currentValue, nestedKeys.slice(1)); + } + + public static overwritePropertyObjectFromAnother(target: T, source: T, nestedKeys: string[]) { + const sourceObject = ObjectUtils.getObjectValue(source, nestedKeys); + if (sourceObject) { + const newObject = {...sourceObject, ...(ObjectUtils.getObjectValue(target, nestedKeys) || {})}; + ObjectUtils.setPropertyValue(target, nestedKeys, newObject); } } } diff --git a/component/src/utils/webComponent/webComponentStyleUtils.ts b/component/src/utils/webComponent/webComponentStyleUtils.ts index 2bfc77057..388fd5bca 100644 --- a/component/src/utils/webComponent/webComponentStyleUtils.ts +++ b/component/src/utils/webComponent/webComponentStyleUtils.ts @@ -1,7 +1,7 @@ import {StyleUtils} from '../element/styleUtils'; export class WebComponentStyleUtils { - private static readonly DEFAULT_COMPONENT_STYLE = { + private static readonly DEFAULT_COMPONENT_STYLE: Partial = { height: '350px', width: '320px', border: '1px solid #cacaca', @@ -9,6 +9,10 @@ export class WebComponentStyleUtils { fontSize: '0.9rem', backgroundColor: 'white', position: 'relative', + // this is used to prevent inputAreaStyle background color from going beyond the container's rounded border + // it will cause issues if there are elements that are meant to be outside of the chat component and in + // that instance they should overwrite this + overflow: 'hidden', }; public static apply(style: string, shadowRoot: ShadowRoot | null) { diff --git a/component/src/views/chat/input/buttons/submit/submitButton.ts b/component/src/views/chat/input/buttons/submit/submitButton.ts index c8adea39b..d457a82e8 100644 --- a/component/src/views/chat/input/buttons/submit/submitButton.ts +++ b/component/src/views/chat/input/buttons/submit/submitButton.ts @@ -38,8 +38,8 @@ export class SubmitButton extends InputButton { // prettier-ignore constructor(deepChat: DeepChat, inputElementRef: HTMLElement, messages: Messages, serviceIO: ServiceIO, fileAttachments: FileAttachments) { - SubmitButtonStateStyle.prepare(deepChat); - super(SubmitButton.createButtonContainerElement(), deepChat.submitButtonStyles?.position, deepChat.submitButtonStyles); + const submitButtonStyles = SubmitButtonStateStyle.process(deepChat.submitButtonStyles); + super(SubmitButton.createButtonContainerElement(), submitButtonStyles?.position, submitButtonStyles); this._messages = messages; this._inputElementRef = inputElementRef; this._fileAttachments = fileAttachments; @@ -47,7 +47,7 @@ export class SubmitButton extends InputButton { this._abortStream = new AbortController(); this._stopClicked = {listener: () => {}}; this._serviceIO = serviceIO; - this._alwaysEnabled = !!deepChat.submitButtonStyles?.alwaysEnabled; + this._alwaysEnabled = !!submitButtonStyles?.alwaysEnabled; deepChat.changeSubmitButtonState = this.changeSubmitButtonState.bind(this, serviceIO); this.attemptOverwriteLoadingStyle(deepChat); setTimeout(() => { // in a timeout as deepChat._validationHandler initialised later @@ -140,7 +140,7 @@ export class SubmitButton extends InputButton { } } - // TO-DO - should be disabled loading history + // TO-DO - should be disabled when loading history // prettier-ignore public async submit(isProgrammatic: boolean, userText: string) { let uploadedFilesData; diff --git a/component/src/views/chat/input/buttons/submit/submitButtonStateStyle.ts b/component/src/views/chat/input/buttons/submit/submitButtonStateStyle.ts index ae2fb81e2..aa3d09405 100644 --- a/component/src/views/chat/input/buttons/submit/submitButtonStateStyle.ts +++ b/component/src/views/chat/input/buttons/submit/submitButtonStateStyle.ts @@ -1,5 +1,6 @@ +import {SubmitButtonStyles} from '../../../../../types/submitButton'; import {ObjectUtils} from '../../../../../utils/data/objectUtils'; -import {DeepChat} from '../../../../../deepChat'; +import {ButtonStyles} from '../../../../../types/button'; import {SubmitButton} from './submitButton'; export class SubmitButtonStateStyle { @@ -13,19 +14,20 @@ export class SubmitButtonStateStyle { } // prettier-ignore - public static prepare(deepChat: DeepChat) { - deepChat.submitButtonStyles ??= {}; - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles, ['submit'], {}); - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles, ['disabled'], {}); - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles.submit, - ['container', 'default', 'backgroundColor'], ''); - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles.disabled, - ['container', 'default', 'backgroundColor'], 'white'); - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles.submit, - ['svg', 'styles', 'default', 'filter'], ''); - ObjectUtils.setPropertyValueIfDoesNotExist(deepChat.submitButtonStyles.disabled, - ['svg', 'styles', 'default', 'filter'], + public static process(submitButtonStyles?: SubmitButtonStyles) { + if (submitButtonStyles?.alwaysEnabled) return submitButtonStyles; + const styles = JSON.parse(JSON.stringify(submitButtonStyles || {})) as SubmitButtonStyles; + ObjectUtils.setPropertyValueIfDoesNotExist(styles, ['submit', 'container', 'default', 'backgroundColor'], ''); + ObjectUtils.setPropertyValueIfDoesNotExist(styles, ['disabled', 'container', 'default', 'backgroundColor'], 'unset'); + ObjectUtils.setPropertyValueIfDoesNotExist(styles.submit, ['svg', 'styles', 'default', 'filter'], ''); + ObjectUtils.setPropertyValueIfDoesNotExist(styles.disabled, ['svg', 'styles', 'default', 'filter'], 'brightness(0) saturate(100%) invert(70%) sepia(0%) saturate(5564%)' + ' hue-rotate(207deg) brightness(100%) contrast(97%)'); + const disabledStyles = JSON.parse(JSON.stringify(styles.disabled)) as ButtonStyles; + ObjectUtils.overwritePropertyObjectFromAnother(disabledStyles, styles.submit, ['container', 'default']); + ObjectUtils.overwritePropertyObjectFromAnother(disabledStyles, styles.submit, ['text', 'styles', 'default']); + ObjectUtils.overwritePropertyObjectFromAnother(disabledStyles, styles.submit, ['svg', 'styles', 'default']); + styles.disabled = disabledStyles; + return styles; } } diff --git a/component/src/views/chat/input/textInput/textInputEvents.ts b/component/src/views/chat/input/textInput/textInputEvents.ts index 8d5dfb303..77b2fb59f 100644 --- a/component/src/views/chat/input/textInput/textInputEvents.ts +++ b/component/src/views/chat/input/textInput/textInputEvents.ts @@ -9,7 +9,6 @@ export class TextInputEvents { KEYBOARD_KEY.ARROW_DOWN, KEYBOARD_KEY.ARROW_UP, KEYBOARD_KEY.META, KEYBOARD_KEY.CONTROL, KEYBOARD_KEY.ENTER ]); - // WORK - check why rendered twice as addEventListeners will be called twice public static add(inputElement: HTMLElement, characterLimit?: number, validationHandler?: ValidationHandler) { if (characterLimit !== undefined) { inputElement.addEventListener('keydown', TextInputEvents.onKeyDown.bind(this, characterLimit));