Tuesday, September 26, 2017

React Router v4: The Complete Guide

React Router is the de facto standard routing library for React. When you need to navigate through a React application with multiple views, you'll need a router to manage the URLs. React Router takes care of that, keeping your application UI and the URL in sync.

This tutorial introduces you to React Router v4 and a whole lot of things you can do with it.

Introduction

React is a popular library for creating single-page applications (SPAs) that are rendered on the client side. An SPA might have multiple views (aka pages), and unlike the conventional multi-page apps, navigating through these views shouldn't result in the entire page being reloaded. Instead, we want the views to be rendered inline within the current page. The end user, who's accustomed to multi-page apps, expects the following features to be present in an SPA:

  • Each view in an application should have a URL that uniquely specifies that view. This is so that the user can bookmark the URL for reference at a later time --- e.g. http://ift.tt/1BB3jk3.
  • The browser's back and forward button should work as expected.
  • The dynamically generated nested views should preferably have a URL of their own too --- e.g. http://ift.tt/2fN1aNZ, where 101 is the product id.

Routing is the process of keeping the browser URL in sync with what's being rendered on the page. React Router lets you handle routing declaratively. The declarative routing approach allows you to control the data flow in your application, by saying "the route should look like this":

<Route path="/about" component={About}/>

You can place your <Route> component anywhere that you want your route to be rendered. Since <Route>, <Link> and all the other React Router API that we'll be dealing with are just components, you can easily get used to routing in React.

A note before getting started. There's a common misconception that React Router is an official routing solution developed by Facebook. In reality, it's a third-party library that's widely popular for its design and simplicity. If your requirements are limited to routers for navigation, you could implement a custom router from scratch without much hassle. However, understanding how the basics of React Router will give you better insights into how a router should work.

Overview

React Router Logo This tutorial is divided into different sections. First, we'll be setting up React and React Router using npm. Then we'll jump right into React Router basics. You'll find different code demonstrations of React Router in action. The examples covered in this tutorial include:

  1. basic navigational routing
  2. nested routing
  3. nested routing with path parameters
  4. protected routing

All the concepts connected with building these routes will be discussed along the way. The entire code for the project is available on this GitHub repo. Once you're inside a particular demo directory, run npm install to install the dependencies. To serve the application on a development server, run npm start and head over to http://localhost:3000/ to see the demo in action.

Let's get started!

Setting up React Router

I assume you already have a development environment up and running. If not, head over to “Getting Started with React and JSX”. Alternatively, you can use Create React App to generate the files required for creating a basic React project. This is the default directory structure generated by Create React App:

 react-routing-demo-v4
    ├── .gitignore
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   └── manifest.json
    ├── README.md
    ├── src
    │   ├── App.css
    │   ├── App.js
    │   ├── App.test.js
    │   ├── index.css
    │   ├── index.js
    │   ├── logo.svg
    │   └── registerServiceWorker.js
    └── yarn.lock

The React Router library comprises three packages: react-router, react-router-dom, and react-router-native. react-router is the core package for the router, whereas the other two are environment specific. You should use react-router-dom if you're building a website, and react-router-native if you're on a mobile app development environment using React Native.

Use npm to install react-router-dom:

npm install --save react-router-dom

React Router Basics

Here's an example of how our routes will look:

<Router>
  <Route exact path="/" component={Home}/>
  <Route path="/category" component={Category}/>
  <Route path="/login" component={Login}/>
  <Route path="/products" component={Products}/>
</Router>

Router

You need a router component and several route components to set up a basic route as exemplified above. Since we're building a browser-based application, we can use two types of routers from the React Router API:

  1. <BrowserRouter>
  2. <HashRouter>

The primary difference between them is evident in the URLs that they create:

// <BrowserRouter>
http://ift.tt/1gCdD0Y

// <HashRouter>
http://ift.tt/1mOPrIK

The <BrowserRouter> is more popular amongst the two because it uses the HTML5 History API to keep track of your router history. The <HashRouter>, on the other hand, uses the hash portion of the URL (window.location.hash) to remember things. If you intend to support legacy browsers, you should stick with <HashRouter>.

Wrap the <BrowserRouter> component around the App component.

index.js

/* Import statements */
import React from 'react';
import ReactDOM from 'react-dom';

