NLP Input

March 8th, 2024

Interactive

This is a simple NLP input component that captures your input and detects dates and times to help you create reminders and events.

How it works

It works with the Chrono Library under the hood. It's a simple and easy-to-use library for detecting and parsing dates and times. The real challenge for me was to find a way to create a user-friendly input field that allows me to fully customize and style single parts of the input string.

Interactive

import { useEditor, EditorContent } from '@tiptap/react'
import Text from '@tiptap/extension-text'
import Document from '@tiptap/extension-document'

const editor = useEditor({
extensions,

        onUpdate: ({ editor }) => {
            const textContent = editor.getText()
            const info = getInformation(textContent)
            setInfo(info)
        },
    })

Configuring the Highlight Plugin

I then created a new Highlight plugin that extends the Mark class from the TipTap library. This plugin is responsible for adding the highlight mark to the selected text and for parsing the HTML to find the mark tag.

import { Mark, mergeAttributes } from '@tiptap/core'
import Paragraph from '@tiptap/extension-paragraph'
const Highlight = Mark.create({
name: 'highlight',

    addOp: {
        HTMLAttributes: {
            class: 'custom-class',
        },
    },

    parseHTML() {
        return [
            {
                tag: 'mark',
            },
        ]
    },

Detecting Dates and Times

After the inital setup I created the "getInformation-function" that uses the Chrono library to detect dates and times in the input string.

import * as chrono from 'chrono-node'

export const getInformation = (input: string) => {
    const results = chrono.parse(input)

    if (results.length > 0) {
        let cleanedInput = input

        // Remove all detected date substrings from the input
        results.forEach((result) => {
            cleanedInput = cleanedInput.replace(result.text, '').trim()
        })

        // Extract the first detected date
        const dueDate = results[0].start.date()

        // Return the first detected date and the cleaned input text
        return {
            date: dueDate,
            detectedDateString: results[0].text as string,
            text: input,
        }
    } else {
        // If no dates are detected, return the original input text
        return {
            date: undefined,
            text: '',
        }
    }

}

Highlight detected string

Now I use the TipTap commands to highlight the detected date string in the input field. It's important to make sure that the correct string is highlighted, so I use the detectedDateString to find the correct start and end position in the input string.

 useEffect(() => {
        const textContent = editor ? editor.getText() : ''
        const startPosition = textContent.indexOf(info?.detectedDateString!)

        // highlights the new detectedDateString
        if (editor && startPosition !== -1 && info?.detectedDateString) {
            const endPosition = startPosition + info.detectedDateString.length
            editor
                .chain()
                .setTextSelection({
                    from: startPosition,
                    to: endPosition + 1,
                })
                // use your highlight extension
                .setMark('highlight')
                .selectTextblockEnd()
                .unsetMark('highlight')
                .run()
        }

        // remember the detectedDateString for the next useEffect call
        setPrevDateString(info?.detectedDateString!)
    }, [info?.detectedDateString, editor])

And then I use the Calendar Picker from ShadcnUI to display the detected date to the user.

Conclusion

This project showed me that human-computer interactions need to be seamless. They need to feel so natural that you just do what you always do, and the computer understands what you want. In my opinion, the time where you need to learn how to talk to a computer in daily business is over. The computers should learn to understand you, your needs, and workflows.

Next Interaction

Parallax Image Grid