My Design System
Why I Created a Design System
I was using Material UI for a project, and the bundle size, combined with the css-in-js approach to styling, resulted in an application that was difficult to render on the server and that had a pretty poor initial load time. I wanted to create a design system that was similar to Material UI / Flutter but that emphasized semantic HTML and a small bundle size.
Also, when creating a Rich Text Editor with Lexical, I found that it was best to not use highly abstracted components, so I tried to create a library of simple components that can be easily rendered on the server and that doesn't use too much CSS and JavaScript.
In summary, the goal of the design system is to create a look that is comparable to other popular design libraries used today while minimizing load time, bundle size, and complexity.
Assumptions
NOTE: This design system uses CSS and JavaScript that are tied together - i.e., some classes are required for components' JavaScript to work correctly. The design system bundles and transpiles client-side JavaScript using webpack, which is why you might want to download the JavaScript and CSS files from the resources section and tweak them / re-transpile them for your own use. If you make changes to the CSS, I recommend you use PostCSS so your changes will appear the same across all browsers.
- you want to use HTMX to create a SPA (Single Page Application),
- you want to use semantic html, but that you want to style components primarily with CSS classes and inline styling,
- your Content Security Policy allows for inline styling,
- you want to use Floating UI for tooltips, menus, dropdowns, and the like,
- you want to have slightly different layouts for desktop and mobile,
- you want to prioritize mobile devices (you want the application that you show the user to always be similar to the mobile device view),
- you do not want to listen to resize events on mobile
Explore the Design System
If you are looking for information about specific components or utility classes, use the links in the list below to find more information about those aspects of the system. Each aspect of the design system should describe the styling, accessability, and JavaScript concerns that go along with it.
If you are looking to learn more about the design system and the decisions made, continue reading below or navigate to the 'General' page for the design system.
If you want the code, navigate to the resources section.
Note that I am still working on documenting the design system. I got tired of writing the documentation and wanted to move onto other things. I will come back and finish / improve the documentation eventually.
Other Inputs
Javascript for Inputs
When new content is loaded, the client side javascript gets all <input>
and <textarea>
elements, and then:
-
initializes them,
-
This involves setting the appropriate background size for range
<input>
s as well as setting the value for the<output>
s for the range<input>
s,
-
This involves setting the appropriate background size for range
-
adds a focus event listener to the
<input>
s that are not readonly,-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
.input-group
class, sets the data-focus attribute to true,
-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
-
adds a blur event listener to the
<input>
s that are not readonly,-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
.input-group
class, sets the data-blurred attribute to true and the data-focus attribute to false,
-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
-
adds a change event listener to the
<input>
s that are not readonly and adds an 'input' event listener to<textarea>
s and range inputs,-
Checks whether classlist of the input contains
.chip
, then return if it does. - gets the id, name, type, current length of the input (if the input.value has a length), the minlength and maxlength attribute of the input,
- checks whether the last change is currently being debounced, cancels the debounced function,
-
creates a debounced function that:
- checks whether there is a character counter for the input, and if there is, set the data-val attributes of the minlength and maxlength spans
- checks whether the input is a range input, and if it is, sets the background size for the range input and sets the value of the output element that corresponds to the range input
- checks whether the input is a range input and if it is, creates a debounced function to blur the range input in 50ms.
-
Checks whether classlist of the input contains
-
adds a mouseover event listener to the
<input>
s that are not readonly,-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
.input-group
class, sets the data-hover attribute to true.
-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
-
adds a mouseout event listener to the
<input>
s that are not readonly,-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
.input-group
class, sets the data-hover attribute to false.
-
gets the parent element node of the parent element node of the input and if the element is a div
that contains the
Range Inputs
About Range Inputs
File Uploads
About File Uploads
Date and Time Inputs
About Date and Time Inputs
Date Input:
Datetime Input:
Time Input:
Month Input:
Week Input:
Phone Inputs
Search Icons
About Icon Search
Resources
Click on the individual buttons to download separate files, or click on the All Files button to download a ZIP file of all the code. The code is sent pre-transpiled
for readability.
Click on the VSCode Snippet button to download a copy of the html.json file that will make implementing this design system simpler.