/* App is the entry point to the React code.*/
import App from './App';

/* import BrowserRouter from 'react-router-dom' */
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
    , document.getElementById('root'));

Note: A router component can only have a single child element. The child element can be an HTML element --- such as div --- or a react component.

For the React Router to work, you need to import the relevant API from the react-router-dom library. Here I've imported the BrowserRouter into index.js. I've also imported the App component from App.js. App.js, as you might have guessed, is the entry point to React components.

The above code creates an instance of history for our entire App component. Let me formally introduce you to history.

history

history is a JavaScript library that lets you easily manage session history anywhere JavaScript runs. history provides a minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions. --- React Training docs

Each router component creates a history object that keeps track of the current location (history.location) and also the previous locations in a stack. When the current location changes, the view is re-rendered and you get a sense of navigation. How does the current location change? The history object has methods such as history.push() and history.replace() to take care of that. history.push() is invoked when you click on a <Link> component, and history.replace() is called when you use <Redirect>. Other methods --- such as history.goBack() and history.goForward() --- are used to navigate through the history stack by going back or forward a page.

Moving on, we have Links and Routes.

Links and Routes

The <Route> component is the most important component in React router. It renders some UI if the current location matches the route's path. Ideally, a <Route> component should have a prop named path, and if the pathname is matched with the current location, it gets rendered.

The <Link> component, on the other hand, is used to navigate between pages. It's comparable to the HTML anchor element. However, using anchor links would result in a browser refresh, which we don't want. So instead, we can use <Link> to navigate to a particular URL and have the view re-rendered without a browser refresh.

We've covered everything you need to know to create a basic router. Let's build one.

Demo 1: Basic Routing

src/App.js

/* Import statements */
import React, { Component } from 'react';
import { Link, Route, Switch } from 'react-router-dom';

/* Home component */
const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
)

/* Category component */
const Category = () => (
  <div>
    <h2>Category</h2>
  </div>
)

/* Products component */
const Products = () => (
  <div>
    <h2>Products</h2>
  </div>
)

/* App component */
class App extends React.Component {
  render() {
    return (
      <div>
        <nav className="navbar navbar-light">
          <ul className="nav navbar-nav">

           /* Link components are used for linking to other views */
            <li><Link to="/">Homes</Link></li>
            <li><Link to="/category">Category</Link></li>
            <li><Link to="/products">Products</Link></li>

          </ul>
         </nav>

          /* Route components are rendered if the path prop matches the current URL */
           <Route path="/" component={Home}/>
           <Route path="/category" component={Category}/>
           <Route path="/products" component={Products}/>

      </div>
    )
  }
}

We've declared the components for Home, Category and Products inside App.js. Although this is okay for now, when the component starts to grow bigger, it's better to have a separate file for each component. As a rule of thumb, I usually create a new file for a component if it occupies more than 10 lines of code. Starting from the second demo, I'll be creating a separate file for components that have grown too big to fit inside the App.js file.

Inside the App component, we've written the logic for routing. The <Route>'s path is matched with the current location and a component gets rendered. The component that should be rendered is passed in as a second prop.

Here / matches both / and /category. Therefore, both the routes are matched and rendered. How do we avoid that? You should pass the exact= {true} props to the router with path='/':

<Route exact={true} path="/" component={Home}/>

If you want a route to be rendered only if the paths are exactly the same, you should use the exact props.

Nested Routing

To create nested routes, we need to have a better understanding of how <Route> works. Let's do that.

<Route> has three props that you can you use to define what gets rendered:

  • component. We've already seen this in action. When the URL is matched, the router creates a React element from the given component using React.createElement.
  • render. This is handy for inline rendering. The render prop expects a function that returns an element when the location matches the route's path.
  • children. The children prop is similar to render in that it expects a function that returns a React element. However, children gets rendered regardless of whether the path is matched with the location or not.

Path and match

The path is used to identify the portion of the URL that the router should match. It uses the Path-to-RegExp library to turn a path string into a regular expression. It will then be matched against the current location.

