Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

The newline Guide to Storybook for React Apps is Now Available 🎉

Learn how to use Storybook in your projects alongside React, Redux, and all the other tools you already use. You will see how to leverage Storybook's addons to tie Storybook into your workflow with design tools, testing tools, and routing tools.   🔖  Yann Braga - a core Storybook maintainer, teaches you step by step how to use Storybook efficiently and effectively in your React development. With over 3 hours of video lessons , the course will open new frontiers for your UI development enabling you to develop React components and apps that deliver superior UX. He covers a lot of ground including:  Your instructor for this course is Yann Braga, a Senior Software Engineer at Chromatic, and a member of the Storybook team. Yann has worked on important packages in and around the Storybook ecosystem, and is uniquely qualified to teach developers how to get the most out of working with Storybook. To learn more about what Storybook has to offer for React development and to enroll, check out the course website 👉 The newline Guide to Storybook for React Apps .  

Thumbnail Image of Tutorial The newline Guide to Storybook for React Apps is Now Available 🎉

Interaction Testing in Storybook

When it comes to visually testing a collection of components, no other tool stands out quite like Storybook . Not only does Storybook provide an isolated environment for developing components and display their different rendered states, but Storybook also integrates with Testing Library to simulate and test component functionality that's triggered by a user interaction. For example, instead of just checking if a form renders correctly, you can also check if behavior like form submission and validation work correctly. This integration with Testing Library allows Storybook to capture all component states, those that can be reproduced solely with props and those that require user interaction to be reached. Conventionally, developers run and receive feedback on tests written in Jest and Testing Library in the CLI. It prints several lines of text that report which assertions ( expect statements) passed and failed. However, it never shows what the component looks like when rendered. With Storybook and a Storybook addon called @storybook/addon-interactions , you get to view and interact with the rendered component in Storybook's Canvas. Plus, you get to see line-by-line reporting of the simulated user interactions and passed/failed assertions in Storybook's Interactions panel. By having everything under one roof this way, you only need to set up decorators like theming and routing just once, and the Storybook GUI trumps over the CLI for debugging UI issues. In v6.4.0 , Storybook introduced browser-compatible wrappers of Testing Library and Jest that power interactive stories. These type of stories automate user interactions using a play function. A new feature to Component Story Format (CSF) 3.0, the play function executes after the component has rendered in Storybook. Using methods from the Testing Library, the play function dispatches events, such as userEvent.click / fireEvent.click for clicking an element, that simulate user interactions in the browser. Below, I'm going to show you how to write interaction tests directly in Storybook. For this tutorial, we will be testing the functionality of a line chart built with React and D3: Specifically, we will test... To get started, clone the following repository: This repository contains a visualization component library with a customizable, multi-line chart written in React, D3 and TypeScript. Inside of the project directory, install the dependencies: Then, run Storybook to view and interact with the multi-line chart component <TimelineChart /> : Currently, there are three stories defined for this component in Storybook: The Default and Legend stories visualize the closing prices of several popular technology stocks from May 2013 to May 2022: Apple (AAPL), Amazon (AMZN), Facebook (FB), Google (GOOGL), Netflix (NFLX) and Tesla (TSLA). Before it renders a story, Storybook fetches the stock data with loaders . Once fetched, the loaded data gets injected into the story via loaded field on the story context, like so: For interaction testing, we must have three addons/integrations installed: Since initializing Storybook for a React project (via the sb init command) automatically installs @storybook/addon-interactions and @storybook/testing-library , all that's left to install is @storybook/jest . Note : The React project must have react and react-dom installed prior to running sb init for the command to choose the correct Storybook project type and install these Storybook addons/integrations. When you open the .storybook/main.ts file, you will find the @storybook/addon-interactions addon already registered. To enable the addon's experimental step debugging features, set interactionsDebugger to true , like so: ( .storybook/main.ts ) Let's write some interaction tests for the <TimelineChart /> component. First, we will write an interaction test for validating the toggling behavior in the chart's legend. We expect the user to be able to toggle lines in the chart by checking/unchecking their corresponding legend keys. Initially, all the lines will be visible in the chart. The play function will simulate a user unchecking all of the legend keys but the first one. By the end, only the line corresponding to the first legend key that's left checked will remain rendered in the chart. The other lines will have been removed. Start by defining a story named ToggledLines . Since the chart requires a legend for toggling, the story will accept the same set of arguments as the Legend story. ( src/stories/TimelineChart.stories.tsx ) Next, let's define a play function on this story, like so: ( src/stories/TimelineChart.stories.tsx ) The play function receives a context object that contains lots of information about the story. For most interaction tests, you will be concerned with only three pieces of information: Now, at the top of the src/stories/TimelineChart.stories.tsx file, import several methods and objects from @storybook/testing-library and @storybook/jest to help simulate user interactions and perform assertions in the play function: ( src/stories/TimelineChart.stories.tsx ) Within the play function... ( src/stories/TimelineChart.stories.tsx ) Challenge : Change the play function so that it asserts that the lines corresponding to all but the first legend key no longer exist within the document. When you visit the ToggledLines story in the Storybook UI, you will notice that Storybook successfully simulated the user interactions and the assertion passed. Here, the canvas displays the component with only one line, the one that corresponds to the first legend key, which we left checked. Let's move on to the next interaction test. For this interaction test, we will validate the behavior of the chart's bisector line and cursor. When the user clicks on a line, the other lines fade out, and the bisector line and cursor appears and attaches to the clicked line. As the user moves their cursor, the bisector's infobox should display the exact value based on the nearest x-axis value. Start by defining a story named SelectedLine . Since multiple lines should fade out when the user clicks on a line, and coloring each line helps the user track the stock that they're interested in, the story will accept the same set of arguments as the Legend story. ( src/stories/TimelineChart.stories.tsx ) Next, let's define a play function on this story, like so: ( src/stories/TimelineChart.stories.tsx ) Since userEvent lacks support for a mousemove event, we need to import fireEvent from @storybook/testing-library . ( src/stories/TimelineChart.stories.tsx ) Within the play function... ( src/stories/TimelineChart.stories.tsx ) When you visit the SelectedLine story in the Storybook UI, you will notice that Storybook successfully simulated the user interactions and the assertions passed. Here, the canvas displays the component with only one line selected, the one that corresponds to the first legend key. A bisector line and cursor is attached to this line and is positioned in the center of the chart's bounded area. On September 1, 2017, the closing price of Apple stock (AAPL) was ~$41.01. What if you wanted to test a scenario in which the user unchecks all but the first legend key, clicks on the line that corresponds to the first legend key and moves their mouse to the center of the chart's bounded area to see what the stock's closing price was at that date within the bisector's infobox? A story that tests this scenario is a combination of the ToggledLines and SelectedLine stories. Rather than duplicating the simulated user interactions and assertions in these stories' play functions, you can re-use these stories' play functions and compose them to simulate complex scenarios like the one just mentioned, like so: ( src/stories/TimelineChart.stories.tsx ) All you need to do is pass the story's play function's context object to both play functions and call them in succession. When you visit the SelectedLine story in the Storybook UI, you will notice that Storybook successfully simulated the user interactions and the assertions passed. Here, the canvas displays exactly what the canvas for the SelectedLine story displayed, but with only one line shown, the one that corresponds to the first legend key. This is the final code for the src/stories/TimelineChart.stories.tsx file. If you find yourself stuck at any point while working through this tutorial, then feel free to visit the main branch of this GitHub repository here for the code. Try migrating your own project's testing suite over to Storybook. If you want to learn more advanced techniques with Storybook, then check out the Storybook for React Apps course by Yann Braga, a senior software engineer at Chromatic and a maintainer of Storybook: As a member of the Storybook team, Yann also worked on many of Storybook's testing-related packages, such as @storybook/addon-interactions , @storybook/test-runner , @storybook/testing-react , @storybook/testing-library  and @storybook/jest .

