remix-nlux
Version:
Remix IDE NLUX integration. Remix IDE is the leading IDE for building and deploying smart contracts on Ethereum. NLUX is a JavaScript and React library for building conversational AI experiences.
73 lines (63 loc) • 2.76 kB
text/typescript
import {createComposerDom} from '@shared/components/Composer/create';
import {CallbackFunction} from '@shared/types/callbackFunction';
import {NluxRenderingError} from '@shared/types/error';
import {domOp} from '@shared/utils/dom/domOp';
import {CompRenderer} from '../../../types/comp';
import {listenToElement} from '../../../utils/dom/listenToElement';
import {source} from '../../../utils/source';
import {CompComposerActions, CompComposerElements, CompComposerEvents, CompComposerProps} from './composer.types';
export const renderChatbox: CompRenderer<
CompComposerProps, CompComposerElements, CompComposerEvents, CompComposerActions
> = ({
appendToRoot,
props,
compEvent,
}) => {
const composerRoot = createComposerDom(props.domCompProps);
appendToRoot(composerRoot);
const [textBoxElement, removeTextBoxListeners] = listenToElement(composerRoot, ':scope > textarea')
.on('input', compEvent('text-updated'))
.on('keydown', ((event: KeyboardEvent) => {
const isEnter = event.key === 'Enter' && !event.isComposing;
const aModifierKeyIsPressed = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
if (isEnter && !aModifierKeyIsPressed) {
compEvent('enter-key-pressed')(event);
return;
}
const isCommandEnter = event.getModifierState('Meta') && event.key === 'Enter';
const isControlEnter = event.getModifierState('Control') && event.key === 'Enter';
if (isCommandEnter || isControlEnter) {
compEvent('command-enter-key-pressed')(event);
return;
}
}) as CallbackFunction).get();
const [sendButtonElement, removeSendButtonListeners] = listenToElement(composerRoot, ':scope > button')
.on('click', compEvent('send-message-clicked')).get();
if (!(sendButtonElement instanceof HTMLButtonElement)) {
throw new Error('Expected a button element');
}
if (!(textBoxElement instanceof HTMLTextAreaElement)) {
throw new NluxRenderingError({
source: source('composer', 'render'),
message: 'Expected a textarea element',
});
}
const focusTextInput = () => domOp(() => {
textBoxElement.focus();
textBoxElement.setSelectionRange(textBoxElement.value.length, textBoxElement.value.length);
});
return {
elements: {
root: composerRoot,
textInput: textBoxElement,
sendButton: sendButtonElement,
},
actions: {
focusTextInput,
},
onDestroy: () => {
removeTextBoxListeners();
removeSendButtonListeners();
},
};
};