mui-design-system
v0.0.35
Published
MUI-based design system with theme, form components, and utilities
Maintainers
Readme
mui-design-system
Design system based on MUI (Material UI) with custom theme, form components, table, and utilities.
Installation
npm install mui-design-systemPeer dependencies
Install in your project if not already present:
react&react-dom(^18.2.0)@mui/material(^6.1.9)@emotion/react,@emotion/styledstyled-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, greyTypeScript 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.tsuseFormContext— Access form context (theme, custom inputs) when insideFormProvider. File:src/lib/context/FormContext.tsx
Build (for maintainers)
From repo root:
npm run build:libOr from this directory (after npm install here):
npm run buildLicense
ISC
