Skip to content

michaelschwobe/react-icon-layout

Repository files navigation

react-icon-layout

Everything you need to manage icon-to-text layouts.

NPM version License NPM status Publish CI CodeQL codecov

Jump to: Overview | Installation | Usage | Features | API | License

Overview

As a developer, you’d like to:

  • 👯 Create icon-to-text pairs (or other content types) multiple times, and possibly nest them.
  • ⚡️ Dynamically or statically control how some or all icon-to-text pairs display.
  • ✍️ Use custom or default styles and variables.

So that you can:

  • 🤝 Ensure layout relationships are consistent and manageable.
  • ✨ Render whatever, wherever — form fields, navigation, pagination, etc.
  • 🛠 Allow some or all users to control their own icon-to-text display settings.

For example, you’ve likely seen this use case before within the macOS Finder:

macOS Finder with it’s header right-click menu visible

Installation

npm i -S react-icon-layout

or

yarn add react-icon-layout

Usage

  • ⬆️ View the “Finder” example (shown above) on CodeSandbox
  • 📚 View the Storybook example on GitHub or clone locally then run the dev script.
  • ⬇️ View the “Basic” example (shown below) on CodeSandbox
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
  IconLayout,
  IconLayoutProvider,
  iconLayoutOptions,
  useIconLayoutDispatch,
  useIconLayoutState,
} from 'react-icon-layout';
import 'react-icon-layout/styles.css';

import { ReactComponent as ArrowRightIcon } from './arrow-right.svg';

function NextButton() {
  const iconLayoutState = useIconLayoutState();
  return (
    <button type="button">
      <IconLayout
        icon={<ArrowRightIcon />}
        text="Next"
        placeIcon="right"
        placeSelf="right"
        variant={iconLayoutState}
      />
    </button>
  );
}

function IconLayoutSelector() {
  const iconLayoutState = useIconLayoutState();
  const iconLayoutDispatch = useIconLayoutDispatch();
  return (
    <label htmlFor="IconLayoutSelector">
      Select icon layout:{' '}
      <select
        name="IconLayoutSelector"
        id="IconLayoutSelector"
        value={iconLayoutState}
        onChange={(event) => iconLayoutDispatch({ type: event.target.value })}
      >
        {iconLayoutOptions.map(({ id, name }) => (
          <option key={id} value={id}>
            {name}
          </option>
        ))}
      </select>
    </label>
  );
}

function App() {
  return (
    <IconLayoutProvider>
      <NextButton />
      <IconLayoutSelector />
    </IconLayoutProvider>
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

Features

import {
  /** Default `placeIcon` prop value */
  defaultPlaceIcon,
  /** Default `placeSelf` prop value */
  defaultPlaceSelf,
  /** Default `variant` prop value / context state */
  defaultVariant,
  /** List of `placeIcon` and `placeSelf` prop values */
  iconLayoutPlacements,
  /** List of `variant` prop values / context states */
  iconLayoutVariants,
  /** List for iterating button/input/option/etc elements */
  iconLayoutOptions,
  /** Display component */
  IconLayout,
  /** Context component for `state` */
  IconLayoutStateContext,
  /** Context component for `dispatch` */
  IconLayoutDispatchContext,
  /** Context provider component */
  IconLayoutProvider,
  /** Hook for accessing context `state` */
  useIconLayoutState,
  /** Hook for accessing context `dispatch` */
  useIconLayoutDispatch,
} from 'react-icon-layout';

/* Types for when using TypeScript */
import type {
  IconLayoutAction,
  IconLayoutDispatch,
  IconLayoutOptions,
  IconLayoutPlacement,
  IconLayoutProps,
  IconLayoutProviderProps,
  IconLayoutState,
} from 'react-icon-layout';

/* Styles for <IconLayout> */
import 'react-icon-layout/styles.css';

API

<IconLayout>

Display component, does NOT consume context.

/** Sets the `class` attribute. **Default:** `undefined` */
className?: string | undefined;
/** Styles the “icon” placement within the display component. **Default:** `"left"` */
placeIcon?: IconLayoutPlacement | undefined;
/** Styles the component placement within a larger parent. **Default:** `undefined` */
placeSelf?: IconLayoutPlacement | undefined;
/** Styles the content visibility. **Default:** `"iconAndText"` */
variant?: IconLayoutState | undefined;
/** Sets the “icon” content, similar to a `children` prop. **Required.** */
icon: React.ReactNode;
/** Sets the “text” content, similar to a `children` prop. **Required.** */
text: React.ReactNode;

<IconLayoutProvider>

Provider component.

/** Sets the content. **Required.** */
children: React.ReactNode;
/** Sets the initial state. **Default:** `iconAndText` */
value?: IconLayoutState | undefined;

useIconLayoutState()

Hook for accessing state, requires <IconLayoutProvider>.

useIconLayoutDispatch()

Hook for accessing dispatch, requires <IconLayoutProvider>.

License

MIT