Thumbnail Image of Tutorial Interaction Testing in Storybook

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Embedding Figma Files in Storybook

The best design and development teams imbue design and brand consistency across multiple products with design systems . When designers and developers collaborate on and regularly contribute to a design system, communication between designers and developers improves since a design system serves as a single source of truth for design guidelines, workflows and elements. By having a design system, everyone understands what set of colors, typography, components, etc. defines the brand and unifies the digital experience. A tool for building robust design systems is Figma . Unlike most other tools, Figma allows teams to work together on design systems in real-time. Design systems constantly evolve to meet users' growing expectations and/or adopt the latest UI/UX trends and patterns, so using a tool like Figma helps to organize, maintain and easily locate design elements. Plus, Figma provides an Inspect panel , which gives developers an easy way to extract CSS code from any design element. This close mapping to code makes developer handoff more seamless. Designers can edit styles and assets within the design system, and developers can view those changes immediately and quickly adapt them into the products. Pairing Figma with Storybook speeds up this process. With a single Storybook addon, storybook-addon-designs , a Figma design system (or any design system) gets directly embedded in the addon panel of the Storybook UI. Any updates made to the design system are synced to the Storybook addon, so developers don't have to switch back and forth between Figma and Storybook to implement these updates in code. They no longer need to ask for links to the updated parts of the design system. Below, I'm going to show you how to embed a Figma file in Storybook with the storybook-addon-designs addon. For this tutorial, we will recreate a button component from the Material 3 Design Kit with React and write stories that represent the different UI states this component supports (e.g., disabled). Material 3 Design Kit is a Figma community file for Google's open-source Material design system . Before proceeding further, duplicate this file to your Figma account's Draft folder and open it to ensure you have access to the design system. When you navigate to the "Components" page, you should see the buttons in the Figma canvas. To get started, create a new directory named figma-storybook and initialize it with a package.json file: Install React and React DOM as dependencies: Install Storybook via the Storybook CLI: Note : Storybook automatically has built-in TypeScript support, so any components written in TypeScript should work with Storybook with no additional configuration needed. To style the React component, install two packages of the Emotion library as dependencies: Within the root of this project's directory, create a src directory and move the stories directory to this directory. Then, delete the contents of the stories directory. Since we moved the stories directory, let's inform Storybook of the new location of this directory: ( .storybook/main.js ) Looking at the design system in Figma, the button's CSS styles can be copied from the Inspect panel. Using these CSS styles, let's implement the button as a React component. Within the src directory, create a components directory and add two files: Here, we will define the button types filled , outlined , text , elevated and tonal as button categories to avoid any confusion with HTML <button /> types ( button , submit and reset ). Each category comes with five unique visual states: enabled , hovered , focused , pressed and disabled . We can implement the hovered , focused and pressed states purely with CSS via the pseudo-classes :hover , :focus and :active respectively. enabled serves as the default state, and disabled can be controlled via the <button /> element's disabled attribute. Now, let's write the <Button /> component and its styles: ( src/components/Button.tsx ) ( src/components/Button.styles.tsx ) Note : The ::after pseudo-element emulates the ripple effect that's recognizable from Material Design UIs. When the user clicks or touches the button, the ripple spreads out in a circular motion from the point of interaction, like a ripple in water. The ripple gives visual feedback to the user that the element has been clicked or touched. For Storybook to load the button's font family "Roboto," let's wrap stories with a decorator that adds an Emotion <Global /> component for injecting global styles like CSS resets and font faces. In this case, the <Global /> component will import the "Roboto" font family from Google Fonts and make it available to all components rendered in stories. ( .storybook/preview.js ) Within the src/stories directory, let's create a Button.stories.tsx file: We will write two stories for the <Button /> component, one for the enabled default state and another for the disabled state. The story for the enabled state should render a button that's clickable and touchable. The story for the disabled state should render a button that's grayed out and not interactive. ( src/stories/Button.stories.tsx ) Run Storybook and check that the <Button /> component looks and behaves correctly. If a designer decides to change the color of the button in the design system, then you would have to launch Figma and open the design system in Figma before being able to see what the new color is and copy the new color from the Inspect panel. Let's improve this workflow by having the design system readily accessible in Storybook. To connect stories directly to Figma, install the storybook-addon-designs addon as a dev. dependency: Within the .storybook/main.js file, register the storybook-addon-designs addon. ( .storybook/main.js ) In Figma, right-click on the filled button with the text "Enabled" and copy its link. A link makes navigating large Figma files easier by referencing a specific element within the file. When visiting the link, Figma brings the referenced element to the forefront of the canvas and highlights it. Within the src/stories/Button.stories.tsx file, set a design parameter for the Enabled story via the parameters key, like so: Parameters define a story's metadata and determine which addons to apply to a story. In this case, the design parameter tells Storybook to apply the storybook-addon-designs addon to the Enabled story. The object set to design configures the storybook-addon-designs addon for the Enabled story. ( src/stories/Button.stories.tsx ) type specifies the type of resource (e.g., image for image, iframe for iframe, figma for Figma file, etc.) to embed in the addon panel. url specifies the URL of the resource. For the Enabled story, we specify the type as figma and the url as the link to the filled button with the text "Enabled" in the Figma file to embed a live view of the Figma file (zoomed into this button) in the addon panel. Save the changes and wait for the Storybook UI to reload. The view has a "Figma" label in the top-left corner, and the user can move around and zoom in (and out of) the Figma file. Since you have a different link for each component variant, let's repeat these same steps for the Disabled story. ( src/stories/Button.stories.tsx ) Currently, all you can do within the live view is move around and zoom in (and out of) the Figma file. To be able to inspect design tokens and extract CSS code from the live view, we must embed the Figma file with an enhanced spec viewed called Figspec . The storybook-addon-designs addon supports a figspec type, but it requires providing a Figma access token to Storybook so that the addon can tell the Figma API to render the Figma file using Figspec components. Let's generate a Figma access token by: Copy the Figma access token. Then, create a .env file within the root of the project directory and add an environment variable named STORYBOOK_FIGMA_ACCESS_TOKEN that's set to the copied token. ( .env ) Within the src/stories/Button.stories.tsx file, replace all instances of the figma type with the figspec type, like so: ( src/stories/Button.stories.tsx ) Restart Storybook so that the environment variable is loaded. When you click on the button in the live view, a panel with the button's CSS code appears. Note : You can click either the button's background or the button's text to get either's CSS code. If you change the background color of the button in the Figma file, then that change will automatically be seen in the live view. If you find yourself stuck at any point while working through this tutorial, then feel free to visit the main branch of this GitHub repository here for the code. Try integrating your Figma design systems into your project's Storybook UI. If you want to learn more advanced techniques with Storybook, then check out the Storybook for React Apps course by Yann Braga, a senior software engineer at Chromatic and a maintainer of Storybook:

Thumbnail Image of Tutorial Embedding Figma Files in Storybook

Kickstart Your Next Project with Deno and PostgreSQL

Most modern web applications rely on a relational database management system (RDBMS) to store and retrieve troves of related data. When you bring together two modern, open-source technologies, Deno and PostgreSQL , you can build production-grade web applications that... Since Deno was built as an improved, alternative V8 runtime to Node.js, Deno projects can use both the third-party modules developed specifically to work with Deno and the many third-party packages that exist in the npm ecosystem. A popular PostgreSQL client for Node.js projects is node-postgres . If you visit the deno.land/x website and search postgres , then you will come across deno-postgres , a lightweight PostgreSQL driver that was developed specifically for Deno. The API and underlying implementation of deno-postgres is based on two popular PostgreSQL drivers: node-postgres (coincidentally) and pq , a Go PostgreSQL driver. deno-postgres provides abstractions for features and operations that allow you to unleash the full potential of PostgreSQL: connection pools, prepared statements, transactions and typed queries. Below, I'm going to show you how to... To get started, let's use Docker to spin up a new PostgreSQL database on the local machine. Running this command creates a new Docker container based on the official postgres Docker image. The docker run command accepts several options and flags that override image and Docker runtime defaults. For this tutorial, the database's schema design is based on a bank. The schema consists of three tables: To create tables in the database, let's run a SQL file directly against the pg_db_container container. With this approach, we never have to copy the SQL file from the host machine to the container. First, create a SQL file named create-db.sql that creates the customers , accounts and transactions tables: ( create-db.sql ) Then, run the following command, which pipes the contents of the create-db.sql SQL file (as a command string) to the psql command that's ran within the pg_db_container container: Alternatively, you can create a Dockerfile that extends the postgres image and copies the create-db.sql file from the host machine to the container's /docker-entrypoint-initdb.d directory. All scripts within this directory are ran at the time the container starts up (and the container's data directory is also empty). Note : Do not adopt this schema for production. The database does not fully reflect what actually happens in the real world. For example, it does not account for the differences in the number of digits a checking account number has (commonly ) and a savings account number has (commonly ). Also, for simplicity's sake, balance calculations only involve integer values. Remember, the main focus of this tutorial is to demonstrate the capabilities of deno-postgres . Now, create a SQL file named seed-customers.sql that inserts three customer records into the customers table. ( seed-customers.sql ) Then, run the following command to populate the database with these three customers: To verify that the database has been successfully seeded with this data, let's query the database with the psql interactive shell: You will be prompted to enter the superuser's password. Once entered, the terminal launches the psql interactive shell, which runs inside the PostgreSQL database server. Enter the following SQL SELECT statement to query the customers table for the seeded data: Create a new project folder named deno-postgres . Within this folder, create a server.ts file. Within server.ts , write a simple HTTP server that responds to every request with a "Hello World!" message. ( deno-postgres/server.ts ) To run the server, execute the following command: The --allow-net option grants network access to the Deno script. When you visit http://localhost:8000/ (or any URL beginning with http://localhost:8000/ ) in your browser, you will find the "Hello World!" message printed on the page. Oak is an HTTP middleware framework for Deno that includes a router middleware. Both the framework and router are inspired by Koa , so if you have any prior experience working with Koa, then many aspects of the code should look quite familiar. Let's modify the server to only respond to requests sent to a GET / endpoint by enabling routing. ( deno-postgres/server.ts ) Re-run the server. The browser only prints the "Hello World!" message for http://localhost:8000/ . As we progress in this tutorial, each new route (and route handler) we add to this router will demonstrate the features and operations that deno-postgres comes with. To connect to the PostgreSQL database, let's import the PostgreSQL client from deno-postgres . Then, create and initialize a new instance of the PostgreSQL client, like so: Each PostgreSQL client instance manages a connection to a single PostgreSQL database. The configuration options we pass to Client tell the driver everything it needs to know to connect to the PostgreSQL database, such as the database's hostname and the credentials of the superuser. You can find more options here . For encrypted connections to the database via SSL/TLS, click here . Call the client's connect method to connect to the database. Call the client's end method to terminate the connection to the database. To ensure the script starts the server only when the client has successfully connected to the PostgreSQL database, perform both client.connect and app.listen in a try block. Any errors that prevent the server from running will terminate the connection to the database. When you run the server, Deno prompts you to grant access to several PostgreSQL environment variables: Press y to grant access for each requested environment variable. To skip this series of prompts, run the Deno script with the --allow-env flag, like so: If the terminal shows no error messages, and the server returns a "Hello World!" message for a GET / request, then the server has successfully connected to the dockerized PostgreSQL database. The recommended way to execute queries is with prepared statements, especially if your application accepts user input. Prepared statements protect your PostgreSQL database from SQL injection attacks. Since the SQL code (statement template) is pre-compiled, prepared statements are also efficient. The statement template consists of a base SQL statement with placeholders for bind variables. Let's write our first prepared statement for querying the customers table based on the customer's first name. Within the deno-postgres/server.ts file, define a new route on the router for the GET /customers endpoint. This endpoint will return customers from the customers table based on a query parameter, firstName . Using this query parameter, we can tell the query to only find customers whose first name matches the value of firstName . For example, firstName=alice would filter the table for any customer who has a first name of "Alice." To extract query parameters from the URL, import the getQuery method from Oak's helpers module, like so: helpers provides APIs for managing router contexts. Then, using the client.queryArray method, write a route handler for the GET /customers endpoint that... The client.queryArray method executes the query and returns the results of the query as an array. It can accept, at most, two arguments: Note : client.queryArray also accepts named arguments . In the WHERE clause, ILIKE is used for case-insensitive string matching. A % sign in the pattern matches for any sequence of characters. So if the URL does not contain a firstName query parameter (or it's set explicitly to an empty string), then the ILIKE will match for any first_name . Note : Don't use % as a default value for ILIKE conditions in production. This is just a quick and easy implementation that ensures all customers are returned if the user decides not to provide any query parameters. Re-run the server. When you visit http://localhost:8000/customers?firstName=alice in a browser, you will see the results of the query. Note : You can use cURL or an application like Postman to send the request. The above is shown in a Chrome browser using the JSONView extension. In this case, because the customers table had a customer whose first name is "Alice," that record ( id , firstName and lastName ) was returned as an array of values. The first value corresponds to the first column id , the second value corresponds to the second column firstName , and the third value corresponds to the third column lastName . Now, let's check that the prepared statement guards against SQL injection attacks. Within the browser, visit http://localhost:8000/customers?firstName=alice%20OR%201%3D1 . If the value of the firstName query parameter was directly placed within the SQL statement, then the SQL statement would be SELECT id, first_name, last_name FROM customers WHERE first_name ILIKE 'alice' OR 1=1 . With the OR operator and 1=1 condition, the WHERE clause always evaluates to true . You would expect all the rows in the customers table to be leaked. However, that's not what happens: Yet, if use psql to execute this same SQL statement, then all the rows in the customers table are leaked. The client correctly executes the query as SELECT id, first_name, last_name FROM customers WHERE first_name ILIKE 'alice OR 1=1' , not SELECT id, first_name, last_name FROM customers WHERE first_name ILIKE 'alice' OR 1=1 . Let's add another query parameter, lastName , to find customers whose last name matches the value of lastName . Re-run the server. When you visit http://localhost:8000/customers?firstName=alice&lastName=king in a browser, you will see the results of the query. Note : There's also a queryObject method, which accepts the same arguments as the queryArray method, but returns the response as an object with the column names as keys. Altogether, the deno-postgres/server.ts file should look like this: ( deno-postgres/server.ts ) Try using PostgreSQL and Deno for your next project! To learn how to create and deploy a production-ready, REST API with Deno from scratch, check out Halvard Mørstad's course here . Halvard is a software engineer and is the author of Nessie , a modular database migration tool for Deno.

Thumbnail Image of Tutorial Kickstart Your Next Project with Deno and PostgreSQL

Fullstack React with TypeScript Masterclass is LIVE 🎉

The Fullstack React with TypeScript Masterclass is now live! 🎉   This Masterclass teaches you practical React and TypeScript for developing apps from idea to completion, along with all the important tools in the React ecosystem. It expands on the material taught in our comprehensive book,  Fullstack React with TypeScript , and gives you over 10 hours of video lessons taught by Maksim Ivanov. By the end of the first module, you'll already have created your environment for React with TypeScript, and you will have completed basic tasks with TypeScript. The subsequent modules then continue your journey through building multiple apps and learning techniques including: This masterclass was developed by Maksim Ivanov and Alex Bespoyasov and taught by Maksim. Maksim worked for leading game developer Mojang, where he helped develop front-end interfaces with React and TypeScript. He has continued his front-end work at Spotify, where he develops interfaces with React, TypeScript, and related tools.  Alex is a frontend developer and works with technology company 0+X where he consults on developing and maintaining applications with React and related tooling.  With their combined depth of expertise, Maksim and Alex will quickly get you up to speed on creating modern React and TypeScript apps that your users will love. You can read more details about the Masterclass over at the Fullstack React with TypeScript Masterclass page .

Thumbnail Image of Tutorial Fullstack React with TypeScript Masterclass is LIVE 🎉