If the router's path and the location are successfully matched, an object is created and we call it the match object. The match object carries more information about the URL and the path. This information is accessible through its properties, listed below:

  • match.url. A string that returns the matched portion of the URL. This is particularly useful for building nested <Link>s
  • match.path. A string that returns the route's path string --- that is, <Route path="">. We'll be using this to build nested <Route>s.
  • match.isExact. A boolean that returns true if the match was exact (without any trailing characters).
  • match.params. An object containing key/value pairs from the URL parsed by the Path-to-RegExp package.

Now that we know all about <Route>s, let's build a router with nested routes.

Switch Component

Before we head for the demo code, I want to introduce you to the <Switch> component. When multiple <Route>s are used together, all the routes that match are rendered inclusively. Consider this code from demo 1. I've added a new route to demonstrate why <Switch> is useful.

<Route exact path="/" component={Home}/>
<Route path="/products" component={Products}/>
<Route path="/category" component={Category}/>
<Route path="/:id" render = {()=> (<p> I want this text to show up for all routes other than '/', '/products' and '/category' </p>)}/>

If the URL is /products, all the routes that match the location /products are rendered. So, the <Route> with path :id gets rendered along with the Products component. This is by design. However, if this is not the behavior you're expecting, you should add the <Switch> component to your routes. With <Switch>, only the first child <Route> that matches the location gets rendered.

Continue reading %React Router v4: The Complete Guide%


by Manjunath M via SitePoint

XXXI

Brutalist One Pager promoting XXXI, a NY-based exhibition and studio space for XXIX, Michael Groth, David McGillivray, and Thierry Blancpain.

Full Review | Direct Link


by Rob Hope @robhope via One Page Love

Getting Started with Redux

A typical web application is usually composed of several UI components that share data. Often, multiple components are tasked with the responsibility of displaying different properties of the same object. This object represents state which can change at any time. Keeping state consistent among multiple components can be a nightmare, especially if there are multiple channels being used to update the same object.

Take, for example, a site with a shopping cart. At the top we have a UI component showing the number of items in the cart. We could also have another UI component that displays the total cost of items in the cart. If a user clicks the Add to Cart button, both of these components should update immediately with the correct figures. If the user decides to remove an item from the cart, change quantity, add a protection plan, use a coupon or change shipping location, then the relevant UI components should update to display the correct information. As you can see, a simple shopping cart can quickly become difficult to keep in sync as the scope of its features grows.

In this guide, I'll introduce you to a framework known as Redux, which can help you build complex projects in way that's easy to scale and maintain. To make learning easier, we'll use a simplified shopping cart project to learn how Redux works. You'll need to be at least familiar with the React library, as you'll later need to integrate it with Redux.

Prerequisites

Before we get started, make sure you're familiar with the following topics:

Also, ensure you have the following setup on your machine:

You can access the entire code used in this tutorial on GitHub.

What is Redux

Redux Logo Redux is a popular JavaScript framework that provides a predictable state container for applications. Redux is based on a simplified version of Flux, a framework developed by Facebook. Unlike standard MVC frameworks, where data can flow between UI components and storage in both directions, Redux strictly allows data to flow in one direction only. See the below illustration:

Redux Flow Chart

Figure 1: Redux Flow Chart

In Redux, all data --- i.e. state --- is held in a container known as the store. There can only be one of these within an application. The store is essentially a state tree where states for all objects are kept. Any UI component can access the state of a particular object directly from the store. To change a state from a local or remote component, an action needs to be dispatched. Dispatch in this context means sending actionable information to the store. When a store receives an action, it delegates it to the relevant reducer. A reducer is simply a pure function that looks at the previous state, performs an action and returns a new state. To see all this in action, we need to start coding.

Understand Immutability First

Before we start, I need you to first understand what immutability means in JavaScript. According to the Oxford English Dictionary, immutability means being unchangeable. In programming, we write code that changes the values of variables all the time. This is referred to as mutability. The way we do this can often cause unexpected bugs in our projects. If your code only deals with primitive data types (numbers, strings, booleans), then you don't need to worry. However, if you're working with Arrays and Objects, performing mutable operations on them can create unexpected bugs. To demonstrate this, open your terminal and launch the Node interactive shell:

node

Next, let's create an array, then later assign it to another variable:

> let a = [1,2,3]
> let b = a
> b.push(9)
> console.log(b)
[ 1, 2, 3, 9 ] // b output
> console.log(a)
[ 1, 2, 3, 9 ] // a output

