npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mui-design-system

v0.0.35

Published

MUI-based design system with theme, form components, and utilities

Readme

mui-design-system

Design system based on MUI (Material UI) with custom theme, form components, table, and utilities.


Installation

npm install mui-design-system

Peer dependencies

Install in your project if not already present:

  • react & react-dom (^18.2.0)
  • @mui/material (^6.1.9)
  • @emotion/react, @emotion/styled
  • styled-components (^6.1.8)
  • stylis-plugin-rtl (for RTL)
  • For form: react-hook-form (^7.51.2)
  • For table: @tanstack/react-table (^8.17.3)

Quick start

import { ReactCacheProvider, themeOptions, Form, colors } from 'mui-design-system';
import { ThemeProvider, createTheme } from '@mui/material/styles';

const theme = createTheme(themeOptions('light', false)); // mode, isRtl

<ThemeProvider theme={theme}>
  <ReactCacheProvider isRtl={false}>
    <App />
  </ReactCacheProvider>
</ThemeProvider>

// Colors from subpath
import { colors } from 'mui-design-system/colors/index';

Exports overview

| Category | Exports | |----------|---------| | Theme & providers | themeOptions, ReactCacheProvider, NextCacheProvider | | Form | Form, FormProvider, and all UF* field components + CheckboxList | | Table | CustomTable, useTable | | OTP | OTPInput | | Methods | debounce, result, deepMerge | | Colors | colors (from mui-design-system/colors/index) |


1. Theme & providers

themeOptions(mode, isRtl)

Builds MUI ThemeOptions (palette, typography, components, direction).

| Parameter | Type | Description | |-----------|------|-------------| | mode | 'light' \| 'dark' | Palette mode | | isRtl | boolean | RTL/LTR direction |

Example:

import { createTheme } from '@mui/material/styles';
import { themeOptions } from 'mui-design-system';

const theme = createTheme(themeOptions('light', false));

ReactCacheProvider

Emotion cache provider for React apps (non-Next). Use for correct RTL/LTR styling with the theme.

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | App content | | isRtl | boolean | — | Use RTL cache (with stylis-plugin-rtl) |

Example:

import { ReactCacheProvider } from 'mui-design-system';

<ReactCacheProvider isRtl={false}>
  <App />
</ReactCacheProvider>

NextCacheProvider

Provider for Next.js (with @mui/material-nextjs). In the current version it mainly wraps children; use Next’s config for RTL if needed.

Props: children, isRtl

Example:

import { NextCacheProvider } from 'mui-design-system';

<NextCacheProvider isRtl={false}>
  <App />
</NextCacheProvider>

2. Form

Form is built on react-hook-form and a schema array that describes each field.

Form

Renders form fields from a schema and a react-hook-form instance.

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | schema | TFormSchema | — | Array of field configs | | form | UseFormReturn<any> | — | Return value of useForm() | | gridContainerProps | GridProps | — | Grid container props | | gridItemProps | GridProps | — | Props for each grid item | | itemProps | any | — | Shared item props | | labelsProps | Partial<TypographyProps> | — | Label typography/style | | hideRequiredStar | boolean | false | Hide required asterisk | | inputLabelMode | 'static' \| 'relative' | 'static' | Label placement | | inputVariants | 'outlined' \| 'filled' \| 'standard' | 'outlined' | Text field variant | | withoutHelperText | boolean | — | Hide helper text | | disabled | boolean | — | Disable entire form |

Schema item shape (summary): name, label, type, rules (react-hook-form), defaultValue, placeholder, options (for select/radio/etc.), props / itemProps per type.

Schema field types: 'text', 'email', 'password', 'number', 'tel', 'text-area', 'select', 'multi-select', 'auto-complete', 'radio', 'checkbox', 'multi-checkbox', 'switch', 'date-picker', 'time', 'currency', 'uploader'.

Example:

import { useForm } from 'react-hook-form';
import { Form } from 'mui-design-system';

const schema = [
  { name: 'email', label: 'Email', type: 'email', rules: { required: true } },
  { name: 'age', label: 'Age', type: 'number' },
  {
    name: 'country',
    label: 'Country',
    type: 'select',
    options: [
      { value: 'us', label: 'United States' },
      { value: 'uk', label: 'United Kingdom' },
    ],
  },
];

const MyForm = () => {
  const form = useForm({ defaultValues: { email: '', age: 0, country: '' } });
  return (
    <form onSubmit={form.handleSubmit((data) => console.log(data))}>
      <Form schema={schema} form={form} />
      <button type="submit">Submit</button>
    </form>
  );
};

