DEV Community

Paul Kim
Paul Kim

Posted on

Hacktoberfest Week 2

For Topics in Open Source Development, the other students in this course and I are partaking in Hacktoberfest - a month-long open source community event where participants submit 4 pull requests to participating projects.

In this post I will cover my experience finding a second issue to work with and submitting a pull request.

Ordspel

For this entry, I've found a project called Ordspel - a website that features a collection of word games based on IKEA furniture names. You can play them at https://ikeawordgames.com.

Issue

The issue can be found here.

The problem is that in Jumble - one of the word games - the visual keyboard allows players to enter any letter in the alphabet. This causes some friction since players cannot enter any letters outside of the provided ones. You can give Jumble a try here.

The maintainer wanted the non-solution letters to appear disabled/faded out so players wouldn't click on them. Additionally, there should be negative visual feedback from the game if the player were to click on a disabled letter anyway (i.e. the input field shakes).

How it looked before:

Before image

How it looked after:

After image

Analyzing the project's code

Looking through the code, I was pleasantly surprised with how straightforward and well organized the project was. Project setup was straightforward; just installed the node dependencies and ran in development mode. Ordspel is a React Next.js web application that uses Chakra UI as its UI component library, which was right up my alley.

The first step was to identify the part of the code that was responsible for handling the visual keyboard. I found that it was a custom React component named WordInput. It acted as a wrapper for a package called simple-keyboard.

My first suggestion (post here) was to implement a disabledKeys property where a parent component can stipulate which keys to specifically disable. avikantz (the maintainer) suggested to use the existing targetValue property to determine which keys to disable, which was fine by me.

Figuring out which keys to disable

The targetValue property represented the target answer string the game was looking for. It was simple enough to figure out that the "bad" keys are just the rest of the keyboard (link). However, since this game is based on Swedish words, there are special diacritics to handle - letters with umlauts i.e. ร–, ร„, รœ. Thankfully, the maintainer already provides a removeAccents() method that strips these umlauts, making using the latin-only simple-keyboard interface easy to work with.

Making changes - look and feel

The next step was to see if simple-keyboard's API provided an easy way to disable specific keys already. Turns out it didn't - should've figured as much. I looked through the documentation to see if there were any options that would be helpful. The buttonAttributes option allowed me to assign a specific attribute to specific keyboard keys which I could target via CSS (link). That handled the "look" of the disabled keys at least.

Making changes - functionality

To make the disabled keys non-interactable I used the inputPattern option provided by simple-keyboard. This allowed me to specify a regex pattern that determined which keys to allow input for - in this case any characters not found in the solution. While this works, it did not allow me to satisfy the maintainer's design requirement to provide negative visual feedback (i.e. a shaking input field) since the input is simply ignored. So I had to look for another solution provided by the keyboard's API. It was a shame that this documentation does not provide a search function - it would have made searching for specific functionality a lot easier.

I realized that the only way to handle this situation was to leverage the existing onKeyPress callback function (link). From there I could check what the current input of the field was and determine whether it contained a character from a disabled key or not. If so, I "jiggle" the input field as negative reinforcement and return early (link). The animation uses the useAnimate function from the Framer Motion animation library.

Afterwards, I created a pull request following the template provided by the maintainer and am now waiting to hear back.

A new issue

While I was working on this project, I noticed there was a pre-existing bug - one could enter additional characters into the input field for Jumble via the visual keyboard. You couldn't see them but they were there - you can backspace to get rid of them. Thankfully I already had a solution in mind.

I posted a new issue and created a pull request - the problem was that the length of the stored "input" of the keyboard component could exceed Jumble's allowed length. The solution was to truncate this value during the onKeyPress callback so that any extra characters were always sliced off (source). While it was possible to limit this field's length in other ways, doing this check during the callback allowed me to provide negative visual feedback (i.e. the same "jiggle").

Takeaways

All in all this was a very fun project to work with. The website was interesting, the project was well organized and documented, it was straightforward to set up, the maintainer was amicable and timely in their responses, and it was fun to use new libraries.

The most difficult part was working around the limitations of the simple-keyboard API. It was tempting to look for workarounds or create a custom fork of this library that gave me more control, but in the end it provided just enough functionality for me to work with to complete my tasks. The lack of a search function in the documentation made the process surprisingly difficult - I hope that all of the documentation I have to deal with in the future provides one.

Thanks for reading!

Top comments (0)