in fact, the keyboard is a text buffer
it has two interactive buttons (ESC, ENTER) that can be pressed with the mouse in the graphical interface of the keyboard. these buttons have nothing to do with real buttons on a real keyboard, when you press the real enter button, you will add a line break to the keyboard buffer and it can be registered by reading it, however, this will not lead to registration of pressing the virtual enter button
The keyboard can work in two modes. normal and print mode. in print mode, the graphical interface of the keyboard is not rendered and the virtual ESC and ENTER buttons become unavailable. however, you can still capture pressing the real enter button by detecting a line break in the buffer.
in print mode, it makes sense to clear the buffer after reading its contents(since the buffer has a limited size of 32 kilobytes)
please note that the contents of the keyboard buffer are SAVED in blueprint even after re-entering the world. in some cases (for example, in print mode) it is better to clear the keyboard buffer at the very beginning of the program
the keyboard can be connected to the seat to open its GUI without getting up
component name - keyboard

methods:

            --example in normal mode

local graphic = require("graphic")

local keyboard = getComponent("keyboard")
local display = getComponent("display")

keyboard.clear()
keyboard.setPrintMode(false)
keyboard.resetButtons()

display.reset()

local rotation = 0

function callback_loop()
    if _endtick then
        display.clear()
        display.forceFlush()
        return
    end

    --rotate the image with two virtual buttons in the keyboard GUI
    if keyboard.isEsc() then
        rotation = rotation - 1
        if rotation < 0 then rotation = 3 end
    end
    if keyboard.isEnter() then
        rotation = rotation + 1
        if rotation > 3 then rotation = 0 end
    end
    keyboard.resetButtons()
    display.setRotation(rotation)
    
    --displaying the contents of the keyboard buffer on the screen
    display.clear()
    graphic.textBox(display, 0, 0, display.getWidth(), display.getHeight(), keyboard.read())
    display.flush()
end
        
            --example in print mode
--this mode is great for creating games. In this case, the WASD buttons control the ball on the screen

local keyboard = getComponent("keyboard")
local display = getComponent("display")

keyboard.clear()
keyboard.setPrintMode(true)
keyboard.setSoundEnable(false)
keyboard.resetButtons()

display.reset()

local posX, posY = display.getWidth() / 2, display.getHeight() / 2

function callback_loop()
    if _endtick then
        display.clear()
        display.forceFlush()
        return
    end

    local buffer = keyboard.read()
    keyboard.clear()

    for i = 1, #buffer do
        local chr = buffer:sub(i, i):lower()
        if chr == "w" then
            posY = posY - 1
        elseif chr == "s" then
            posY = posY + 1
        elseif chr == "a" then
            posX = posX - 1
        elseif chr == "d" then
            posX = posX + 1
        end
    end

    display.clear()
    display.drawCircle(posX, posY, 8)
    display.flush()
end