FormProvider

Provides form theme and optional custom inputs. Wrap your form when you need default styling or custom field types.

Props: children, theme? (TFormTheme), customInputs?

Example:

import { FormProvider, Form } from 'mui-design-system';

<FormProvider theme={{ text: { /* default TextField props */ } }}>
  <Form schema={schema} form={form} />
</FormProvider>

Form field components (UF*)

These are used internally by Form but can also be used standalone with react-hook-form’s register / control. All are wrapped with an error boundary when exported.

UFTextField

Text input for text, email, password, number, tel.

Example:

import { useForm } from 'react-hook-form';
import { UFTextField } from 'mui-design-system';

const MyField = () => {
  const form = useForm({ defaultValues: { username: '' } });
  return (
    <UFTextField
      form={form}
      name="username"
      label="Username"
      type="text"
      placeholder="Enter username"
    />
  );
};

UFTextArea

Multiline text field.

Example:

import { Form, useForm } from 'mui-design-system';

const schema = [
  { name: 'bio', label: 'Bio', type: 'text-area', placeholder: 'Tell us about yourself' },
];
const form = useForm({ defaultValues: { bio: '' } });
<Form schema={schema} form={form} />;

UFSelect

Single select dropdown.

Example:

const schema = [
  {
    name: 'city',
    label: 'City',
    type: 'select',
    options: [
      { value: 'ny', label: 'New York' },
      { value: 'la', label: 'Los Angeles' },
    ],
  },
];
<Form schema={schema} form={form} />;

UFMultiSelect

Multi-select dropdown.

Example:

const schema = [
  {
    name: 'tags',
    label: 'Tags',
    type: 'multi-select',
    options: [
      { value: 'a', label: 'Tag A' },
      { value: 'b', label: 'Tag B' },
    ],
  },
];
<Form schema={schema} form={form} />;

UFAutoComplete

Autocomplete with search, options, and optional async loading.

Example:

const schema = [
  {
    name: 'country',
    label: 'Country',
    type: 'auto-complete',
    options: countries,
    onSearch: (value) => fetchCountries(value),
    isLoading: loading,
  },
];
<Form schema={schema} form={form} />;

UFCheckbox

Single checkbox.

Example:

const schema = [
  { name: 'agree', label: 'I agree to terms', type: 'checkbox' },
];
<Form schema={schema} form={form} />;

UFMultiCheckbox / CheckboxList

List of checkboxes; used for multi-checkbox fields.

Example:

const schema = [
  {
    name: 'interests',
    label: 'Interests',
    type: 'multi-checkbox',
    options: [
      { value: 'sports', label: 'Sports' },
      { value: 'music', label: 'Music' },
    ],
  },
];
<Form schema={schema} form={form} />;

UFRadio

Radio group.

Example:

const schema = [
  {
    name: 'gender',
    label: 'Gender',
    type: 'radio',
    options: [
      { value: 'm', label: 'Male' },
      { value: 'f', label: 'Female' },
    ],
  },
];
<Form schema={schema} form={form} />;

UFSwitch

Toggle switch.

Example:

const schema = [
  { name: 'notifications', label: 'Enable notifications', type: 'switch' },
];
<Form schema={schema} form={form} />;

UFDatePicker

Date picker field.

Example:

const schema = [
  { name: 'birthDate', label: 'Birth date', type: 'date-picker' },
];
<Form schema={schema} form={form} />;

UFTime

Time input (hours/minutes).

Example:

const schema = [
  { name: 'appointmentTime', label: 'Time', type: 'time' },
];
<Form schema={schema} form={form} />;

UFCurrency

Numeric/currency input with formatting.

Example:

const schema = [
  { name: 'price', label: 'Price', type: 'currency', placeholder: '0.00' },
];
<Form schema={schema} form={form} />;

UFUploader

File upload with optional multiple files and delete handler.

Example:

const schema = [
  {
    name: 'attachments',
    label: 'Attachments',
    type: 'uploader',
    multiple: true,
    onDelete: (index) => removeFile(index),
  },
];
<Form schema={schema} form={form} />;

3. Table

useTable

Hook that builds a @tanstack/react-table instance and returns table, pagination, and optional selection/expand helpers for CustomTable.

Parameters (IUseTableProps): columns, data, pageSize?, multiSelect?, onSelectRow?, getRowId?, renderSubComponent?, getRowCanExpand?, state?, and other react-table options.

Returns: { table, pagination, selectedRows, renderSubComponent }.

Example:

