@gnwebsoft/ui
v4.0.42
Published
A set of reusable wrappers for MUI v7
Downloads
2,430
Readme
@gnwebsoft/ui
A comprehensive TypeScript library providing reusable React components and wrappers for MUI v7. Built for modern React applications with full TypeScript support, form integration, and accessibility features.
Features
- 🎨 MUI v7 Integration - Built on top of Material-UI components
- 📝 Form Controls - Comprehensive react-hook-form wrappers
- 🔍 TypeScript First - Full type safety and IntelliSense support
- 🌳 Tree Shakeable - Modular exports for optimal bundle size
- ♿ Accessible - WCAG compliant components
- 🎯 Modern React - Hooks, memo, forwardRef patterns
- 📱 Responsive - Mobile-first design approach
Installation
npm install @gnwebsoft/ui
# or
yarn add @gnwebsoft/ui
# or
pnpm add @gnwebsoft/uiPeer Dependencies
This library requires the following peer dependencies:
npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled react-hook-form @hookform/resolvers zod{
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@hookform/resolvers": "^5.2.1",
"@mui/icons-material": "^7.3.1",
"@mui/lab": "^7.0.0-beta.16",
"@mui/material": "^7.3.1",
"@mui/x-data-grid": "^8.9.2",
"@mui/x-date-pickers": "^8.9.2",
"autosuggest-highlight": "^3.3.4",
"axios": "^1.11.0",
"dayjs": "^1.11.13",
"es-toolkit": "^1.39.8",
"lodash": "^4.17.21",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-hook-form": "^7.62.0",
"typescript": "^5.9.2",
"zod": "^4.0.15",
"zustand": "^5.0.2"
}Quick Start
import React from 'react';
import { SimpleButton, LabelText } from '@gnwebsoft/ui';
import { ThemeProvider, createTheme } from '@mui/material/styles';
const theme = createTheme();
function App() {
return (
<ThemeProvider theme={theme}>
<div>
<LabelText>Welcome to @gnwebsoft/ui</LabelText>
<SimpleButton
variant="contained"
color="primary"
onClick={() => alert('Hello World!')}
>
Click Me
</SimpleButton>
</div>
</ThemeProvider>
);
}
export default App;Module Imports
For optimal bundle size, import from specific modules:
// 🎯 Preferred - Tree-shakeable imports
import { SimpleButton } from '@gnwebsoft/ui/components';
import { TextFieldElement } from '@gnwebsoft/ui/wrappers';
import { useTransform } from '@gnwebsoft/ui/hooks';
import type { ApiResponse } from '@gnwebsoft/ui/types';
import { handleServerErrors } from '@gnwebsoft/ui/utils';
// 📦 Alternative - Root import (larger bundle)
import { SimpleButton, TextFieldElement } from '@gnwebsoft/ui';Available Modules
| Module | Description | Import Path |
| -------------- | ---------------------- | -------------------------- |
| Components | UI components | @gnwebsoft/ui/components |
| Wrappers | Form element wrappers | @gnwebsoft/ui/wrappers |
| Hooks | Custom React hooks | @gnwebsoft/ui/hooks |
| Types | TypeScript definitions | @gnwebsoft/ui/types |
| Utils | Utility functions | @gnwebsoft/ui/utils |
Components
Basic Components
SimpleButton
Enhanced MUI Button with loading states and conditional rendering.
import { SimpleButton } from '@gnwebsoft/ui/components';
<SimpleButton
loading={isSubmitting}
loadingText="Saving..."
show={hasPermission}
variant="contained"
onClick={handleSubmit}
>
Save Changes
</SimpleButton>;Features:
- Loading state with spinner
- Conditional rendering
- Automatic disabling during loading
- Custom loading text support
- Full TypeScript support
LabelText
Responsive label-value display component with grid layout and hover effects.
import { LabelText } from '@gnwebsoft/ui/components';
<LabelText
label="Full Name"
value="John Doe"
gridSize={{
labelSize: { xs: 12, sm: 4, md: 3 },
valueSize: { xs: 12, sm: 8, md: 9 },
}}
/>;Features:
- Responsive grid layout
- Hover effects with background color change
- Text overflow handling with ellipsis
- Tooltip on hover showing full value
- Customizable spacing and styling
AuthorizedView
Simple conditional rendering component based on a boolean show prop.
import { AuthorizedView } from '@gnwebsoft/ui/components';
<AuthorizedView show={user.hasAdminRole}>
<AdminPanel />
</AuthorizedView>;Features:
- Minimal overhead conditional rendering
- Returns empty fragment when hidden
- TypeScript support
ClearButton, CancelButton, FilterButton
Standardized button components for common form actions.
import { ClearButton, CancelButton, FilterButton } from '@gnwebsoft/ui/components';
<ClearButton
isSubmitting={isLoading}
handleClear={() => reset()}
storeKey="userFormData" // Optional localStorage cleanup
/>
<CancelButton
isSubmitting={isLoading}
handleCancel={() => navigate('/dashboard')}
/>
<FilterButton
isSubmitting={isFiltering}
show={hasFilters}
title="Apply Filters"
icon={<SearchIcon />}
/>Layout Components
FormWrapper
Card-based container for forms with header, title, and action buttons.
import { FormWrapper } from '@gnwebsoft/ui/components';
<FormWrapper
title="User Profile"
icon={<PersonIcon />}
actionButton={
<SimpleButton variant="outlined" size="small">
Reset
</SimpleButton>
}
>
<TextFieldElement name="firstName" label="First Name" />
<TextFieldElement name="lastName" label="Last Name" />
</FormWrapper>;Features:
- Card-based layout with header and content areas
- Divider between header and content
- Flexible action button placement
- Grid container for content with spacing
FilterWrapper, ListWrapper, SimpleToolbar
Specialized container components for different UI patterns.
import { FilterWrapper, ListWrapper, SimpleToolbar } from '@gnwebsoft/ui/components';
<FilterWrapper>
<TextField label="Search" />
<SelectElement name="category" options={categories} />
</FilterWrapper>
<ListWrapper>
<LabelText label="Name" value={user.name} />
<LabelText label="Email" value={user.email} />
</ListWrapper>
<SimpleToolbar>
<SimpleButton variant="contained">Add New</SimpleButton>
<SimpleButton variant="outlined">Export</SimpleButton>
</SimpleToolbar>Form Wrappers
All form wrappers integrate seamlessly with react-hook-form:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
TextFieldElement,
SelectElement,
DatePickerElement,
CheckboxElement,
} from '@gnwebsoft/ui/wrappers';
const schema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email('Invalid email'),
category: z.string(),
birthDate: z.date(),
subscribe: z.boolean(),
});
type FormData = z.infer<typeof schema>;
function ContactForm() {
const { control, handleSubmit } = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextFieldElement
control={control}
name="name"
label="Full Name"
required
/>
<TextFieldElement
control={control}
name="email"
label="Email"
type="email"
required
/>
<SelectElement
control={control}
name="category"
label="Category"
options={[
{ value: 'general', label: 'General Inquiry' },
{ value: 'support', label: 'Support' },
]}
/>
<DatePickerElement
control={control}
name="birthDate"
label="Birth Date"
/>
<CheckboxElement
control={control}
name="subscribe"
label="Subscribe to newsletter"
/>
<SimpleButton type="submit" variant="contained">
Submit
</SimpleButton>
</form>
);
}Available Form Wrappers
| Component | Description | Use Case | Features |
| ---------------------- | ------------------------------------- | --------------------------------- | ----------------------------------------------------- |
| TextFieldElement | Text input wrapper | Single-line text, email, password | Value transformation, grid layout, auto-validation |
| PasswordElement | Password input with visibility toggle | Secure password entry | Eye icon toggle, all TextFieldElement features |
| SelectElement | Single selection dropdown | Categories, statuses | Auto-select single option, custom label/value keys |
| SelectMultiElement | Multiple selection dropdown | Tags, permissions | Chip display, select all/none functionality |
| SelectCascadeElement | Dependent dropdown selections | Country → State → City | Hierarchical options, parent-child relationships |
| AsyncSelect | Async searchable dropdown | User search, API data | Debounced search, loading states, no options handling |
| AsyncMultiSelect | Async multiple selection | Multiple user selection | Async loading with multi-select capabilities |
| DatePickerElement | Date selection | Birth dates, deadlines | MUI date picker integration, keyboard input |
| TimePickerElement | Time selection | Appointments, schedules | MUI time picker integration, 12/24 hour format |
| CheckboxElement | Single checkbox | Agreements, preferences | Boolean value handling, label integration |
| CheckboxGroup | Multiple checkboxes | Multiple selections | Array value handling, group validation |
| RadioButtonGroup | Radio button group | Exclusive selections | Single selection from multiple options |
Hooks
useTransform
Transform values with memoization and change handling for form components.
import { useTransform } from '@gnwebsoft/ui/hooks';
const { value, onChange } = useTransform({
value: formValue,
onChange: field.onChange,
transform: {
input: value => value?.toString() || '',
output: event => parseInt(event.target.value) || null,
},
});Features:
- Memoized transformations for performance
- Input/output transformation support
- Change event handling
- TypeScript type safety
- Integration with form components
Common Use Cases:
- Number input formatting
- Date formatting
- Currency formatting
- Array to string conversion
Types
Comprehensive TypeScript interfaces for API integration and form handling:
import type {
ApiResponse,
OperationResponse,
ValidationErrors,
OptionItem,
PostModel,
ListResponse,
} from '@gnwebsoft/ui/types';
// API response structure
const response: ApiResponse<User[]> = {
status: 200,
data: users,
traceId: 'abc123',
};
// Form options
const options: OptionItem[] = [
{ Label: 'Option 1', Value: '1' },
{ Label: 'Option 2', Value: '2' },
];
// Paginated list response
const listResponse: ListResponse<User> = {
Data: [
/* users */
],
Total: 150,
};
// Filter/search request
const filterRequest: PostModel<UserFilter> = {
filterModel: { name: 'John' },
pageOffset: 0,
pageSize: 20,
sortField: 'name',
sortOrder: 'asc',
};Available Types:
ApiResponse<T>- Standard API response structureValidationErrors- Form validation errorsOptionItem/OptionItem2- Select optionsPostModel<T>- Filter/pagination requestsListResponse<T>- Paginated responsesAsyncSelectPayload- Async select data
Utilities
API Utilities
import { api, handleServerErrors } from '@gnwebsoft/ui/utils';
// API calls with automatic authentication
const users = await api.get<User[]>('/users');
const newUser = await api.post<User>('/users', userData);
const filteredUsers = await api.filter<User, UserFilter>(
'/users/search',
filterModel
);
// File upload
const uploadResult = await api.upload<UploadResponse>('/upload', formData);
// Form error handling
try {
await api.post('/submit', formData);
} catch (error) {
handleServerErrors({
errors: error.response.data.errors,
setError,
});
}Data Transformation
import {
flattenObjectKeys,
readValueAsDate,
propertyExists,
removeLeadingTrailingSlashes,
getTimezone,
} from '@gnwebsoft/ui/utils';
// Flatten nested objects
const flatData = flattenObjectKeys({ user: { name: 'John', age: 30 } });
// Result: { 'user.name': 'John', 'user.age': 30, 'user': {...} }
// Date conversion
const date = readValueAsDate('2023-12-25');
// Result: Date object or null
// Property checking
if (propertyExists(obj, 'user.address.street')) {
console.log(obj.user.address.street);
}
// URL cleaning
const cleanPath = removeLeadingTrailingSlashes('/api/users/');
// Result: 'api/users'
// Timezone info
const timezone = getTimezone();
// Result: 'America/New_York' or current timezoneAvailable Utilities:
api/api2- HTTP clients with authenticationhandleServerErrors- Form error mappingflattenObjectKeys- Nested object flatteningreadValueAsDate- Safe date conversionpropertyExists- Type-safe property checkingremoveLeadingTrailingSlashes- URL path cleaninggetTimezone- Timezone informationschemaTools- Zod schema utilities
Styling and Theming
Components inherit MUI theme configuration:
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
typography: {
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
},
});
function App() {
return (
<ThemeProvider theme={theme}>{/* Your app components */}</ThemeProvider>
);
}Advanced Usage
Async Select with Search
import { AsyncSelect } from '@gnwebsoft/ui/wrappers';
<AsyncSelect
control={control}
name="assignee"
label="Assign to User"
loadOptions={async searchValue => {
const response = await api.get(`/users/search?q=${searchValue}`);
return response.data.map(user => ({
value: user.id,
label: `${user.name} (${user.email})`,
}));
}}
placeholder="Search users..."
noOptionsText="No users found"
/>;Cascade Selects
import { SelectCascadeElement } from '@gnwebsoft/ui/wrappers';
<SelectCascadeElement
control={control}
name="location"
label="Location"
options={[
{
value: 'us',
label: 'United States',
children: [
{ value: 'ny', label: 'New York' },
{ value: 'ca', label: 'California' },
],
},
]}
/>;Testing
Components are built with testing in mind:
import { render, screen } from '@testing-library/react';
import { SimpleButton } from '@gnwebsoft/ui/components';
test('renders button with loading state', () => {
render(
<SimpleButton loading loadingText="Loading...">
Submit
</SimpleButton>
);
expect(screen.getByText('Loading...')).toBeInTheDocument();
expect(screen.getByRole('button')).toBeDisabled();
});Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation
Comprehensive documentation is available for all components and utilities:
📚 Complete Documentation
- Component Documentation - Detailed guide for all components
- Components - UI Components documentation
- Form Wrappers - Form wrapper components documentation
- Hooks - Custom React hooks documentation
- Utilities - Utility functions documentation
- Types - TypeScript types documentation
🎯 Quick References
- Getting Started Guide - Setup and basic usage
- Forms Guide - Form handling patterns
- API Documentation - Generated API docs
📖 Examples
Each component includes:
- ✅ Basic usage examples
- ✅ Advanced configuration options
- ✅ TypeScript integration examples
- ✅ Testing patterns
- ✅ Accessibility guidelines
- ✅ Performance considerations
Development
# Install dependencies
pnpm install
# Start development mode with hot reload
pnpm dev
# Run tests
pnpm test
# Build library
pnpm build
# Generate TypeScript documentation
pnpm docs:generate
# Validate package exports
pnpm run check-exportsDevelopment Workflow
The package supports instant development with hot module reloading:
# Start both UI package and sample app
pnpm dev
# Or start individually
pnpm run dev:ui # UI package in watch mode
pnpm run dev:web # Sample web appBrowser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
License
MIT © GNWebsoft Private Limited
Changelog
See CHANGELOG.md for release history.
Made with ❤️ by GNWebsoft Team