As you can see, updating array b caused array a to change as well. This happens because Objects and Arrays are known referential data types --- meaning that such data types don't actually hold values themselves, but are pointers to a memory location where the values are stored. By assigning a to b, we merely created a second pointer that references the same location. To fix this, we need to copy the referenced values to a new location. In JavaScript, there are three different ways of achieving this:

  1. using immutable data structures created by Immutable.js
  2. using JavaScript libraries such as Underscore and Lodash to execute immutable operations
  3. using native ES6 functions to execute immutable operations.

For this article, we'll use the ES6 way, since it's already available in the NodeJS environment. Inside your NodeJS terminal, execute the following:

> a = [1,2,3] // reset a
[ 1, 2, 3 ]
> b = Object.assign([],a) // copy array a to b
[ 1, 2, 3 ]
> b.push(8)
> console.log(b)
[ 1, 2, 3, 8 ] // b output
> console.log(a)
[ 1, 2, 3 ] // a output

In the above code example, array b can now be modified without affecting array a. We've used Object.assign() to create a new copy of values that variable b will now point to. We can also use the rest operator(...) to perform an immutable operation like this:

> a = [1,2,3]
[ 1, 2, 3 ]
> b = [...a, 4, 5, 6]
[ 1, 2, 3, 4, 5, 6 ]
> a
[ 1, 2, 3 ]

The rest operator works with object literals too! I won't go deep into this subject, but here are some additional ES6 functions that we'll use to perform immutable operations:

In case the documentation I've linked isn't useful, don't worry, as you'll see how they're used in practice. Let's start coding!

Setting up Redux

The fastest way to set up a Redux development environment is to use the create-react-app tool. Before we begin, make sure you've installed and updated nodejs, npm and yarn. Let's set up a Redux project by generating a redux-shopping-cart project and installing the Redux package:

create-react-app redux-shopping-cart

cd redux-shopping-cart
yarn add redux # or npm install redux

Delete all files inside the src folder except index.js. Open the file and clear out all existing code. Type the following:

import { createStore } from "redux";

const reducer = function(state, action) {
  return state;
}

const store = createStore(reducer);

Let me explain what the above piece of code does:

  • 1st statement. We import a createStore() function from the Redux package.
  • 2nd statement. We create an empty function known as a reducer. The first argument, state, is current data held in the store. The second argument, action, is a container for:
    • type --- a simple string constant e.g. ADD, UPDATE, DELETE etc.
    • payload --- data for updating state
  • 3rd statement. We create a Redux store, which can only be constructed using a reducer as a parameter. The data kept in the Redux store can be accessed directly, but can only be updated via the supplied reducer.

You may have noticed I mentioned current data as if it already exists. Currently, our state is undefined or null. To remedy this, just assign a default value to state like this to make it an empty array:

const reducer = function(state=[], action) {
  return state;
}

Now, let's get practical. The reducer we created is generic. Its name doesn't describe what it's for. Then there's the issue of how we work with multiple reducers. The answer is to use a combineReducers function that's supplied by the Redux package. Update your code as follows:

// src/index.js
…
import { combineReducers } from 'redux';

const productsReducer = function(state=[], action) {
  return state;
}

const cartReducer = function(state=[], action) {
  return state;
}

const allReducers = {
  products: productsReducer,
  shoppingCart: cartReducer
}

const rootReducer = combineReducers(allReducers);

let store = createStore(rootReducer);

In the code above, we've renamed the generic reducer to cartReducer. There's also a new empty reducer named productsReducer that I've created just to show you how to combine multiple reducers within a single store using the combineReducers function.

Next, we'll look at how we can define some test data for our reducers. Update the code as follows:

// src/index.js
…
const initialState = {
  cart: [
    {
      product: 'bread 700g',
      quantity: 2,
      unitCost: 90
    },
    {
      product: 'milk 500ml',
      quantity: 1,
      unitCost: 47
    }
  ]
}

const cartReducer = function(state=initialState, action) {
  return state;
}
…
let store = createStore(rootReducer);

console.log("initial state: ", store.getState());

Just to confirm that the store has some initial data, we use store.getState() to print out the current state in the console. You can run the dev server by executing npm start or yarn start in the console. Then press Ctrl+Shift+I to open the inspector tab in Chrome in order to view the console tab.

Redux Initial State

