@gnwebsoft/ui 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +688 -0
  2. package/dist/chunk-4H3AFH7A.js +505 -0
  3. package/dist/chunk-DE62KYFK.js +122 -0
  4. package/dist/chunk-DEPJRTVT.js +1 -0
  5. package/dist/chunk-EBRUE2WR.cjs +493 -0
  6. package/dist/chunk-FD57PCAC.cjs +1 -0
  7. package/dist/chunk-H3GQLELL.js +2025 -0
  8. package/dist/chunk-MVPLBJRK.cjs +1 -0
  9. package/dist/chunk-OJF67RNM.js +1 -0
  10. package/dist/chunk-OT7COE7R.cjs +2025 -0
  11. package/dist/chunk-R2YK4LTT.cjs +122 -0
  12. package/dist/chunk-U6SDYCWF.js +493 -0
  13. package/dist/chunk-ZC7FGYL2.cjs +505 -0
  14. package/dist/components/index.cjs +25 -0
  15. package/dist/components/index.d.cts +752 -0
  16. package/dist/components/index.d.ts +664 -15
  17. package/dist/components/index.js +25 -24
  18. package/dist/enhanced-z-I7EHVS.d.cts +134 -0
  19. package/dist/enhanced-z-I7EHVS.d.ts +134 -0
  20. package/dist/hooks/index.cjs +12 -0
  21. package/dist/hooks/index.d.cts +95 -0
  22. package/dist/hooks/index.d.ts +82 -4
  23. package/dist/hooks/index.js +12 -7
  24. package/dist/index.cjs +127 -0
  25. package/dist/index.d.cts +14 -0
  26. package/dist/index.d.ts +4 -6
  27. package/dist/index.js +127 -54
  28. package/dist/types/index.cjs +2 -0
  29. package/dist/types/index.d.cts +241 -0
  30. package/dist/types/index.d.ts +205 -20
  31. package/dist/types/index.js +2 -1
  32. package/dist/utils/index.cjs +45 -0
  33. package/dist/utils/index.d.cts +366 -0
  34. package/dist/utils/index.d.ts +317 -9
  35. package/dist/utils/index.js +45 -22
  36. package/dist/wrappers/index.cjs +54 -0
  37. package/dist/wrappers/index.d.cts +1684 -0
  38. package/dist/wrappers/index.d.ts +1601 -118
  39. package/dist/wrappers/index.js +54 -8
  40. package/package.json +139 -88
  41. package/dist/AsyncSelectPayload-Cz4bgak0.d.mts +0 -10
  42. package/dist/AsyncSelectPayload-Cz4bgak0.d.ts +0 -10
  43. package/dist/chunk-2JFL7TS5.mjs +0 -0
  44. package/dist/chunk-6BGQA4BQ.js +0 -1
  45. package/dist/chunk-6JZ35VQJ.js +0 -19
  46. package/dist/chunk-7M2VOCYN.js +0 -1
  47. package/dist/chunk-BWQUYXUW.mjs +0 -1634
  48. package/dist/chunk-D3J7MWAU.js +0 -1634
  49. package/dist/chunk-EVPUCTZA.mjs +0 -0
  50. package/dist/chunk-FSU3H777.mjs +0 -473
  51. package/dist/chunk-GFSTK7KN.mjs +0 -19
  52. package/dist/chunk-I7EIUZKK.js +0 -332
  53. package/dist/chunk-JKUOV3MN.js +0 -473
  54. package/dist/chunk-RQS44YC7.mjs +0 -332
  55. package/dist/components/index.d.mts +0 -103
  56. package/dist/components/index.mjs +0 -24
  57. package/dist/hooks/index.d.mts +0 -17
  58. package/dist/hooks/index.mjs +0 -7
  59. package/dist/index.d.mts +0 -16
  60. package/dist/index.mjs +0 -54
  61. package/dist/types/index.d.mts +0 -56
  62. package/dist/types/index.mjs +0 -1
  63. package/dist/utils/index.d.mts +0 -58
  64. package/dist/utils/index.mjs +0 -22
  65. package/dist/wrappers/index.d.mts +0 -201
  66. package/dist/wrappers/index.mjs +0 -8
