Skip to main content
1.0.0 Dark Light System

React

Lynk offers a React version of every component to provide an idiomatic experience for React users. You can easily toggle between HTML and React examples throughout the documentation.

Installation

To add Lynk to your React app, install the package from npm.

npm install @uplynk/lynk-design

Next, include a theme and set the base path for icons and other assets. In this example, we’ll import the light theme and use the CDN as a base path.

// App.jsx
import '@uplynk/lynk-design/dist/themes/light.css';
import { setBasePath } from '@uplynk/lynk-design/dist/utilities/base-path';

setBasePath('https://cdn.jsdelivr.net/npm/@uplynk/lynk-design@1.0.0/cdn/');
If you’d rather not use the CDN for assets, you can create a [build task](https://webpack.js.org/plugins/copy-webpack-plugin/) that copies `node_modules/@uplynk/lynk-design/dist/assets` into your app’s `public` directory. Then you can point the base path to that folder instead.

Now you can start using components!

Preact

Preact users facing type errors using components may benefit from setting “paths” in their tsconfig.json so that react types will instead resolve to preact/compat as described in Preact’s typescript documentation.

Usage

Importing Components

Every Lynk component is available to import as a React component. Note that we’re importing the <LynkButton> React component instead of the <lynk-button> custom element in the example below.

import LynkButton from '@uplynk/lynk-design/dist/react/button';

const MyComponent = () => <LynkButton variant="primary">Click me</LynkButton>;

export default MyComponent;

Notes about tree shaking

Previously, it was recommended to import from a single entrypoint like so:

import { LynkButton } from '@uplynk/lynk-design/dist/react';

However, tree-shaking extra Lynk components proved to be a challenge. As a result, we now recommend cherry-picking components you want to use, rather than importing from a single entrypoint.

- import { LynkButton } from '@uplynk/lynk-design/dist/react';
+ import LynkButton from '@uplynk/lynk-design/dist/react/button';

You can find a copy + paste import for each component in the “importing” section of its documentation.

Event Handling

Many Lynk components emit custom events. For example, the input component emits the lynk-input event when it receives input. In React, you can listen for the event using onOnInput.

Here’s how you can bind the input’s value to a state variable.

import { useState } from 'react';
import LynkInput from '@uplynk/lynk-design/dist/react/input';

function MyComponent() {
  const [value, setValue] = useState('');

  return <LynkInput value={value} onLynkInput={event => setValue(event.target.value)} />;
}

export default MyComponent;

If you’re using TypeScript, it’s important to note that event.target will be a reference to the underlying custom element. You can use (event.target as any).value as a quick fix, or you can strongly type the event target as shown below.

import { useState } from 'react';
import LynkInput from '@uplynk/lynk-design/dist/react/input';
import type LynkInputElement from '@uplynk/lynk-design/dist/components/input/input';

function MyComponent() {
  const [value, setValue] = useState('');

  return <LynkInput value={value} onLynkInput={event => setValue((event.target as LynkInputElement).value)} />;
}

export default MyComponent;

You can also import the event type for use in your callbacks, shown below.

import { useCallback, useState } from 'react';
import LynkInput, { type LynkInputEvent } from '@uplynk/lynk-design/dist/react/input';
import type LynkInputElement from '@uplynk/lynk-design/dist/components/input/input';

function MyComponent() {
  const [value, setValue] = useState('');
  const onInput = useCallback((event: LynkInputEvent) => {
    setValue(event.detail);
  }, []);

  return <LynkInput value={value} onLynkInput={event => setValue((event.target as LynkInputElement).value)} />;
}

export default MyComponent;

Testing with Jest

Testing with web components can be challenging if your test environment runs in a Node environment (i.e. it doesn’t run in a real browser). Fortunately, Jest has made a number of strides to support web components and provide additional browser APIs. However, it’s still not a complete replication of a browser environment.

Here are some tips that will help smooth things over if you’re having trouble with Jest + Lynk.

If you’re looking for a fast, modern testing alternative, consider [Web Test Runner](https://modern-web.dev/docs/test-runner/overview/).

Upgrade Jest

Jest underwent a major revamp and received support for web components in version 26.5.0 when it introduced JSDOM 16.2.0. This release also included a number of mocks for built-in browser functions such as MutationObserver, document.createRange, and others.

If you’re using Create React App, you can update react-scripts which will also update Jest.

npm install react-scripts@latest

Mock Missing APIs

Some components use window.matchMedia, but this function isn’t supported by JSDOM so you’ll need to mock it yourself.

In src/setupTests.js, add the following.

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // deprecated
    removeListener: jest.fn(), // deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn()
  }))
});

For more details, refer to Jest’s manual mocking documentation.

Transform ES Modules

ES Modules are a well-supported browser standard. This is how Lynk is distributed, but most React apps expect CommonJS. As a result, you’ll probably run into the following error.

Error: Unable to import outside of a module

To fix this, add the following to your package.json which tells the transpiler to process Lynk modules.

{
  "jest": {
    "transformIgnorePatterns": ["node_modules/(?!(@lynk))"]
  }
}

These instructions are for apps created via Create React App. If you’re using Jest directly, you can add transformIgnorePatterns directly into jest.config.js.

For more details, refer to Jest’s transformIgnorePatterns customization documentation.