Standardizing how components are spaced in ReactNative

React Native Spacing System

Using margin and padding to control spacing between components introduces too many ways to accomplish the same goal. React Native Spacing System seeks to standardize your React Native code and increase legibility though the usage of spacing components.

Factory method are provided so that you can use your own spacing key instead of raw value.

TypeScript and Flow are both supported!

Installation

npm install react-native-spacing-system

or

yarn add react-native-spacing-system

Sentiment & Rationalization

Inspired by Nathan Curtis’s Medium article Space In Design Systems and this react-spacing library by Nathan Winder, I figured I’d do something similar for React Native with slight tweaks.

Stack: #45e6e6    Queue: #e645e6    Inset: #e6e645

For the full sentiment and rationalization, please check out my Medium blog post: Enforcing Component Spacing in React & React Native.

Features

Stack

Stack is a vertical spacing component, think of a pile of plates at a buffet.

Usage

Stack takes size: number, debug?: boolean and debugOptions?: {color?: string, border?: boolean, borderColor?: string, opacity?: number}.

import * as React from "react";
import { View } from 'react-native';
import { Stack } from "react-native-spacing-system";
import { BuffetPlates } from "./BuffetPlates";
import { KitchenCounter } from "./KitchenCounter";

/*
    Creates a vertical space with size of 16 between
     <BuffetPlates /> and <KitchenCounter /> components.
*/
const QueueExample = () => {
  return (
    <View>
      <BuffetPlates />
      <Stack size={16} />
      <BuffetPlates />
      <Stack size={16} />
      <KitchenCounter />
    </View>
  );

Queue

Queue is a horizontal spacing component, think of people queueing for that new bubbletea joint.

Usage

Queue takes size: number, debug?: boolean and debugOptions?: {color?: string, border?: boolean, borderColor?: string, opacity?: number}.

import * as React from "react";
import { View } from "react-native";
import { Queue } from "react-native-spacing-system";
import { BubbleTeaJoint } from "./BubbleTeaJoint";
import { PatientPatron } from "./PatientPatron";

/*
    Creates a horizontal space with size of 16 between
    <BubbleTeaJoint /> and <PatientPatron /> components.
    Only works when flex direction is row.
*/
const StackExample = () => {
  return (
    <View style={{ flexDirection: "row" }}>
      <BubbleTeaJoint />
      <Queue size={16} />
      <PatientPatron />
      <Queue size={16} />
      <PatientPatron />
    </View>
  );
};

Inset

Inset is a boundary spacing component, think of adding frames around a picture (the child).

Usage

Inset takes children: ReactNode, debug?: boolean, debugOptions?: {color?: string}, flex?: number, and paddings: PaddingCombinations.

The allowed PaddingCombinations are as follows:

  • {all: number}
  • {horizontal: number, vertical: number}
  • {horizontal: number, bottom?: number, top?: number}
  • {vertical: number, left?: number, right?: number}
  • {left?: number, top?: number, right?:number, bottom: number}
import * as React from "react";
import { Inset } from "react-native-spacing-system";
import { PictureNeedingAFrame } from "./PictureNeedingAFrame";

/*
    Creates a padding of size 16 around 
    the <PictureNeedingAFrame /> component.
*/
const InsetExample = () => {
  return (
    <Inset all={16}>
      <PictureNeedingAFrame />
    </Inset>
  );
};

Factory Methods

Create your own spacing component with custom keys by passing in the space mapping object into the factory method provided.

  • stackFactory()
  • queueFactory()
  • insetFactory()
import { stackFactory } from "react-native-spacing-system";

const spacing = {
  tall: 8,
  grande: 12,
  venti: 16
};

const Stack = stackFactory(spacing);

<Stack size={16}/> // Error
<Stack size="venti"/> // Works

spacingFactory

If the spacing object is expected to be used in all Stack, Queue, and Inset, spacingFactory can be used to create the components in one function.

import { spacingFactory } from "react-native-spacing-system";

const spacing = {
  tall: 8,
  grande: 12,
  venti: 16,
};

const { Stack, Queue, Inset } = spacingFactory(spacing);

Flow

Depending on your version of flow, you may have to pass in the type of your space object.

/* @flow */
import { stackFactory } from "react-native-spacing-system";

type SpacingKey = 'tall' | 'grande' | 'venti'

type Spacing = {[key: SpacingKey]: number}

const spacing: Spacing = {
  tall: 8,
  grande: 12,
  venti: 16
};

const Stack = stackFactory<Spacing>(spacing);

<Stack size={16}/> // Error
<Stack size="venti"/> // Works

Debug Mode

Each component supports a debug mode where their spacing is highlighted.

Import the DebugContext and use the Provider to toggle debug mode on and off.

import * as React from "react";
import { DebugContext } from "react-native-spacing-system";
import ComponentWithSpacingSystemComponents from "./ComponentWithSpacingSystemComponents";

const SomeComponent = () => {
  return (
    <DebugContext.Provider value={{ debug: booleanValue }}>
      <ComponentWithSpacingSystemComponents />
    </DebugContext.Provider>
  );
};

You can also control debug mode of each type of spacing component as well as their border highlighting.

Expected Type (TypeScript)

type DebugContextProps = {
  debug: boolean;
  inset?: {
    debug?: boolean;
    color?: string;
  };
  queue?: {
    debug?: boolean;
    color?: string;
    border?: boolean;
    borderColor?: string;
    opacity?: number;
  };
  stack?: {
    debug?: boolean;
    color?: string;
    border?: boolean;
    borderColor?: string;
    opacity?: number;
  };
};

Expected Type (Flow)

type DebugContextProps = {|
  debug: boolean,
  inset?: {|
    debug?: boolean,
    color?: string,
  |},
  queue?: {|
    debug?: boolean,
    color?: string,
    border?: boolean,
    borderColor?: string,
    opacity?: number,
  |},
  stack?: {|
    debug?: boolean,
    color?: string,
    border?: boolean,
    borderColor?: string,
    opacity?: number,
  |},
|};

Download Details:

Author: hirokazutei

GitHub: https://github.com/hirokazutei/react-native-spacing-system

#react-native #react #mobile-apps

Standardizing how components are spaced in ReactNative
2.80 GEEK