package/README.md ADDED
@@ -0,0 +1,688 @@
1
+ # @gnwebsoft/ui
2
+
3
+ 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.
4
+
5
+ [![npm version](https://badge.fury.io/js/%40gnwebsoft%2Fui.svg)](https://badge.fury.io/js/%40gnwebsoft%2Fui)
6
+ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
7
+ [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/)
8
+
9
+ ## Features
10
+
11
+ - 🎨 **MUI v7 Integration** - Built on top of Material-UI components
12
+ - 📝 **Form Controls** - Comprehensive react-hook-form wrappers
13
+ - 🔍 **TypeScript First** - Full type safety and IntelliSense support
14
+ - 🌳 **Tree Shakeable** - Modular exports for optimal bundle size
15
+ - ♿ **Accessible** - WCAG compliant components
16
+ - 🎯 **Modern React** - Hooks, memo, forwardRef patterns
17
+ - 📱 **Responsive** - Mobile-first design approach
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @gnwebsoft/ui
23
+ # or
24
+ yarn add @gnwebsoft/ui
25
+ # or
26
+ pnpm add @gnwebsoft/ui
27
+ ```
28
+
29
+ ### Peer Dependencies
30
+
31
+ This library requires the following peer dependencies:
32
+
33
+ ```bash
34
+ npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled react-hook-form @hookform/resolvers zod
35
+ ```
36
+
37
+ <details>
38
+ <summary>Complete peer dependency list</summary>
39
+
40
+ ```json
41
+ {
42
+ "@emotion/cache": "^11.14.0",
43
+ "@emotion/react": "^11.14.0",
44
+ "@emotion/styled": "^11.14.0",
45
+ "@hookform/resolvers": "^5.2.1",
46
+ "@mui/icons-material": "^7.3.1",
47
+ "@mui/lab": "^7.0.0-beta.16",
48
+ "@mui/material": "^7.3.1",
49
+ "@mui/x-data-grid": "^8.9.2",
50
+ "@mui/x-date-pickers": "^8.9.2",
51
+ "autosuggest-highlight": "^3.3.4",
52
+ "axios": "^1.11.0",
53
+ "dayjs": "^1.11.13",
54
+ "es-toolkit": "^1.39.8",
55
+ "lodash": "^4.17.21",
56
+ "react": "^19.1.1",
57
+ "react-dom": "^19.1.1",
58
+ "react-hook-form": "^7.62.0",
59
+ "typescript": "^5.9.2",
60
+ "zod": "^4.0.15",
61
+ "zustand": "^5.0.2"
62
+ }
63
+ ```
64
+ </details>
65
+
66
+ ## Quick Start
67
+
68
+ ```tsx
69
+ import React from 'react';
70
+ import { SimpleButton, LabelText } from '@gnwebsoft/ui';
71
+ import { ThemeProvider, createTheme } from '@mui/material/styles';
72
+
73
+ const theme = createTheme();
74
+
75
+ function App() {
76
+ return (
77
+ <ThemeProvider theme={theme}>
78
+ <div>
79
+ <LabelText>Welcome to @gnwebsoft/ui</LabelText>
80
+ <SimpleButton
81
+ variant="contained"
82
+ color="primary"
83
+ onClick={() => alert('Hello World!')}
84
+ >
85
+ Click Me
86
+ </SimpleButton>
87
+ </div>
88
+ </ThemeProvider>
89
+ );
90
+ }
91
+
92
+ export default App;
93
+ ```
94
+
95
+ ## Module Imports
96
+
97
+ For optimal bundle size, import from specific modules:
98
+
99
+ ```tsx
100
+ // 🎯 Preferred - Tree-shakeable imports
101
+ import { SimpleButton } from '@gnwebsoft/ui/components';
102
+ import { TextFieldElement } from '@gnwebsoft/ui/wrappers';
103
+ import { useTransform } from '@gnwebsoft/ui/hooks';
104
+ import type { ApiResponse } from '@gnwebsoft/ui/types';
105
+ import { handleServerErrors } from '@gnwebsoft/ui/utils';
106
+
107
+ // 📦 Alternative - Root import (larger bundle)
108
+ import { SimpleButton, TextFieldElement } from '@gnwebsoft/ui';
109
+ ```
110
+
111
+ ### Available Modules
112
+
113
+ | Module | Description | Import Path |
114
+ |--------|-------------|-------------|
115
+ | **Components** | UI components | `@gnwebsoft/ui/components` |
116
+ | **Wrappers** | Form element wrappers | `@gnwebsoft/ui/wrappers` |
117
+ | **Hooks** | Custom React hooks | `@gnwebsoft/ui/hooks` |
118
+ | **Types** | TypeScript definitions | `@gnwebsoft/ui/types` |
119
+ | **Utils** | Utility functions | `@gnwebsoft/ui/utils` |
120
+
121
+ ## Components
122
+
123
+ ### Basic Components
124
+
125
+ #### SimpleButton
126
+ Enhanced MUI Button with loading states and conditional rendering.
127
+
128
+ ```tsx
129
+ import { SimpleButton } from '@gnwebsoft/ui/components';
130
+
131
+ <SimpleButton
132
+ loading={isSubmitting}
133
+ loadingText="Saving..."
134
+ show={hasPermission}
135
+ variant="contained"
136
+ onClick={handleSubmit}
137
+ >
138
+ Save Changes
139
+ </SimpleButton>
140
+ ```
141
+
142
+ **Features:**
143
+ - Loading state with spinner
144
+ - Conditional rendering
145
+ - Automatic disabling during loading
146
+ - Custom loading text support
147
+ - Full TypeScript support
148
+
149
+ #### LabelText
150
+ Responsive label-value display component with grid layout and hover effects.
151
+
152
+ ```tsx
153
+ import { LabelText } from '@gnwebsoft/ui/components';
154
+
155
+ <LabelText
156
+ label="Full Name"
157
+ value="John Doe"
158
+ gridSize={{
159
+ labelSize: { xs: 12, sm: 4, md: 3 },
160
+ valueSize: { xs: 12, sm: 8, md: 9 }
161
+ }}
162
+ />
163
+ ```
164
+
165
+ **Features:**
166
+ - Responsive grid layout
167
+ - Hover effects with background color change
168
+ - Text overflow handling with ellipsis
169
+ - Tooltip on hover showing full value
170
+ - Customizable spacing and styling
171
+
172
+ #### AuthorizedView
173
+ Simple conditional rendering component based on a boolean show prop.
174
+
175
+ ```tsx
176
+ import { AuthorizedView } from '@gnwebsoft/ui/components';
177
+
178
+ <AuthorizedView show={user.hasAdminRole}>
179
+ <AdminPanel />
180
+ </AuthorizedView>
181
+ ```
182
+
183
+ **Features:**
184
+ - Minimal overhead conditional rendering
185
+ - Returns empty fragment when hidden
186
+ - TypeScript support
187
+
188
+ #### ClearButton, CancelButton, FilterButton
189
+ Standardized button components for common form actions.
190
+
191
+ ```tsx
192
+ import { ClearButton, CancelButton, FilterButton } from '@gnwebsoft/ui/components';
193
+
194
+ <ClearButton
195
+ isSubmitting={isLoading}
196
+ handleClear={() => reset()}
197
+ storeKey="userFormData" // Optional localStorage cleanup
198
+ />
199
+
200
+ <CancelButton
201
+ isSubmitting={isLoading}
202
+ handleCancel={() => navigate('/dashboard')}
203
+ />
204
+
205
+ <FilterButton
206
+ isSubmitting={isFiltering}
207
+ show={hasFilters}
208
+ title="Apply Filters"
209
+ icon={<SearchIcon />}
210
+ />
211
+ ```
212
+
213
+ ### Layout Components
214
+
215
+ #### FormWrapper
216
+ Card-based container for forms with header, title, and action buttons.
217
+
218
+ ```tsx
219
+ import { FormWrapper } from '@gnwebsoft/ui/components';
220
+
221
+ <FormWrapper
222
+ title="User Profile"
223
+ icon={<PersonIcon />}
224
+ actionButton={
225
+ <SimpleButton variant="outlined" size="small">
226
+ Reset
227
+ </SimpleButton>
228
+ }
229
+ >
230
+ <TextFieldElement name="firstName" label="First Name" />
231
+ <TextFieldElement name="lastName" label="Last Name" />
232
+ </FormWrapper>
233
+ ```
234
+
235
+ **Features:**
236
+ - Card-based layout with header and content areas
237
+ - Divider between header and content
238
+ - Flexible action button placement
239
+ - Grid container for content with spacing
240
+
241
+ #### FilterWrapper, ListWrapper, SimpleToolbar
242
+ Specialized container components for different UI patterns.
243
+
244
+ ```tsx
245
+ import { FilterWrapper, ListWrapper, SimpleToolbar } from '@gnwebsoft/ui/components';
246
+
247
+ <FilterWrapper>
248
+ <TextField label="Search" />
249
+ <SelectElement name="category" options={categories} />
250
+ </FilterWrapper>
251
+
252
+ <ListWrapper>
253
+ <LabelText label="Name" value={user.name} />
254
+ <LabelText label="Email" value={user.email} />
255
+ </ListWrapper>
256
+
257
+ <SimpleToolbar>
258
+ <SimpleButton variant="contained">Add New</SimpleButton>
259
+ <SimpleButton variant="outlined">Export</SimpleButton>
260
+ </SimpleToolbar>
261
+ ```
262
+
263
+ ## Form Wrappers
264
+
265
+ All form wrappers integrate seamlessly with react-hook-form:
266
+
267
+ ```tsx
268
+ import { useForm } from 'react-hook-form';
269
+ import { zodResolver } from '@hookform/resolvers/zod';
270
+ import { z } from 'zod';
271
+ import {
272
+ TextFieldElement,
273
+ SelectElement,
274
+ DatePickerElement,
275
+ CheckboxElement
276
+ } from '@gnwebsoft/ui/wrappers';
277
+
278
+ const schema = z.object({
279
+ name: z.string().min(1, 'Name is required'),
280
+ email: z.string().email('Invalid email'),
281
+ category: z.string(),
282
+ birthDate: z.date(),
283
+ subscribe: z.boolean()
284
+ });
285
+
286
+ type FormData = z.infer<typeof schema>;
287
+
288
+ function ContactForm() {
289
+ const { control, handleSubmit } = useForm<FormData>({
290
+ resolver: zodResolver(schema)
291
+ });
292
+
293
+ return (
294
+ <form onSubmit={handleSubmit(onSubmit)}>
295
+ <TextFieldElement
296
+ control={control}
297
+ name="name"
298
+ label="Full Name"
299
+ required
300
+ />
301
+
302
+ <TextFieldElement
303
+ control={control}
304
+ name="email"
305
+ label="Email"
306
+ type="email"
307
+ required
308
+ />
309
+
310
+ <SelectElement
311
+ control={control}
312
+ name="category"
313
+ label="Category"
314
+ options={[
315
+ { value: 'general', label: 'General Inquiry' },
316
+ { value: 'support', label: 'Support' }
317
+ ]}
318
+ />
319
+
320
+ <DatePickerElement
321
+ control={control}
322
+ name="birthDate"
323
+ label="Birth Date"
324
+ />
325
+
326
+ <CheckboxElement
327
+ control={control}
328
+ name="subscribe"
329
+ label="Subscribe to newsletter"
330
+ />
331
+
332
+ <SimpleButton type="submit" variant="contained">
333
+ Submit
334
+ </SimpleButton>
335
+ </form>
336
+ );
337
+ }
338
+ ```
339
+
340
+ ### Available Form Wrappers
341
+
342
+ | Component | Description | Use Case | Features |
343
+ |-----------|-------------|----------|----------|
344
+ | `TextFieldElement` | Text input wrapper | Single-line text, email, password | Value transformation, grid layout, auto-validation |
345
+ | `PasswordElement` | Password input with visibility toggle | Secure password entry | Eye icon toggle, all TextFieldElement features |
346
+ | `SelectElement` | Single selection dropdown | Categories, statuses | Auto-select single option, custom label/value keys |
347
+ | `SelectMultiElement` | Multiple selection dropdown | Tags, permissions | Chip display, select all/none functionality |
348
+ | `SelectCascadeElement` | Dependent dropdown selections | Country → State → City | Hierarchical options, parent-child relationships |
349
+ | `AsyncSelect` | Async searchable dropdown | User search, API data | Debounced search, loading states, no options handling |
350
+ | `AsyncMultiSelect` | Async multiple selection | Multiple user selection | Async loading with multi-select capabilities |
351
+ | `DatePickerElement` | Date selection | Birth dates, deadlines | MUI date picker integration, keyboard input |
352
+ | `TimePickerElement` | Time selection | Appointments, schedules | MUI time picker integration, 12/24 hour format |
353
+ | `CheckboxElement` | Single checkbox | Agreements, preferences | Boolean value handling, label integration |
354
+ | `CheckboxGroup` | Multiple checkboxes | Multiple selections | Array value handling, group validation |
355
+ | `RadioButtonGroup` | Radio button group | Exclusive selections | Single selection from multiple options |
356
+
357
+ ## Hooks
358
+
359
+ ### useTransform
360
+ Transform values with memoization and change handling for form components.
361
+
362
+ ```tsx
363
+ import { useTransform } from '@gnwebsoft/ui/hooks';
364
+
365
+ const { value, onChange } = useTransform({
366
+ value: formValue,
367
+ onChange: field.onChange,
368
+ transform: {
369
+ input: (value) => value?.toString() || '',
370
+ output: (event) => parseInt(event.target.value) || null
371
+ }
372
+ });
373
+ ```
374
+
375
+ **Features:**
376
+ - Memoized transformations for performance
377
+ - Input/output transformation support
378
+ - Change event handling
379
+ - TypeScript type safety
380
+ - Integration with form components
381
+
382
+ **Common Use Cases:**
383
+ - Number input formatting
384
+ - Date formatting
385
+ - Currency formatting
386
+ - Array to string conversion
387
+
388
+ ## Types
389
+
390
+ Comprehensive TypeScript interfaces for API integration and form handling:
391
+
392
+ ```tsx
393
+ import type {
394
+ ApiResponse,
395
+ OperationResponse,
396
+ ValidationErrors,
397
+ OptionItem,
398
+ PostModel,
399
+ ListResponse
400
+ } from '@gnwebsoft/ui/types';
401
+
402
+ // API response structure
403
+ const response: ApiResponse<User[]> = {
404
+ status: 200,
405
+ apiData: users,
406
+ traceId: 'abc123'
407
+ };
408
+
409
+ // Form options
410
+ const options: OptionItem[] = [
411
+ { Label: 'Option 1', Value: '1' },
412
+ { Label: 'Option 2', Value: '2' }
413
+ ];
414
+
415
+ // Paginated list response
416
+ const listResponse: ListResponse<User> = {
417
+ Data: [/* users */],
418
+ Total: 150
419
+ };
420
+
421
+ // Filter/search request
422
+ const filterRequest: PostModel<UserFilter> = {
423
+ filterModel: { name: 'John' },
424
+ pageOffset: 0,
425
+ pageSize: 20,
426
+ sortField: 'name',
427
+ sortOrder: 'asc'
428
+ };
429
+ ```
430
+
431
+ **Available Types:**
432
+ - `ApiResponse<T>` - Standard API response structure
433
+ - `ValidationErrors` - Form validation errors
434
+ - `OptionItem` / `OptionItem2` - Select options
435
+ - `PostModel<T>` - Filter/pagination requests
436
+ - `ListResponse<T>` - Paginated responses
437
+ - `AsyncSelectPayload` - Async select data
438
+
439
+ ## Utilities
440
+
441
+ ### API Utilities
442
+
443
+ ```tsx
444
+ import { api, handleServerErrors } from '@gnwebsoft/ui/utils';
445
+
446
+ // API calls with automatic authentication
447
+ const users = await api.get<User[]>('/users');
448
+ const newUser = await api.post<User>('/users', userData);
449
+ const filteredUsers = await api.filter<User, UserFilter>('/users/search', filterModel);
450
+
451
+ // File upload
452
+ const uploadResult = await api.upload<UploadResponse>('/upload', formData);
453
+
454
+ // Form error handling
455
+ try {
456
+ await api.post('/submit', formData);
457
+ } catch (error) {
458
+ handleServerErrors({
459
+ errors: error.response.data.errors,
460
+ setError
461
+ });
462
+ }
463
+ ```
464
+
465
+ ### Data Transformation
466
+
467
+ ```tsx
468
+ import {
469
+ flattenObjectKeys,
470
+ readValueAsDate,
471
+ propertyExists,
472
+ removeLeadingTrailingSlashes,
473
+ getTimezone
474
+ } from '@gnwebsoft/ui/utils';
475
+
476
+ // Flatten nested objects
477
+ const flatData = flattenObjectKeys({ user: { name: 'John', age: 30 } });
478
+ // Result: { 'user.name': 'John', 'user.age': 30, 'user': {...} }
479
+
480
+ // Date conversion
481
+ const date = readValueAsDate('2023-12-25');
482
+ // Result: Date object or null
483
+
484
+ // Property checking
485
+ if (propertyExists(obj, 'user.address.street')) {
486
+ console.log(obj.user.address.street);
487
+ }
488
+
489
+ // URL cleaning
490
+ const cleanPath = removeLeadingTrailingSlashes('/api/users/');
491
+ // Result: 'api/users'
492
+
493
+ // Timezone info
494
+ const timezone = getTimezone();
495
+ // Result: 'America/New_York' or current timezone
496
+ ```
497
+
498
+ **Available Utilities:**
499
+ - `api` / `api2` - HTTP clients with authentication
500
+ - `handleServerErrors` - Form error mapping
501
+ - `flattenObjectKeys` - Nested object flattening
502
+ - `readValueAsDate` - Safe date conversion
503
+ - `propertyExists` - Type-safe property checking
504
+ - `removeLeadingTrailingSlashes` - URL path cleaning
505
+ - `getTimezone` - Timezone information
506
+ - `schemaTools` - Zod schema utilities
507
+
508
+ ## Styling and Theming
509
+
510
+ Components inherit MUI theme configuration:
511
+
512
+ ```tsx
513
+ import { createTheme, ThemeProvider } from '@mui/material/styles';
514
+
515
+ const theme = createTheme({
516
+ palette: {
517
+ primary: {
518
+ main: '#1976d2',
519
+ },
520
+ secondary: {
521
+ main: '#dc004e',
522
+ },
523
+ },
524
+ typography: {
525
+ fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
526
+ },
527
+ });
528
+
529
+ function App() {
530
+ return (
531
+ <ThemeProvider theme={theme}>
532
+ {/* Your app components */}
533
+ </ThemeProvider>
534
+ );
535
+ }
536
+ ```
537
+
538
+ ## Advanced Usage
539
+
540
+ ### Async Select with Search
541
+
542
+ ```tsx
543
+ import { AsyncSelect } from '@gnwebsoft/ui/wrappers';
544
+
545
+ <AsyncSelect
546
+ control={control}
547
+ name="assignee"
548
+ label="Assign to User"
549
+ loadOptions={async (searchValue) => {
550
+ const response = await api.get(`/users/search?q=${searchValue}`);
551
+ return response.data.map(user => ({
552
+ value: user.id,
553
+ label: `${user.name} (${user.email})`
554
+ }));
555
+ }}
556
+ placeholder="Search users..."
557
+ noOptionsText="No users found"
558
+ />
559
+ ```
560
+
561
+ ### Cascade Selects
562
+
563
+ ```tsx
564
+ import { SelectCascadeElement } from '@gnwebsoft/ui/wrappers';
565
+
566
+ <SelectCascadeElement
567
+ control={control}
568
+ name="location"
569
+ label="Location"
570
+ options={[
571
+ {
572
+ value: 'us',
573
+ label: 'United States',
574
+ children: [
575
+ { value: 'ny', label: 'New York' },
576
+ { value: 'ca', label: 'California' }
577
+ ]
578
+ }
579
+ ]}
580
+ />
581
+ ```
582
+
583
+ ## Testing
584
+
585
+ Components are built with testing in mind:
586
+
587
+ ```tsx
588
+ import { render, screen } from '@testing-library/react';
589
+ import { SimpleButton } from '@gnwebsoft/ui/components';
590
+
591
+ test('renders button with loading state', () => {
592
+ render(
593
+ <SimpleButton loading loadingText="Loading...">
594
+ Submit
595
+ </SimpleButton>
596
+ );
597
+
598
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
599
+ expect(screen.getByRole('button')).toBeDisabled();
600
+ });
601
+ ```
602
+
603
+ ## Contributing
604
+
605
+ 1. Fork the repository
606
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
607
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
608
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
609
+ 5. Open a Pull Request
610
+
611
+ ## Documentation
612
+
613
+ Comprehensive documentation is available for all components and utilities:
614
+
615
+ ### 📚 Complete Documentation
616
+ - **[Component Documentation](./docs/COMPONENT_DOCUMENTATION.md)** - Detailed guide for all components
617
+ - **[Components](./docs/components/README.md)** - UI Components documentation
618
+ - **[Form Wrappers](./docs/wrappers/README.md)** - Form wrapper components documentation
619
+ - **[Hooks](./docs/hooks/README.md)** - Custom React hooks documentation
620
+ - **[Utilities](./docs/utils/README.md)** - Utility functions documentation
621
+ - **[Types](./docs/types/README.md)** - TypeScript types documentation
622
+
623
+ ### 🎯 Quick References
624
+ - **[Getting Started Guide](./docs/guides/getting-started.md)** - Setup and basic usage
625
+ - **[Forms Guide](./docs/guides/forms.md)** - Form handling patterns
626
+ - **[API Documentation](./docs/api/README.md)** - Generated API docs
627
+
628
+ ### 📖 Examples
629
+ Each component includes:
630
+ - ✅ Basic usage examples
631
+ - ✅ Advanced configuration options
632
+ - ✅ TypeScript integration examples
633
+ - ✅ Testing patterns
634
+ - ✅ Accessibility guidelines
635
+ - ✅ Performance considerations
636
+
637
+ ## Development
638
+
639
+ ```bash
640
+ # Install dependencies
641
+ pnpm install
642
+
643
+ # Start development mode with hot reload
644
+ pnpm dev
645
+
646
+ # Run tests
647
+ pnpm test
648
+
649
+ # Build library
650
+ pnpm build
651
+
652
+ # Generate TypeScript documentation
653
+ pnpm docs:generate
654
+
655
+ # Validate package exports
656
+ pnpm run check-exports
657
+ ```
658
+
659
+ ### Development Workflow
660
+ The package supports instant development with hot module reloading:
661
+
662
+ ```bash
663
+ # Start both UI package and sample app
664
+ pnpm dev
665
+
666
+ # Or start individually
667
+ pnpm run dev:ui # UI package in watch mode
668
+ pnpm run dev:web # Sample web app
669
+ ```
670
+
671
+ ## Browser Support
672
+
673
+ - Chrome (latest)
674
+ - Firefox (latest)
675
+ - Safari (latest)
676
+ - Edge (latest)
677
+
678
+ ## License
679
+
680
+ MIT © GNWebsoft Private Limited
681
+
682
+ ## Changelog
683
+
684
+ See [CHANGELOG.md](./CHANGELOG.md) for release history.
685
+
686
+ ---
687
+
688
+ **Made with ❤️ by GNWebsoft Team**