npm package: @shipengine/alchemy
Description: `shipengine/alchemy` is a toolkit for building re-usable, fully-featured, data-connected and cross-compatible React components (“Elements”)[^1] for use in applications that utilize the [ShipEngine API](https://shipengine.github.io/shipengine-openapi/).
Latest version: 6.0.95

# Alchemy

`shipengine/alchemy` is a toolkit for building re-usable, fully-featured, data-connected and cross-compatible React components (“Elements”)[^1] for use in applications that utilize the [ShipEngine API](https://shipengine.github.io/shipengine-openapi/).

The library makes opinionated choices about API access, state management, language translations[^2] and UI foundations.

## Features:

- Available to all descendants of the `AlchemyProvider`:

  - A batteries-included client for accessing ShipeEngine API endpoints with a shared cache and lifecycle management via hooks from [@shipengine/react-api](https://www.npmjs.com/package/@shipengine/react-api).
  - A [ShipEngine Giger](https://www.shipengine.com/docs/elements/elements-guide/#theming) theme, which can be re-defined at instantiation via the `themeConfig` prop and accessible on the Emotion `css` callback prop, and icons via Giger's `Icon` component.

- Available to components created via the `alchemy.createElement` factory:
  - Fully isolated styles. CSS styles are reset at the boundary of each Element, ensuring that they are self-contained and unaffected by the host application’s styles.
  - Fully isolated language translations. A non-global instance of `i18next` is provided for each Element. Individual translations can be overriden at the Element's point-of-use via the optional `resources` prop.
  - A configurable `ErrorBoundary`.

## Basic Usage

[!IMPORTANT]
In addition to `@shipengine/alchemy`, you _must_ also add `@shipengine/react-api` and `@shipengine/js-api` to your project's dependencies.

- A single `AlchemyProvider` should be rendered near the top of the application's component hiearchy
- The `createElement` factory is used to create stylistically isolated components that will utilize the AlchemyProvider's API client and theme.

```tsx
import alchemy, { AlchemyProvider, useListShipments } from "@shipengine/alchemy";
import { themeConfig } from "../themeConfig";

type MyComponentProps = {
  myProp: string;
};

const MyComponent = ({ myProp }: MyComponentProps) => {
  const { data, isLoading, error } = useListShipments();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>{error.message}</div>;

  console.log(data);
  // > an object matching the response schema of https://shipengine.github.io/shipengine-openapi/#operation/list_shipments

  return (
    <div
      css={(theme) => ({
        /* ... */
      })}
    >
      Retrieved {data.shipments.length} shipments
    </div>
  );
};

// Your own component that the ErrorBoundary will display when an error occurs
const MyErrorFallback = ({ error }) => <div>Whoops...</div>;

const MyElement = alchemy.createElement(
  MyComponent,
  MyErrorFallback,
  // optional configuration object
  {
    // applied to the container
    css: (theme) => ({
      // ...
    }),

    // i18next translations
    resources: {
      // ...
    },
  }
);

const MyApp = () => {
  return (
    <AlchemyProvider getToken={() => "your-platform-token"} themeConfig={themeConfig}>
      <section>
        Your pre-existing application
        <div>
          Locate the Element wherever you like
          <MyElement
            myProp="just a regular prop"
            // optional translations override prop added by the factory
            resources={{}}
          />
        </div>
      </section>
    </AlchemyProvider>
  );
};
```