Figure 2: Redux Initial State

Currently, our cartReducer does nothing, yet it's supposed to manage the state of our shopping cart items within the Redux store. We need to define actions for adding, updating and deleting shopping cart items. Let's start by defining logic for a ADD_TO_CART action:

// src/index.js
…
const ADD_TO_CART = 'ADD_TO_CART';

const cartReducer = function(state=initialState, action) {
  switch (action.type) {
    case ADD_TO_CART: {
      return {
        ...state,
        cart: [...state.cart, action.payload]
      }
    }

    default:
      return state;
  }
}
…

Take your time to analyze and understand the code. A reducer is expected to handle different action types, hence the need for a SWITCH statement. When an action of type ADD_TO_CART is dispatched anywhere in the application, the code defined here will handle it. As you can see, we're using the information provided in action.payload to combine to an existing state in order to create a new state.

Next, we'll define an action, which is needed as a parameter for store.dispatch(). Actions are simply JavaScript objects that must have type and an optional payload. Let's go ahead and define one right after the cartReducer function:

…
function addToCart(product, quantity, unitCost) {
  return {
    type: ADD_TO_CART,
    payload: { product, quantity, unitCost }
  }
}
…

Here, we've defined a function that returns a plain JavaScript object. Nothing fancy. Before we dispatch, let's add some code that will allow us to listen to store event changes. Place this code right after the console.log() statement:

…
let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

unsubscribe();

Next, let's add several items to the cart by dispatching actions to the store. Place this code before unsubscribe():

…
store.dispatch(addToCart('Coffee 500gm', 1, 250));
store.dispatch(addToCart('Flour 1kg', 2, 110));
store.dispatch(addToCart('Juice 2L', 1, 250));

For clarification purposes, I'll illustrate below how the entire code should look after making all the above changes:

// src/index.js

import { createStore } from "redux";
import { combineReducers } from 'redux';

const productsReducer = function(state=[], action) {
  return state;
}

const initialState = {
  cart: [
    {
      product: 'bread 700g',
      quantity: 2,
      unitCost: 90
    },
    {
      product: 'milk 500ml',
      quantity: 1,
      unitCost: 47
    }
  ]
}

const ADD_TO_CART = 'ADD_TO_CART';

const cartReducer = function(state=initialState, action) {
  switch (action.type) {
    case ADD_TO_CART: {
      return {
        ...state,
        cart: [...state.cart, action.payload]
      }
    }

    default:
      return state;
  }
}

function addToCart(product, quantity, unitCost) {
  return {
    type: ADD_TO_CART,
    payload: {
      product,
      quantity,
      unitCost
    }
  }
}

const allReducers = {
  products: productsReducer,
  shoppingCart: cartReducer
}

const rootReducer = combineReducers(allReducers);

let store = createStore(rootReducer);

console.log("initial state: ", store.getState());

let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

store.dispatch(addToCart('Coffee 500gm', 1, 250));
store.dispatch(addToCart('Flour 1kg', 2, 110));
store.dispatch(addToCart('Juice 2L', 1, 250));

unsubscribe();

After you've saved your code, Chrome should automatically refresh. Check the console tab to confirm that the new items have been added:

Redux Actions Dispatched

Figure 3: Redux Actions Dispatched

Continue reading %Getting Started with Redux%


by Michael Wanyoike via SitePoint

10 Pages You Should Include on Your Website [infographic]

Are you considering creating a new website for your business? Are you unsure what pages you need to include? The answer does depend on what your business does, a builder will have some different page titles than an online shop that sells handbags for example, but there are 10 types of pages you...