import { useTable, CustomTable } from 'mui-design-system';

const columns = [
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'age', header: 'Age' },
];
const data = [
  { id: '1', name: 'Alice', age: 28 },
  { id: '2', name: 'Bob', age: 32 },
];

const MyTable = () => {
  const { table, pagination, renderSubComponent } = useTable({
    columns,
    data,
    pageSize: 10,
  });
  return (
    <CustomTable
      table={table}
      pagination={pagination}
      renderSubComponent={renderSubComponent}
    />
  );
};

CustomTable

Table UI with header, body, loading skeleton, pagination, optional row selection (radio/checkbox) and expandable rows.

Props (ICustomTable): id?, table, pagination?, variant? ('zebra' | 'linear'), isLoading?, wrapperStackProps?, footerProps?, onClickRow?, renderSubComponent?, withRadio?, withSelect?, withIndex?, rowStyle?, cellsStyle?, headerStyle?, headerTypoProps?, checkboxProps?, radioProps?, emptyListComponent?, rowBorderRadius?, borderRadius?.

Example:

import { useTable, CustomTable } from 'mui-design-system';

const columns = [
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'email', header: 'Email' },
];
const data = [
  { id: '1', name: 'Alice', email: '[email protected]' },
  { id: '2', name: 'Bob', email: '[email protected]' },
];

const DataTable = () => {
  const { table, pagination } = useTable({ columns, data, pageSize: 5 });
  return (
    <CustomTable
      id="users-table"
      table={table}
      pagination={pagination}
      variant="zebra"
      emptyListComponent="No users found"
    />
  );
};

4. OTP Input

OTPInput

Multi-digit OTP input (one box per digit).

Props: valueLength, value?, onChange, size?, gap?, inputStyle?, activeInputStyle?, onFinish?, onBack?, containerProp?, readonly?, disabled?, isError?.

Example:

import { useState } from 'react';
import { OTPInput } from 'mui-design-system';

const VerifyCode = () => {
  const [otp, setOtp] = useState('');
  return (
    <OTPInput
      valueLength={6}
      value={otp}
      onChange={setOtp}
      onFinish={(val) => console.log('OTP completed:', val)}
      gap={2}
    />
  );
};

5. Methods

debounce(func, wait, immediate?)

Debounces a function (e.g. for search input).

Example:

import { debounce } from 'mui-design-system';

const handleSearch = debounce((query: string) => {
  fetchSuggestions(query);
}, 300);

// In JSX: <Input onChange={(e) => handleSearch(e.target.value)} />

result(object, key, defaultValue?)

Reads a value from an object with optional default or lazy default (function).

Example:

import { result } from 'mui-design-system';

const userName = result(user, 'name', 'Guest');
const value = result(config, 'key', () => computeExpensiveDefault());

deepMerge<T>(...objects)

Deep-merges objects. Arrays and non-object values are overwritten.

Example:

import { deepMerge } from 'mui-design-system';

const merged = deepMerge(
  { a: 1, b: { x: 1 } },
  { b: { y: 2 }, c: 3 }
);
// { a: 1, b: { x: 1, y: 2 }, c: 3 }

6. Colors

Color palettes are available from the colors subpath.

Example:

import { colors } from 'mui-design-system/colors/index';

// Each color has keys 50–900
colors.blue[500];  // "#1e88e5"
colors.grey[700];  // "#535353"

// Available: yellow, blue, green, orange, red, purple, grey

TypeScript types: TColors, ColorScale ("50" | "100" | ... | "900"), IColor.


Export tree (summary)

mui-design-system
├── themeOptions
├── ReactCacheProvider
├── NextCacheProvider
├── Form
├── FormProvider
├── UFTextField, UFTextArea, UFSelect, UFMultiSelect, UFAutoComplete
├── UFCheckbox, UFMultiCheckbox, CheckboxList
├── UFRadio, UFSwitch
├── UFDatePicker, UFTime, UFCurrency, UFUploader
├── CustomTable
├── useTable
├── OTPInput
├── debounce, result, deepMerge
└── (colors from mui-design-system/colors/index)

Not exported from main entry

These exist in the library but are not re-exported from the main package. You can add them to index.ts if needed:

  • useEffectOnce — Hook that runs an effect once (mount) with cleanup. File: src/lib/hooks/useEffectOnce.ts
  • useFormContext — Access form context (theme, custom inputs) when inside FormProvider. File: src/lib/context/FormContext.tsx

Build (for maintainers)

From repo root:

npm run build:lib

Or from this directory (after npm install here):

npm run build

License

ISC