{"id":514973,"date":"2023-03-21T14:26:00","date_gmt":"2023-03-21T13:26:00","guid":{"rendered":"https:\/\/www.devoteam.com\/expert-view\/building-a-react-grid-library-merengue\/"},"modified":"2023-03-21T14:26:00","modified_gmt":"2023-03-21T13:26:00","slug":"building-a-react-grid-library-merengue","status":"publish","type":"expert-view","link":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/","title":{"rendered":"Building a React grid library: Merengue"},"content":{"rendered":"\n<p class=\"has-medium-font-size wp-block-paragraph\"><strong>In this article, I\u2019ll talk about the process of building Merengue. This React component library helps developers implement a page grid and build their page layouts quickly without worrying about CSS rules.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-motivation\">Motivation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The development of Merengue started as an effort to offer a way to allow content editors to customize page designs, and move and position elements even if the CMS does not offer an integrated tool for that purpose.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Custom-made and headless CMSs could benefit from this library to allow content editors to build different pages with a high level of flexibility.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Initially built as part of a bigger component library, the essence of the tool was then extracted and published as a set of small React components. Merengue takes out of the equation definitions of typography, colors, and imagery, and focuses on the challenge of providing a consistent, yet flexible, page grid &#8211; a minimal but powerful resource to organize the elements of the page while not interfering with other design definitions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The development of Merengue library intends to provide the following:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A quick way to structure pages while keeping the grid settings consistent;<\/li>\n\n\n\n<li>No interference with other page design elements;<\/li>\n\n\n\n<li>Flexibility to render any custom components inside the grid blocks;<\/li>\n\n\n\n<li>Accessibility-friendly components, that allow you to define the DOM elements that build the grid through <a href=\"#polymorphic-componentshej\">polymorphic components<\/a>;<\/li>\n\n\n\n<li><a href=\"#server-components\">Server Components<\/a> compatibility;&nbsp;<\/li>\n\n\n\n<li>Possibility to dynamically build the grid of the elements by representing them as an array of objects.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">With Merengue is possible to build a grid using the default settings out of the box as in the example below. All the options are documented in more detail <a href=\"https:\/\/github.com\/irisrosa\/merengue#readme\">here<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.13.43.png\" alt=\"\" class=\"wp-image-13291\" style=\"width:1296px;height:468px\"\/><figcaption class=\"wp-element-caption\">Example usage of MerengueBox with default settings<br><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The default settings are:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.15.49.png\" alt=\"\" class=\"wp-image-13292\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This will render a grid of 4 columns of the same size, like below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.16.52.png\" alt=\"\" class=\"wp-image-13293\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-context\">Context<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-definition\">Definition<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A page grid<\/strong> is a system of columns and rows that helps align elements on a webpage and create a sense of balance and unity. This can improve the user experience by making the page look more organized and visually appealing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The page layout<\/strong> is commonly referred to as a group of defined areas where the content will fit, e.g. header, menu, sidebar, footer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that as of today there is no one way to represent either a page grid or page layout when it comes to HTML or CSS. It\u2019s up to the developer to translate the design definitions as code, making sure to consider other topics such as responsiveness and accessibility along the way.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fundamentally, the page should be built exclusively with the <a href=\"https:\/\/www.w3schools.com\/jsref\/dom_obj_all.asp\">DOM Elements<\/a> required to represent the content, while the layout and grid are design concepts that won\u2019t be understood by the browser but rather by the user.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-possible-solutions\">Possible solutions<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ll go through some of the approaches used to represent page grids and layouts, looking briefly at each one.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-legacy-methods\">Legacy methods<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tables<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><em>While tables were once commonly used to implement page layouts, their extensive markup and poor responsiveness make them a less attractive option today.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tables can build mostly fixed, boxed layouts, configured by a set number of rows, columns and the cells where they intersect. The markup can quickly become convoluted with nested tables. Also, the method offers low to no responsiveness support and bad accessibility.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tables are not the norm for modern websites anymore, and their use should be limited to the extent of what they were designed for: a great method to display two-dimensional data.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Float<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The float property in CSS allows for greater flexibility in positioning layout elements, but it can feel like a workaround. It was not originally designed for page layouts and may not behave as expected when used for that purpose.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/www.w3schools.com\/cssref\/pr_class_float.php\">float<\/a> property in CSS allows floated objects to be taken out of the normal flow and pushed to the left or right while other elements flow around them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While the use of the float property enables much more plasticity than tables, it most often feels like a workaround to implement a design with this approach, and making responsive layouts with it can be challenging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s worth noting that the float property was not originally developed to build page layouts, and therefore may not behave as expected when used for that purpose. However, there are specific scenarios where floats can be used effectively, such as for image galleries or wrapping text around an element. By understanding the strengths and limitations of the float property, developers can use it effectively as part of their frontend toolkit.<\/p>\n\n\n\n\t<div class=\"align wp-block-acf-quote\">\n\n\t\n\t<figure class=\"text-center\"><blockquote class=\"blockquote\"><svg width=\"49\" height=\"38\" viewBox=\"0 0 49 38\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M42.875 0C44.4995 0 46.0574 0.652728 47.206 1.81459C48.3547 2.97645 49 4.55228 49 6.1954V15.4885C49 17.1316 48.3547 18.7075 47.206 19.8693C46.0574 21.0312 44.4995 21.6839 42.875 21.6839H33.6875C33.6875 24.1486 34.6555 26.5123 36.3785 28.2551C38.1014 29.9979 40.4383 30.977 42.875 30.977H45.9375C46.7497 30.977 47.5287 31.3034 48.103 31.8843C48.6773 32.4652 49 33.2532 49 34.0747C49 34.8963 48.6773 35.6842 48.103 36.2651C47.5287 36.8461 46.7497 37.1724 45.9375 37.1724H42.875C38.8139 37.1724 34.9191 35.5406 32.0474 32.6359C29.1758 29.7313 27.5625 25.7917 27.5625 21.6839V6.1954C27.5625 4.55228 28.2078 2.97645 29.3565 1.81459C30.5051 0.652728 32.063 0 33.6875 0H42.875ZM15.3125 0C16.937 0 18.4949 0.652728 19.6435 1.81459C20.7922 2.97645 21.4375 4.55228 21.4375 6.1954V15.4885C21.4375 17.1316 20.7922 18.7075 19.6435 19.8693C18.4949 21.0312 16.937 21.6839 15.3125 21.6839H6.125C6.125 24.1486 7.09296 26.5123 8.81596 28.2551C10.5389 29.9979 12.8758 30.977 15.3125 30.977H18.375C19.1872 30.977 19.9662 31.3034 20.5405 31.8843C21.1148 32.4652 21.4375 33.2532 21.4375 34.0747C21.4375 34.8963 21.1148 35.6842 20.5405 36.2651C19.9662 36.8461 19.1872 37.1724 18.375 37.1724H15.3125C11.2514 37.1724 7.35658 35.5406 4.48493 32.6359C1.61328 29.7313 0 25.7917 0 21.6839V6.1954C0 4.55228 0.645313 2.97645 1.79397 1.81459C2.94263 0.652728 4.50055 0 6.125 0H15.3125Z\" fill=\"#3C3C3A\"\/>\n<\/svg><p>In its simplest use, the float property can be used to wrap text around images.<\/p><\/blockquote><figcaption class=\"blockquote-footer\">\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8d39b2df wp-block-group-is-layout-flex\">\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-6fa7971b wp-block-group-is-layout-flex\"><\/div>\n<\/div>\n<\/figcaption><\/figure>\n\t\n\t<\/div>\n\n\n\n\n<h4 class=\"wp-block-heading\">CSS Flexible Box Layout Module<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The CSS Flexible Box Layout, also known as Flexbox enables flexible and responsive layouts in CSS.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;It offers a straightforward way to arrange elements on a page, making it easier to create complex and responsive web designs. Flexbox allows developers to control the alignment, direction, order, and sizing of elements in a flexible manner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The flexbox module is a W3C Candidate Recommendation and is commonly supported by all major modern browsers.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>\u201cThe Flexible Box Layout Module makes it easier to design flexible responsive layout structures without using float or positioning.\u201d<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.w3schools.com\/css\/css3_flexbox.asp\">CSS Flexbox (Flexible Box)<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With a set of different properties, it\u2019s possible to achieve great control and flexibility with the way elements should be positioned, and compose the page layout.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CSS-grid-layout-module\">CSS Grid Layout Module<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The CSS Grid Layout module is a powerful layout system that allows for complex two-dimensional layouts in CSS.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Currently, a <a href=\"https:\/\/www.w3.org\/TR\/2020\/CRD-css-grid-2-20201218\/\">W3C Candidate Recommendation Draft<\/a> the CSS Grid method enables high flexibility in how columns and rows are configured, allowing for a complex setup of the page layout, even including named template areas and gap configuration.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">CSS Grid is a comprehensive method that <a href=\"https:\/\/caniuse.com\/css-grid\">has already been adopted by all major browsers<\/a>.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both Flexbox and CSS Grid are good options to build a page layout. <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/CSS_Grid_Layout\/Relationship_of_Grid_Layout\">This article<\/a> from MDN Web Docs lays out the differences between the two approaches &#8211; to summarise I can say that the main differences are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Flexbox has a one-dimensional approach while Grid has a two-dimensional take on the rows <strong>and<\/strong> columns.<\/li>\n\n\n\n<li>Flexbox is ideal when the content size affects the space taken by the item on the row (or column), while grid is better when we want the content to adapt to the definitions of the rows and columns.&nbsp;<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Merengue Grid<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Considering the initial goals, the chosen method was to use <a href=\"#CSS-grid-layout-module\">CSS Grid<\/a> and abstract some of the options the method offers to React components that can be used out of the box, minimising the need for configuration. But there\u2019s of course many other choices to make when building a library. I\u2019ll go through these and quickly look over the reasoning behind the choices made.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">TypeScript<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Built with TypeScript, a superset of JavaScript, the intention was to improve the developer experience when developing and consuming the library.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">CSS Modules &amp; SASS<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The initial iteration was built with the help of Styled Components, a popular and very powerful CSS-in-JS library. However, using it made it necessary either to distribute the library with styled components or to require it as peer dependency.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also, I wanted to make the library fully compatible with <a href=\"#server-components\">Server Components<\/a> and although Styled Components supports concurrent server-side rendering, the component styles still need to be rehydrated on the client.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For these reasons, I\u2019ve opted for CSS Modules, which simply output the CSS files that will style the Server Components. CSS Modules are one of the recommended approaches to style Server Components by <a href=\"https:\/\/beta.nextjs.org\/docs\/styling\/css-in-js\">Next.js<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On top of that, with the aid of SASS (a preprocessor scripting language and a superset of CSS) it was easier to develop all the different variations needed to offer Merengue grid with a good number of options. All the classes that generate different gap and column rules are generated with useful <a href=\"https:\/\/sass-lang.com\/documentation\/at-rules\/mixin\">mixins<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mixin that generates a list of CSS rules based on variable $gap-max&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.18.45.png\" alt=\"\" class=\"wp-image-13296\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Example usage of the gap mixin<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.18.57.png\" alt=\"\" class=\"wp-image-13297\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">CSS generated<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"polymorphic-componentshej\">Polymorphic components<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Polymorphic components are a special kind of component that allows users to choose which DOM Element they will output. This practice is common in libraries such as Styled Components and <a href=\"https:\/\/mui.com\/material-ui\/\">MUI (Material UI)<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/article\">example article<\/a> from MDN Docs could be written as the following using the polymorphic Block component:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.20.33.png\" alt=\"\" class=\"wp-image-13300\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">And output the exact same HTML:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.20.42.png\" alt=\"\" class=\"wp-image-13301\"\/><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">Semantic HTML<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Being able to choose the right HTML element is especially useful when creating accessibility-friendly pages, where the elements are meaningful and descriptive of the content they present.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beyond improved accessibility, semantic HTML also has a positive effect on SEO and is easier to maintain.&nbsp;&nbsp;<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Properties validation<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Depending on the chosen element, different attributes will be acceptable and&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a polymorphic component needs to account for that too. With TypeScript it\u2019s possible to create dynamic types that will validate the properties based on the value of another property.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the example below the block should be rendered as an article element. The article won\u2019t support properties such as \u2018alt\u2019, designed to describe images, and TypeScript will let us know..<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Polymorphic Ref:<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">In React, the <em>ref<\/em> property represents a way to imperatively modify or interact with a child component outside of the typical data flow. Even though there are only a handful of cases where the use of <em>ref<\/em> is really necessary, it\u2019s not possible to predict how the Merengue components will be used, and therefore this feature should also be fully supported.<\/p>\n\n\n\n<div class=\"wp-block-group is-style-column-box-shadow has-gray-light-background-color has-background has-global-padding is-layout-constrained wp-container-core-group-is-layout-a9070b44 wp-block-group-is-layout-constrained\" style=\"border-radius:5px;padding-top:var(--wp--preset--spacing--large);padding-right:var(--wp--preset--spacing--large);padding-bottom:var(--wp--preset--spacing--large);padding-left:var(--wp--preset--spacing--large)\">\n<figure class=\"wp-block-image size-large is-resized wp-duotone-red-devoteam\"><img loading=\"lazy\" decoding=\"async\" width=\"24\" height=\"24\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/09\/citation-a-droite.svg\" alt=\"Quote\" class=\"wp-image-208\" style=\"width:28px;height:auto\"\/><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Refs provide a way to access DOM nodes or React elements created in the render method.<\/p>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/reactjs.org\/docs\/refs-and-the-dom.html\">Refs and the DOM \u2013 React<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>ref<\/em> type can be different for different HTML elements. For that reason, the type of <em>ref<\/em> should also depend on the type of element passed via the \u2018as\u2019 property.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Creating the <em>ref<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using the <em>ref <\/em>with different types<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The error TypeScript outputs<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The type definition of PolymorphicRef<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/blog.logrocket.com\/build-strongly-typed-polymorphic-components-react-typescript\/\">This<\/a> very detailed article is a good reference for building strongly typed polymorphic components and handles all of the issues commented on above.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"server-components\">Server components<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Published at the end of 2020, the concept of Server Components (or zero-bundle-size components) was introduced to the public with a <a href=\"https:\/\/reactjs.org\/blog\/2020\/12\/21\/data-fetching-with-react-server-components.html\">very informative presentation<\/a> available on React\u2019s blog. Currently, the feature is still in <a href=\"https:\/\/reactjs.org\/blog\/2022\/03\/29\/react-v18.html#server-components-is-still-in-development\">development<\/a> and it\u2019s experimental in React, but support for its newest implementation is already included with Next.js 13, <a href=\"https:\/\/nextjs.org\/blog\/next-13#server-components\">released in October 2022<\/a>.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The main goal of Server Components is to reduce the bundle sent to the client by keeping as much as possible on the server, drastically improving the initial page load. They also allow direct access to backend resources and the use of sensitive information such as tokens or secrets.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But they do have some limitations. Server components do not have access to life-cycle effects, state, interactivity events or browser-only APIs.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make sure the library components were compatible with Server Components (as described by Next.js 13) I had to make sure not to depend on any of these features. This meant <a href=\"#context-provider\">not using a context provider<\/a> to theme it and not depending on complex CSS-in-JS libraries for styling (not generating CSS on runtime).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"context-provider\">Creating a theme without the use of React Context API<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">One of the most common methods of sharing theme options between components in React is to use the <a href=\"https:\/\/reactjs.org\/docs\/context.html\">Context<\/a>. Context is a way of making properties available to a tree of React components without the need to pass them down to each child component individually. Defining a context provider at a high level of the tree makes it very easy to maintain it. It is also the method used by Styled Components and many other libraries that allow theming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, since Server Components have no React state, it was necessary to find a different solution to make the theme options available without <a href=\"https:\/\/beta.reactjs.org\/learn\/passing-data-deeply-with-context#the-problem-with-passing-props\">prop drilling<\/a>. Instead, I\u2019ve created a singleton (a globally accessible class with only one instance) and allowed properties to be set and read from it by tree components.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The theme has default values for its properties that get merged with the definitions passed to the entrypoint component, MerengueBox. These values are then read by other components, helping them choose different class names and define a couple of inline styles.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the example below the <em>BlockSet <\/em>component reads the theme options object to define the CSS rules that will be used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.23.26.png\" alt=\"\" class=\"wp-image-13305\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">With the use of <a href=\"https:\/\/www.npmjs.com\/package\/classnames\">classnames<\/a> it was simpler to conditionally apply rules based on the component props.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Parcel<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The choice of a method to build the library was also something I invested some time to research. For this library the best choice was Parcel, as it offered support for TypeScript, CSS Modules and all default configurations out of the box. Let\u2019s go through some term definitions to understand this decision better.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Compiler<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A compiler is a tool that transforms high-level code into low-level, that the machine understands. When it comes to javascript, modern browsers execute the JIT (just-in-time) compilation with their own engines, often giving the impression that they simply execute javascript.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But when I say \u201cjavascript\u201d it is important to consider that javascript has many versions, and the features available in the different versions might not be supported by all browsers. For this reason developers often <em>compile<\/em> modern javascript to make it compatible with most browsers while keeping the developer experience of newer versions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Merengue the compiler of choice is <a href=\"https:\/\/swc.rs\/\">SWC<\/a>, a modern and fast<strong> <\/strong>compiler written in Rust.<\/p>\n\n\n\n<div class=\"wp-block-group is-style-column-box-shadow has-gray-light-background-color has-background has-global-padding is-layout-constrained wp-container-core-group-is-layout-a9070b44 wp-block-group-is-layout-constrained\" style=\"border-radius:5px;padding-top:var(--wp--preset--spacing--large);padding-right:var(--wp--preset--spacing--large);padding-bottom:var(--wp--preset--spacing--large);padding-left:var(--wp--preset--spacing--large)\">\n<figure class=\"wp-block-image size-large is-resized wp-duotone-red-devoteam\"><img loading=\"lazy\" decoding=\"async\" width=\"24\" height=\"24\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/09\/citation-a-droite.svg\" alt=\"Quote\" class=\"wp-image-208\" style=\"width:28px;height:auto\"\/><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">SWC is an extensible Rust-based platform for the next generation of fast developer tools. It&#8217;s used by tools like Next.js, Parcel, and Deno, as well as companies like Vercel, ByteDance, Tencent, Shopify, and more.<\/p>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/swc.rs\/\">SWC<\/a><\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Transpiler<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A transpiler is a program that will transform the code written in one high-level language into another. In the javascript context it\u2019s often used to transform TypeScript into ECMAScript (regular javascript).&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Even though SWC <a href=\"https:\/\/swc.rs\/blog\/swc-1#what-can-swc-do\">can also act as a transpiler<\/a> on its own, I\u2019ve opted to use a more complete solution that could handle CSS modules. <a href=\"https:\/\/parceljs.org\/\">Parcel<\/a> uses SWC as its default compiler and transpiler, and comes with <a href=\"https:\/\/lightningcss.dev\/docs.html\">Lightning CSS<\/a> solving both requirements.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Bundler<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Bundler is a tool capable of combining assets together. Parcel acts as a bundler that can output different types of module systems, CommonJS or ES Modules. When developing a library meant to be consumed by other React applications, I\u2019ve decided to distribute it as ES Modules only.&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ladle<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">While developing and testing the components of Merengue I\u2019ve decided to use Ladle, instead of the most common Storybook. Ladle is incredibly fast and requires zero configuration to work. At the same time it offers all necessary resources to test and exemplify the variations of each component.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, we&#8217;ve discussed various methods for creating page grids, and the pros and cons of each. I&#8217;ve also introduced Merengue, a new React component library for building page grids, and discussed some of its features and benefits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Merengue is published as a <a href=\"https:\/\/www.npmjs.com\/package\/merengue?activeTab=readme\">npm package<\/a> and its source is available publicly on <a href=\"https:\/\/github.com\/irisrosa\/merengue\">Github<\/a>. Even though it\u2019s a small React component library to solve a very specific problem, a lot of work and dedication has been put into it in the hopes that it will help other developers who have faced similar challenges.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The process of developing a public library per se was a very good learning exercise and being able to share the outcome is extremely rewarding.<br>If you&#8217;re interested in trying out Merengue, check out the documentation on <a href=\"https:\/\/github.com\/irisrosa\/merengue\">GitHub<\/a>, and feel free to <a href=\"mailto:hello@irisrosa.se\">share<\/a> your questions or feedback.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, I\u2019ll talk about the process of building Merengue. This React component library helps developers implement a page grid and build their page layouts quickly without worrying about CSS rules. Motivation The development of Merengue started as an effort to offer a way to allow content editors to customize page designs, and move [&hellip;]<\/p>\n","protected":false},"featured_media":0,"template":"","categories":[],"tags":[3041,2665],"industry":[2659],"class_list":["post-514973","expert-view","type-expert-view","status-publish","hentry","tag-cloud-native-app-development-sk","tag-sweden-sk","industry-technology-sk"],"acf":[],"cards":"\n\t<div class=\"single-post-card\">\n\n\t\t\n\n\t\t\n\t\t<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-43282307 wp-block-group-is-layout-flex\">\n\t<p style=\"font-style:normal;font-weight:700\" class=\"has-link-color wp-elements-1 wp-block-lp-post-type has-text-color has-primary-color has-small-font-size\">Expert View<\/p>\n\n\t\t\n\t\t<h3 style=\"font-style:normal;font-weight:400\" class=\"wp-block-post-title has-base-font-size\"><a href=\"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/\" target=\"_self\" >Building a React grid library: Merengue<\/a><\/h3><\/div>\n\t\t\n\t<\/div>\n\n","yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.4 (Yoast SEO v28.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Building a React grid library: Merengue | Devoteam<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a React grid library: Merengue\" \/>\n<meta property=\"og:description\" content=\"In this article, I\u2019ll talk about the process of building Merengue. This React component library helps developers implement a page grid and build their page layouts quickly without worrying about CSS rules. Motivation The development of Merengue started as an effort to offer a way to allow content editors to customize page designs, and move [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/\" \/>\n<meta property=\"og:site_name\" content=\"Devoteam\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/\",\"url\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/\",\"name\":\"Building a React grid library: Merengue | Devoteam\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/Skarmavbild-2023-03-21-kl.-15.13.43.png\",\"datePublished\":\"2023-03-21T13:26:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/#breadcrumb\"},\"inLanguage\":\"en-SK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-SK\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/#primaryimage\",\"url\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/Skarmavbild-2023-03-21-kl.-15.13.43.png\",\"contentUrl\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/Skarmavbild-2023-03-21-kl.-15.13.43.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/building-a-react-grid-library-merengue\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Expert View\",\"item\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/expert-view\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Building a React grid library: Merengue\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/#website\",\"url\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/\",\"name\":\"Devoteam\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/devoteam.info\\\/sk\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-SK\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building a React grid library: Merengue | Devoteam","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/","og_locale":"en_US","og_type":"article","og_title":"Building a React grid library: Merengue","og_description":"In this article, I\u2019ll talk about the process of building Merengue. This React component library helps developers implement a page grid and build their page layouts quickly without worrying about CSS rules. Motivation The development of Merengue started as an effort to offer a way to allow content editors to customize page designs, and move [&hellip;]","og_url":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/","og_site_name":"Devoteam","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/","url":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/","name":"Building a React grid library: Merengue | Devoteam","isPartOf":{"@id":"https:\/\/devoteam.info\/sk\/#website"},"primaryImageOfPage":{"@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/#primaryimage"},"image":{"@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/#primaryimage"},"thumbnailUrl":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.13.43.png","datePublished":"2023-03-21T13:26:00+00:00","breadcrumb":{"@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/#breadcrumb"},"inLanguage":"en-SK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/"]}]},{"@type":"ImageObject","inLanguage":"en-SK","@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/#primaryimage","url":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.13.43.png","contentUrl":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/Skarmavbild-2023-03-21-kl.-15.13.43.png"},{"@type":"BreadcrumbList","@id":"https:\/\/devoteam.info\/sk\/expert-view\/building-a-react-grid-library-merengue\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devoteam.info\/sk\/"},{"@type":"ListItem","position":2,"name":"Expert View","item":"https:\/\/devoteam.info\/sk\/expert-view\/"},{"@type":"ListItem","position":3,"name":"Building a React grid library: Merengue"}]},{"@type":"WebSite","@id":"https:\/\/devoteam.info\/sk\/#website","url":"https:\/\/devoteam.info\/sk\/","name":"Devoteam","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devoteam.info\/sk\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-SK"}]}},"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"jelena.saveljic","author_link":"https:\/\/devoteam.info\/sk\/author\/"},"uagb_comment_info":0,"uagb_excerpt":"In this article, I\u2019ll talk about the process of building Merengue. This React component library helps developers implement a page grid and build their page layouts quickly without worrying about CSS rules. Motivation The development of Merengue started as an effort to offer a way to allow content editors to customize page designs, and move&hellip;","_links":{"self":[{"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/expert-view\/514973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/expert-view"}],"about":[{"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/types\/expert-view"}],"version-history":[{"count":0,"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/expert-view\/514973\/revisions"}],"wp:attachment":[{"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/media?parent=514973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/categories?post=514973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/tags?post=514973"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/devoteam.info\/sk\/wp-json\/wp\/v2\/industry?post=514973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}