Web Components
Solving a simple usability challenge using Web Components.
This project is a rewrite of a technical challenge I had undertaken some time ago and built using ReactJS. The challenge was to build a re-usable component that renders a list of items. The user should be able to add to the list of items by typing into an input and they should be able to subsequently delete items from the list.
I figured this would be an interesting challenge to undertake without the use of any libraries, frameworks or utilities - just the WebAPI. It is built using Web Components which is a suite of standardised web technologies that come together to allow developers to create custom HTML elements.
With that, I set about creating a suite of custom elements that would work together to achieve this goal as follows:
- The <list-item> component contains the styling, structure and behaviour for individual list items. This component styles itself if the content is not valid and it has a delete button callback that is executed in its parent container.
- The <items-list> component handles the logic for rendering, adding and removing items from the list. It contains a slot element so we can add an input inline alongside the list items. Using slots allows developers to add an element inline with others, even if it is in a completely different component.
- The <item-input> component is a text field that focuses on adding event listeners. It handles callbacks passed in for when the text field is changed, focused, blurred or when a key press event occurs. This helps with adding an item to the list when the user presses enter, types in a comma or blurs on the input field.
- Finally, the <editable-list> component ties the previous two together and is the main component that is imported into a document the end-user is authoring. This is where we can 'slot' the <item-input> component into the <items-list> component.
With the above structure, I wanted to be able to deliver a robust, scalable solution with good separation of concerns. Web Components are quite powerful and are well supported in modern browsers. This project relies on the user of scoped styling, Shadow DOM and HTML Templates.
I wrote each component as a class using TypeScript, and this gets transpiled to ECMAScript using webpack and Babel. Code quality checking is carried out with the ESLint tool.
This project is fully tested as well, and uses Jest as its test runnner, alongside Dom Testing Library which has some support for testing components that use Shadow Dom. Full test coverage has been achieved.
The source code for this project is on github.com/matfin/editable-list.