[ This is a content summary only. Visit our website http://ift.tt/1b4YgHQ for full links, other content, and more! ]

by Web Desk via Digital Information World

15 Top Prototyping Tools Go Head-to-Head

As the number and variety of prototyping tools continues to grow, it’s becoming harder and harder to figure out which tools meet what needs, and who they’re suitable for. Since we first wrote this article back in 2015, countless design apps have dominated (and changed) the prototyping space.

Stakeholder feedback and user testing is now taking a far greater role in UI design and this new generation of tools aims to connect these two previously separate stages of the design process. Clients want to be involved, and email isn’t cutting it anymore. Some apps like UXPin are also taking care of the wireframing stages, whereas others like InVision App are bridging the gap between designer and developer by offering design handoff tools.

Plus, there’s now a clear divide between desktop tools with cloud sharing (Adobe XD, Axure, Balsamiq, Sketch+InVision) and collaborative online tools (Figma, UXPin, Fluid UI, Proto.io).

Many of these tools appear to be converging on a feature set that defines the role of the modern user experience designer. TL;DR—here’s a swift comparison of prototyping tools.

Adobe XD

Adobe may have been caught napping during the rise of Sketch, but they’re rapidly making up for it with Adobe XD. Launched in March 2016, and still in beta as of July 2017, it’s the latest addition to Adobe’s Creative Cloud Suite. While you can prototype interactions in Sketch with the help of the Craft Plugin, Adobe XD impressively offers these tools right out of the box, so designers are already comparing Adobe XD to Sketch like longtime rivals.

It’s definitely worth a look if you’re interested in a tool that covers all your bases (low-fidelity prototyping, high-fidelity prototyping, user flows, sharing and feedback) in a single app.

Strengths

  • Available for macOS and Windows
  • Everything you need in a single app

Weaknesses

  • Still in beta (although pleasantly mature as a design app)
  • Plugin workflow non-existent, you’re locked into the Adobe ecosystem

InVision App (with Sketch and Craft)

InVision App is the largest and most successful design collaboration tool currently on the market, the primary go-to tool for serious designers and enterprise teams alike. With tools like whiteboard collaboration, dynamic prototyping, comments, device preview, video calling, user testing, version control and design handoff, InVision is already a colossal force in the prototyping space, but when you factor in its Sketch and Photoshop integrations, it becomes an all-in-one design suite, especially when you throw in Craft, the Sketch/Photoshop Plugin that brings a lot of that functionality directly into your design app of choice.

Strengths

  • Powerful, mature platform
  • Fully-integrated with Sketch for high-fidelity design
  • Constantly being updated with new features

Weaknesses

  • Feature-set can be a little overwhelming at first
  • Sketch is only available for macOS users only (but you can pair InVision with Photoshop on Windows, although Photoshop isn’t strictly a UI design tool)

Marvel App

A very strong favourite for those looking for simpler, friendlier alternatives to InVision App. Marvel App has excelled at creating a prototyping tool that works for both advanced UX designers and those simply looking to communicate high and low fidelity concepts. Plus, while they champion working with Sketch, they also offer component libraries to allow for a complete online workflow in Marvel. Marvel App also recently integrated fan-favourite POP, which allows designers to transform their pen/paper ideas into iPhone and Android apps.

Strengths

  • Great support for transitions for additional realism
  • Friendlier for non-designers, especially when giving feedback

Weaknesses

  • Web based only
  • No offline designing

UXPin

UXPin is the most complete online solution for UX designers in terms of their offering. While you can import from Sketch and Photoshop, you can also design complex and responsive interfaces with UXPin’s built-in libraries, making UXPin something of a wireframing tool as well. With their design systems features, UXPin becomes one of the most complex tools in terms of automated documentation, designer/developer handoffs and collaborative features.

Strengths

  • Responsive design with breakpoints
  • Powerful animations (not just linking screens)
  • Complete design collaboration and handoff solution

Weaknesses

  • A little pricey versus the competition at $49/user/month
  • Additional features increase the complexity of use

Webflow

Webflow is a visual tool for designing responsive websites that also exports clean code—it removes the headache of going from design to published on the web. Competing as much with WordPress as it does with Sketch App, Webflow lets you design fully functional responsive websites incorporating back-end (API) data and can automatically deploy to fully scalable, worry-free hosting with a single click of a button. It’s basically Adobe Dreamweaver for the modern-day designer who cares about clean code and mobile-friendly web design.

Strengths

  • Real data can be included (from APIs/JSON/etc)
  • Creates high-quality, reusable code
  • Responsive websites can be designed and deployed with ease

Weaknesses

  • Not useful for designing native mobile apps
  • Requires some knowledge of HTML/CSS to be at its most effective

Figma

A somewhat recent addition to the prototyping space, Figma boasts the most mesmerising real-time design collaboration features of any prototyping tool while modelling its feature-set on many of the intuitive design tools of Sketch and Adobe XD (such as symbols and device preview), along with a bunch of tools usually reserved for the online crowd (such as versioning and design handoff). Version 2.0, launched in July 2017, includes a prototyping mode with hotspots and developer handoffs to further streamline the design workflow. It works in the browser, on macOS, and on WIndows, although it sometimes can be slow.

Strengths

  • Real-time collaborative design features are second-to-none
  • Fully-featured, ideal for designers from start to finish

Weaknesses

  • Figma can can be laggy at time, especially with real-time collaboration

9 More Prototyping Tools Worth Considering

Fluid UI

With a strong focus on simplicity and communication, Fluid UI includes built-in high and low fidelity component libraries, live team collaboration, device previews and video presentations making it a top-notch solution for designers, product managers and founders alike.

Proto.io

Mature and feature-rich, Proto.io is best used by designers looking to create high-fidelity and highly-animated prototypes in the browser.

Axure RP 8

Established way back in 2003, Axure is an excellent choice for UX designers who need to create specifications for designs and animations in supreme detail. Axure’s includes support for conditional flow interactions, dynamic content and adaptive/responsive design, as well as high and low-fidelity prototyping. Axure is a serious tool for serious designers.

Continue reading %15 Top Prototyping Tools Go Head-to-Head%


by Dave Kearney via SitePoint

CSS font-display: The Future of Font Rendering on the Web

One of the downsides of using web fonts is that if a font is not available on a user’s device, it must be downloaded. This means that before the font becomes available the browser has to decide how to handle the display of any block of text that uses that font. And it needs to do so in a way that doesn’t significantly impact the user experience and perceived performance.

In the course of time, browsers have adopted several strategies to mitigate this problem. But they do this in different ways and out of the control of developers, who have had to devise several techniques and workarounds to overcome these issues.

Using Chrome DevTools to test font -display

Enter the font-display descriptor for the @font-face at-rule. This CSS feature introduces a way to standardize these behaviors and provide more control to developers.

Using font-display

Before looking in detail at the various features offered by font-display, let’s briefly consider how you might use the feature in your CSS.

First of all, font-display is not a CSS property but, as mentioned in the intro, it is a descriptor for the @font-face at-rule. This means that it must be used inside a @font-face rule, as showed in the following code:

[code language="css"]
@font-face {
font-family: 'Saira Condensed';
src: url(fonts/sairacondensed.woff2) format('woff2');
font-display: swap;
}
[/code]

In this snippet I’m defining a swap value for the font Saira Condensed.

The keywords for all the available values are:

  • auto
  • block
  • swap
  • fallback
  • optional

The initial value for font-display is auto.

In later sections I’ll go over each of these values in detail. But first, let’s look at the time period that the browser uses to determine the font to be rendered. When discussing each of the values, I’ll explain the different aspects of the timeline and how these behave for each value.

The font-display Timeline

At the core of this feature is the concept of the font-display timeline. The font loading time, starting from its request and ending with its successful loading or failure, can be divided into three consecutive periods that dictate how a browser should render the text. These three periods are as follows:

  • The block period. During this period, the browser renders the text with an invisible fallback font. If the requested font successfully loads, the text is re-rendered with that requested font. The invisible fallback font acts as a blank placeholder for the text. This reduces layout shifting when the re-rendering is performed.
  • The swap period. If the desired font is not yet available, the fallback font is used, but this time the text is visible. Again, if the loading font comes in, it is used.
  • The failure period. If the font does not become available, the browser doesn’t wait for it, and the text will be displayed with the fallback font on the duration of the current page visit. Note that this doesn’t necessarily mean that the font loading is aborted; instead, the browser can decide to continue it, so that the font will be ready for use on successive page visits by the same user.

Continue reading %CSS font-display: The Future of Font Rendering on the Web%


by Giulio Mainardi via SitePoint

Learn Computer Science With JavaScript: Part 2, Conditionals

Introduction

In part one of this series, our programs were only written as a sequence of statements. This structure severely limits what we can do. Say you are designing a program that needs to log in users. You may want to direct a user to one page if they give the correct credentials and send them to another if they aren’t registered. 

To do this, you need to use a decision structure like an if statement. This will perform an action only under certain conditions. If the condition does not exist, the action is not performed. In this tutorial, you'll learn all about conditionals.

Contents

  • If statements
  • Relational operators
  • If-else statement
  • Switch statements
  • Logical operators
  • Review
  • Resources

If Statements

A single if statement will perform an action if a condition is true. If the condition is false, the program will execute the next statement that is outside of the if block. In the following example, if the expression isRaining() is true, then we will putOnCoat() and putOnRainboots() then goOutside(). If isRaining() is false, the program will only execute goOutside().

This is the general form for writing an if statement:

The condition is an expression that has the value true or false. An expression that is true or false is called a boolean expression. Boolean expressions are made with relational operators. 

Relational Operators

A relational operator compares two values and determines if the relationship between them is true or false. They can be used to create boolean expressions for our conditions. Here is a list of relational operators with examples:

Operator Meaning Example Meaning
== equality x == y Is x equal to y?
===
strict equality  x === y Is x equal to y in value and type?
!=
inequality
x != y
Is x not equal to y?
!==
strict inequality
x !== y
Is x not equal to y in value and type?
> greater than
x > y
Is x greater than y?
< less than
x < y
Is x less than y?
>= greater than or equal
x >= y
Is x greater than or equal to y?
<= less than or equal
x <= y
Is x less than or equal to y?

It is important to note the difference between the equality operator == and the strict equality operator ===. For example, the expression 2 == "2" is true. But the expression 2 === "2" is false.  In the second example, the two values are different data types, and that is why the expression is false. It is best practice to use === or !==.

The following example will display the message, "You get an A".

Task

What is the value of the expression 5 > 3? 6 != "6"?

If-Else Statements

An if-else statement will execute one block of statements if its condition is true, or another block if its condition is false. The following example will display the message “valid username” because the condition is true.

This is the general form of an if-else statement:

Task

 What will be the output of this program:

It is also possible to check for more than one condition. Example:

This is the general form for writing multiple if-else-if statements:

Switch Statements

A switch statement is also used to conditionally execute some part of your program. The following example implements our roman numeral converter as a switch statement:

This is the general form of a switch statement:

Each case represents a value our expression can take. Only the block of code for the case that is true will execute. We include a break statement at the end of the code block so that the program exits the switch statement and doesn’t execute any other cases. The default case executes when none of the other cases are true.    

Task 

Write a switch statement that displays the day of the week given a number. For example, 1 = Sunday, 2 = Monday, etc.

Logical Operators

The and operator && and the or operator || allow us to connect two boolean expressions. The not operator ! negates an expression. To illustrate how logical operators work, we will look at a truth table. A truth table contains all the combinations of values used with the operators. I use P to represent the left-hand expression and Q for the right-hand expression.  

&& truth table:

P Q P && Q
true true true
true
false
false
false
true
false
false
false false

We read the table going across each row. The first row tells us that when P is true and Q is true, P && Q is true. The following example tests whether 82 is between 60 and 100 inclusive.

  • let x = 82;
  • x >= 60 && x <= 100
  • P: x >= 60 is true
  • Q: x <= 100 is true
  • P && Q: true && true

|| truth table:

P Q P || Q
true
true
true
true
false
true
false
false true
false
false
false

This example tests if 82 is outside the range 60–100:

  • let x = 82;
  • x < 60 || x > 100
  • P: x < 60 is false
  • Q: x > 100 is false
  • P || Q: false || false

! truth table:

P !P
true
false
false
true

Example:

  • x = 82
  • P: x > 0 is true
  • !P: false

Task

Fill in the table with the missing values.

P Q !P !Q !P && !Q
!P || !Q
true
true




true
false

false
true

false
false


Something useful to know about logical operators is that if the expression on the left side of the && operator is false, the expression on the right will not be checked because the entire statement is false. And if the expression on the left-hand side of an || operator is true, the expression on the right will not be checked because the entire statement is true.

Review

A program can execute blocks of code conditionally using boolean expressions. A boolean expression is written using relational operators. Logical operators allow us to combine boolean expressions. 

A single if statement gives the program one alternative path to take if a condition is met. If-else statements provide a second course of action if the condition is false. And if-else-if statements allow us to test multiple conditions. Switch statements can be used as an alternative to an if-else-if statement when you have multiple conditions to test. 

Next, in part 3, we will discuss loops.

Resources


by Alberta Williams via Envato Tuts+ Code