@admin-layout/tailwind-ui 10.0.9-alpha.71
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.
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/lib/components/ErrorHandlers/ApplicationErrorHandler.d.ts +2 -0
- package/lib/components/ErrorHandlers/ApplicationErrorHandler.d.ts.map +1 -0
- package/lib/components/ErrorHandlers/ApplicationErrorHandler.js +24 -0
- package/lib/components/ErrorHandlers/ApplicationErrorHandler.js.map +1 -0
- package/lib/components/ErrorHandlers/ErrorBoundary.d.ts +2 -0
- package/lib/components/ErrorHandlers/ErrorBoundary.d.ts.map +1 -0
- package/lib/components/ErrorHandlers/ErrorBoundary.js +48 -0
- package/lib/components/ErrorHandlers/ErrorBoundary.js.map +1 -0
- package/lib/components/ErrorHandlers/LayoutErrorBoundary.d.ts +2 -0
- package/lib/components/ErrorHandlers/LayoutErrorBoundary.d.ts.map +1 -0
- package/lib/components/ErrorHandlers/LayoutErrorBoundary.js +34 -0
- package/lib/components/ErrorHandlers/LayoutErrorBoundary.js.map +1 -0
- package/lib/components/ErrorHandlers/index.d.ts +4 -0
- package/lib/components/ErrorHandlers/index.d.ts.map +1 -0
- package/lib/components/ErrorPages/403.d.ts +2 -0
- package/lib/components/ErrorPages/403.d.ts.map +1 -0
- package/lib/components/ErrorPages/403.js +29 -0
- package/lib/components/ErrorPages/403.js.map +1 -0
- package/lib/components/ErrorPages/404.d.ts +2 -0
- package/lib/components/ErrorPages/404.d.ts.map +1 -0
- package/lib/components/ErrorPages/404.js +29 -0
- package/lib/components/ErrorPages/404.js.map +1 -0
- package/lib/components/ErrorPages/500.d.ts +2 -0
- package/lib/components/ErrorPages/500.d.ts.map +1 -0
- package/lib/components/ErrorPages/500.js +29 -0
- package/lib/components/ErrorPages/500.js.map +1 -0
- package/lib/components/ErrorPages/index.d.ts +4 -0
- package/lib/components/ErrorPages/index.d.ts.map +1 -0
- package/lib/components/OTP/OTPInput.d.ts +4 -0
- package/lib/components/OTP/OTPInput.d.ts.map +1 -0
- package/lib/components/OTP/OTPInput.js +82 -0
- package/lib/components/OTP/OTPInput.js.map +1 -0
- package/lib/components/OTP/OTPVerification.d.ts +4 -0
- package/lib/components/OTP/OTPVerification.d.ts.map +1 -0
- package/lib/components/OTP/OTPVerification.js +155 -0
- package/lib/components/OTP/OTPVerification.js.map +1 -0
- package/lib/components/OTP/SingleInput.d.ts +10 -0
- package/lib/components/OTP/SingleInput.d.ts.map +1 -0
- package/lib/components/OTP/SingleInput.js +43 -0
- package/lib/components/OTP/SingleInput.js.map +1 -0
- package/lib/components/OTP/hooks.d.ts +3 -0
- package/lib/components/OTP/hooks.d.ts.map +1 -0
- package/lib/components/OTP/hooks.js +95 -0
- package/lib/components/OTP/hooks.js.map +1 -0
- package/lib/components/OTP/index.d.ts +6 -0
- package/lib/components/OTP/index.d.ts.map +1 -0
- package/lib/components/OTP/types.d.ts +110 -0
- package/lib/components/OTP/types.d.ts.map +1 -0
- package/lib/components/OTP/utils.d.ts +26 -0
- package/lib/components/OTP/utils.d.ts.map +1 -0
- package/lib/components/OTP/utils.js +36 -0
- package/lib/components/OTP/utils.js.map +1 -0
- package/lib/components/PageContainer/PageContainer.d.ts +4 -0
- package/lib/components/PageContainer/PageContainer.d.ts.map +1 -0
- package/lib/components/PageContainer/PageContainer.js +57 -0
- package/lib/components/PageContainer/PageContainer.js.map +1 -0
- package/lib/components/PageContainer/index.d.ts +2 -0
- package/lib/components/PageContainer/index.d.ts.map +1 -0
- package/lib/components/PageContainer/types.d.ts +51 -0
- package/lib/components/PageContainer/types.d.ts.map +1 -0
- package/lib/components/PageLoading/index.d.ts +6 -0
- package/lib/components/PageLoading/index.d.ts.map +1 -0
- package/lib/components/PageLoading/index.js +9 -0
- package/lib/components/PageLoading/index.js.map +1 -0
- package/lib/components/ReactTable/Table.d.ts +18 -0
- package/lib/components/ReactTable/Table.d.ts.map +1 -0
- package/lib/components/ReactTable/Table.js +151 -0
- package/lib/components/ReactTable/Table.js.map +1 -0
- package/lib/components/ReactTable/TableFilters.d.ts +8 -0
- package/lib/components/ReactTable/TableFilters.d.ts.map +1 -0
- package/lib/components/ReactTable/TableFilters.js +58 -0
- package/lib/components/ReactTable/TableFilters.js.map +1 -0
- package/lib/components/ReactTable/index.d.ts +3 -0
- package/lib/components/ReactTable/index.d.ts.map +1 -0
- package/lib/components/Spin/index.d.ts +10 -0
- package/lib/components/Spin/index.d.ts.map +1 -0
- package/lib/components/Spin/index.js +31 -0
- package/lib/components/Spin/index.js.map +1 -0
- package/lib/components/index.d.ts +9 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/hooks/useToast.d.ts +17 -0
- package/lib/hooks/useToast.d.ts.map +1 -0
- package/lib/hooks/useToast.js +163 -0
- package/lib/hooks/useToast.js.map +1 -0
- package/lib/icons/index.d.ts +15 -0
- package/lib/icons/index.d.ts.map +1 -0
- package/lib/icons/index.js +14 -0
- package/lib/icons/index.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/machines/otpMachine.d.ts +3 -0
- package/lib/machines/otpMachine.d.ts.map +1 -0
- package/lib/machines/otpMachine.js +131 -0
- package/lib/machines/otpMachine.js.map +1 -0
- package/lib/utils/hooks/useDebounceFn/index.d.ts +8 -0
- package/lib/utils/hooks/useDebounceFn/index.d.ts.map +1 -0
- package/lib/utils/hooks/useDeepCompareEffect/index.d.ts +5 -0
- package/lib/utils/hooks/useDeepCompareEffect/index.d.ts.map +1 -0
- package/lib/utils/hooks/useDocumentTitle/index.d.ts +7 -0
- package/lib/utils/hooks/useDocumentTitle/index.d.ts.map +1 -0
- package/lib/utils/hooks/usePrevious/index.d.ts +3 -0
- package/lib/utils/hooks/usePrevious/index.d.ts.map +1 -0
- package/lib/utils/hooks/useWindowDimensions/index.d.ts +5 -0
- package/lib/utils/hooks/useWindowDimensions/index.d.ts.map +1 -0
- package/lib/utils/hooks/useWindowDimensions/index.js +21 -0
- package/lib/utils/hooks/useWindowDimensions/index.js.map +1 -0
- package/lib/utils/index.d.ts +21 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/isBrowser/index.d.ts +3 -0
- package/lib/utils/isBrowser/index.d.ts.map +1 -0
- package/lib/utils/isDropdownValueType/index.d.ts +3 -0
- package/lib/utils/isDropdownValueType/index.d.ts.map +1 -0
- package/lib/utils/isImg/index.d.ts +4 -0
- package/lib/utils/isImg/index.d.ts.map +1 -0
- package/lib/utils/isNil/index.d.ts +3 -0
- package/lib/utils/isNil/index.d.ts.map +1 -0
- package/lib/utils/isUrl/index.d.ts +3 -0
- package/lib/utils/isUrl/index.d.ts.map +1 -0
- package/lib/utils/omitUndefined/index.d.ts +3 -0
- package/lib/utils/omitUndefined/index.d.ts.map +1 -0
- package/lib/utils/omitUndefinedAndEmptyArr/index.d.ts +3 -0
- package/lib/utils/omitUndefinedAndEmptyArr/index.d.ts.map +1 -0
- package/lib/utils/typing.d.ts +142 -0
- package/lib/utils/typing.d.ts.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 CDMBase LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Tailwind CSS Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document outlines our approach to using Tailwind CSS for component styling across the project. Tailwind provides a utility-first CSS framework that enables rapid UI development with consistent design patterns.
|
|
6
|
+
|
|
7
|
+
## Documentation Reference
|
|
8
|
+
|
|
9
|
+
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
|
|
10
|
+
- [Tailwind CSS GitHub](https://github.com/tailwindlabs/tailwindcss)
|
|
11
|
+
|
|
12
|
+
## Implementation Process
|
|
13
|
+
|
|
14
|
+
We use Tailwind utility classes directly in our components. This approach provides several benefits:
|
|
15
|
+
|
|
16
|
+
1. Eliminates the need for custom CSS files
|
|
17
|
+
2. Enables faster development through pre-defined utility classes
|
|
18
|
+
3. Ensures consistent styling across the application
|
|
19
|
+
4. Reduces overall bundle size by removing unnecessary CSS
|
|
20
|
+
|
|
21
|
+
## Tailwind CSS Implementation Guidelines
|
|
22
|
+
|
|
23
|
+
Follow these guidelines when implementing components with Tailwind:
|
|
24
|
+
|
|
25
|
+
1. Use Tailwind utility classes directly in your components
|
|
26
|
+
2. Refer to the Tailwind documentation for available classes
|
|
27
|
+
3. Use Tailwind's responsive prefixes for different screen sizes (sm:, md:, lg:, xl:, 2xl:)
|
|
28
|
+
4. Use Tailwind's state variants (hover:, focus:, active:, etc.)
|
|
29
|
+
5. Group related classes for better readability
|
|
30
|
+
|
|
31
|
+
## Example Component with Tailwind
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
<div className="relative flex cursor-pointer hover:bg-blue-600">
|
|
35
|
+
<a href="/" className="flex">
|
|
36
|
+
<img src="/logo.png" alt="logo" className="inline-block" />
|
|
37
|
+
<h1 className="inline-block ml-2 text-xl font-semibold text-gray-800">Application Name</h1>
|
|
38
|
+
</a>
|
|
39
|
+
</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Common Tailwind Patterns
|
|
43
|
+
|
|
44
|
+
### Layout Components
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
// Simple card component
|
|
48
|
+
<div className="p-4 bg-white rounded-lg shadow-md">
|
|
49
|
+
<h2 className="text-xl font-bold mb-2">Card Title</h2>
|
|
50
|
+
<p className="text-gray-600">Card content goes here</p>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
// Flex container with items
|
|
54
|
+
<div className="flex items-center justify-between p-4">
|
|
55
|
+
<div className="flex-1">Left content</div>
|
|
56
|
+
<div className="flex-1 text-right">Right content</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
// Grid layout
|
|
60
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
61
|
+
<div className="p-4 bg-white rounded-lg shadow">Item 1</div>
|
|
62
|
+
<div className="p-4 bg-white rounded-lg shadow">Item 2</div>
|
|
63
|
+
<div className="p-4 bg-white rounded-lg shadow">Item 3</div>
|
|
64
|
+
</div>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Testing Components
|
|
68
|
+
|
|
69
|
+
For testing Tailwind components, consider using these approaches:
|
|
70
|
+
|
|
71
|
+
1. Visual regression testing with tools like Storybook and Chromatic
|
|
72
|
+
2. Snapshot testing with Jest
|
|
73
|
+
3. Component testing with React Testing Library to ensure proper class application
|
|
74
|
+
|
|
75
|
+
Example test with React Testing Library:
|
|
76
|
+
|
|
77
|
+
```jsx
|
|
78
|
+
import { render, screen } from '@testing-library/react';
|
|
79
|
+
import Header from './Header';
|
|
80
|
+
|
|
81
|
+
test('renders header with correct Tailwind classes', () => {
|
|
82
|
+
render(<Header />);
|
|
83
|
+
const logoElement = screen.getByTestId('logo');
|
|
84
|
+
expect(logoElement).toHaveClass('relative');
|
|
85
|
+
expect(logoElement).toHaveClass('flex');
|
|
86
|
+
expect(logoElement).toHaveClass('cursor-pointer');
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Responsive Design with Tailwind
|
|
91
|
+
|
|
92
|
+
Tailwind makes it easy to create responsive designs using breakpoint prefixes:
|
|
93
|
+
|
|
94
|
+
```jsx
|
|
95
|
+
<div className="w-full md:w-1/2 lg:w-1/3 p-4">
|
|
96
|
+
{/* This element will be full width on mobile,
|
|
97
|
+
half width on medium screens,
|
|
98
|
+
and one-third width on large screens */}
|
|
99
|
+
<div className="bg-white p-4 rounded shadow">
|
|
100
|
+
<h2 className="text-lg md:text-xl lg:text-2xl">Responsive Title</h2>
|
|
101
|
+
<p className="hidden md:block">This text only appears on medium screens and larger</p>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Best Practices
|
|
107
|
+
|
|
108
|
+
1. **Group related utilities** - Keep related utility classes together for better readability
|
|
109
|
+
2. **Extract component patterns** - For repeated patterns, create reusable components
|
|
110
|
+
3. **Use @apply sparingly** - Only use the @apply directive for truly reusable styles
|
|
111
|
+
4. **Mobile-first approach** - Start with mobile layouts and add responsive variants
|
|
112
|
+
5. **Use custom theme values** - Extend Tailwind's theme with your project-specific values
|
|
113
|
+
|
|
114
|
+
## Theme Customization
|
|
115
|
+
|
|
116
|
+
Create a `tailwind.config.js` file to customize colors, spacing, and other design tokens:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
// tailwind.config.js
|
|
120
|
+
module.exports = {
|
|
121
|
+
theme: {
|
|
122
|
+
extend: {
|
|
123
|
+
colors: {
|
|
124
|
+
primary: {
|
|
125
|
+
light: '#4da8ff',
|
|
126
|
+
DEFAULT: '#0073e6',
|
|
127
|
+
dark: '#005bb8',
|
|
128
|
+
},
|
|
129
|
+
// Add more custom colors
|
|
130
|
+
},
|
|
131
|
+
spacing: {
|
|
132
|
+
72: '18rem',
|
|
133
|
+
84: '21rem',
|
|
134
|
+
96: '24rem',
|
|
135
|
+
},
|
|
136
|
+
// Add other customizations
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
// Add plugins or other configurations
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Advanced Tailwind Features
|
|
144
|
+
|
|
145
|
+
### Dark Mode
|
|
146
|
+
|
|
147
|
+
Tailwind supports dark mode out of the box. Enable it in your config:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
// tailwind.config.js
|
|
151
|
+
module.exports = {
|
|
152
|
+
darkMode: 'class', // or 'media' for OS-level preference
|
|
153
|
+
// ...rest of your config
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Then use dark: variant in your components:
|
|
158
|
+
|
|
159
|
+
```jsx
|
|
160
|
+
<div className="bg-white text-black dark:bg-gray-800 dark:text-white">
|
|
161
|
+
This component changes appearance in dark mode
|
|
162
|
+
</div>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Custom Plugins
|
|
166
|
+
|
|
167
|
+
Extend Tailwind's functionality with plugins for common patterns:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
// tailwind.config.js
|
|
171
|
+
const plugin = require('tailwindcss/plugin');
|
|
172
|
+
|
|
173
|
+
module.exports = {
|
|
174
|
+
plugins: [
|
|
175
|
+
plugin(function ({ addComponents }) {
|
|
176
|
+
const buttons = {
|
|
177
|
+
'.btn': {
|
|
178
|
+
padding: '.5rem 1rem',
|
|
179
|
+
borderRadius: '.25rem',
|
|
180
|
+
fontWeight: '600',
|
|
181
|
+
},
|
|
182
|
+
'.btn-blue': {
|
|
183
|
+
backgroundColor: '#3490dc',
|
|
184
|
+
color: '#fff',
|
|
185
|
+
'&:hover': {
|
|
186
|
+
backgroundColor: '#2779bd',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
addComponents(buttons);
|
|
191
|
+
}),
|
|
192
|
+
],
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### JIT (Just-In-Time) Mode
|
|
197
|
+
|
|
198
|
+
Tailwind v3 uses JIT mode by default, which:
|
|
199
|
+
|
|
200
|
+
- Only generates the CSS you actually use
|
|
201
|
+
- Allows for arbitrary values like `w-[327px]`
|
|
202
|
+
- Provides faster build times
|
|
203
|
+
- Enables all variants for all utilities
|
|
204
|
+
|
|
205
|
+
## Common Component Examples
|
|
206
|
+
|
|
207
|
+
### Button Component
|
|
208
|
+
|
|
209
|
+
```jsx
|
|
210
|
+
// Primary button
|
|
211
|
+
<button className="px-4 py-2 bg-blue-600 text-white font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 transition-colors">
|
|
212
|
+
Submit
|
|
213
|
+
</button>
|
|
214
|
+
|
|
215
|
+
// Secondary button
|
|
216
|
+
<button className="px-4 py-2 bg-gray-200 text-gray-800 font-medium rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-opacity-50 transition-colors">
|
|
217
|
+
Cancel
|
|
218
|
+
</button>
|
|
219
|
+
|
|
220
|
+
// Disabled button
|
|
221
|
+
<button disabled className="px-4 py-2 bg-gray-300 text-gray-500 font-medium rounded-md cursor-not-allowed">
|
|
222
|
+
Disabled
|
|
223
|
+
</button>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Form Input
|
|
227
|
+
|
|
228
|
+
```jsx
|
|
229
|
+
<div className="mb-4">
|
|
230
|
+
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="username">
|
|
231
|
+
Username
|
|
232
|
+
</label>
|
|
233
|
+
<input
|
|
234
|
+
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
|
235
|
+
id="username"
|
|
236
|
+
type="text"
|
|
237
|
+
placeholder="Username"
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Navigation Bar
|
|
243
|
+
|
|
244
|
+
```jsx
|
|
245
|
+
<nav className="bg-gray-800">
|
|
246
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
247
|
+
<div className="flex items-center justify-between h-16">
|
|
248
|
+
<div className="flex items-center">
|
|
249
|
+
<div className="flex-shrink-0">
|
|
250
|
+
<img className="h-8 w-8" src="/logo.svg" alt="Logo" />
|
|
251
|
+
</div>
|
|
252
|
+
<div className="hidden md:block">
|
|
253
|
+
<div className="ml-10 flex items-baseline space-x-4">
|
|
254
|
+
<a href="#" className="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium">
|
|
255
|
+
Dashboard
|
|
256
|
+
</a>
|
|
257
|
+
<a
|
|
258
|
+
href="#"
|
|
259
|
+
className="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
|
|
260
|
+
>
|
|
261
|
+
Team
|
|
262
|
+
</a>
|
|
263
|
+
<a
|
|
264
|
+
href="#"
|
|
265
|
+
className="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
|
|
266
|
+
>
|
|
267
|
+
Projects
|
|
268
|
+
</a>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</nav>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Performance Considerations
|
|
278
|
+
|
|
279
|
+
1. **Purge unused CSS** - Configure purge settings to remove unused classes in production:
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
// tailwind.config.js
|
|
283
|
+
module.exports = {
|
|
284
|
+
content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
|
|
285
|
+
// ...rest of your config
|
|
286
|
+
};
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
2. **Minify CSS in production** - Use cssnano or another minifier in your build process
|
|
290
|
+
3. **Avoid excessive class duplication** - Extract common patterns to component libraries
|
|
291
|
+
|
|
292
|
+
## Resources
|
|
293
|
+
|
|
294
|
+
- [Tailwind CSS Components](https://tailwindui.com/) - Official component library
|
|
295
|
+
- [Headless UI](https://headlessui.dev/) - Unstyled, accessible UI components
|
|
296
|
+
- [Tailwind Cheat Sheet](https://nerdcave.com/tailwind-cheat-sheet) - Quick reference
|
|
297
|
+
- [Tailwind Play](https://play.tailwindcss.com/) - Online playground
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApplicationErrorHandler.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorHandlers/ApplicationErrorHandler.tsx"],"names":[],"mappings":"AAwBA,eAAO,MAAM,uBAAuB,yDAGnC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {jsx}from'react/jsx-runtime';import {ApplicationErrorHandlerCommon}from'@admin-layout/client';import*as React from'react';import {logger}from'@cdm-logger/client';import {useToast}from'../../hooks/useToast.js';const FallbackComponent = ({
|
|
2
|
+
error
|
|
3
|
+
}) => {
|
|
4
|
+
const toast = useToast();
|
|
5
|
+
React.useLayoutEffect(() => {
|
|
6
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7
|
+
toast({
|
|
8
|
+
position: 'top',
|
|
9
|
+
title: 'Server Errors. Please try again later...',
|
|
10
|
+
status: 'error',
|
|
11
|
+
duration: 9000,
|
|
12
|
+
isClosable: true
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
logger.error('Application Backend Error', error?.payload.message);
|
|
16
|
+
}, [toast]);
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
const ApplicationErrorHandler = props => {
|
|
20
|
+
const CommonHandler = ApplicationErrorHandlerCommon(FallbackComponent);
|
|
21
|
+
return jsx(CommonHandler, {
|
|
22
|
+
...props
|
|
23
|
+
});
|
|
24
|
+
};export{ApplicationErrorHandler};//# sourceMappingURL=ApplicationErrorHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApplicationErrorHandler.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorHandlers/ErrorBoundary.tsx"],"names":[],"mappings":"AAyCA,eAAO,MAAM,aAAa,yDAEzB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {ErrorBoundaryCommon}from'@admin-layout/client';import*as React from'react';import {useNavigate}from'@remix-run/react';import {logger}from'@cdm-logger/client';import {icons}from'../../icons/index.js';const Fallback = props => {
|
|
2
|
+
const {
|
|
3
|
+
error
|
|
4
|
+
} = props;
|
|
5
|
+
const navigate = useNavigate();
|
|
6
|
+
const {
|
|
7
|
+
ExclamationCircleIcon
|
|
8
|
+
} = icons;
|
|
9
|
+
React.useEffect(() => {
|
|
10
|
+
logger.trace(error);
|
|
11
|
+
}, [error]);
|
|
12
|
+
return jsxs("div", {
|
|
13
|
+
className: "flex items-start p-4 rounded-md bg-red-50 border border-red-200",
|
|
14
|
+
children: [jsx("div", {
|
|
15
|
+
className: "flex-shrink-0 mr-3 text-red-400",
|
|
16
|
+
children: jsx(ExclamationCircleIcon, {
|
|
17
|
+
className: "h-5 w-5"
|
|
18
|
+
})
|
|
19
|
+
}), jsxs("div", {
|
|
20
|
+
className: "flex-1",
|
|
21
|
+
children: [jsx("h3", {
|
|
22
|
+
className: "text-lg font-medium text-red-800",
|
|
23
|
+
children: "Error!"
|
|
24
|
+
}), jsx("div", {
|
|
25
|
+
className: "mt-2 text-sm text-red-700",
|
|
26
|
+
children: error?.message
|
|
27
|
+
})]
|
|
28
|
+
}), jsx("button", {
|
|
29
|
+
className: "ml-4 px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition-colors",
|
|
30
|
+
onClick: () => {
|
|
31
|
+
navigate('/');
|
|
32
|
+
/**
|
|
33
|
+
* Have to reload the window because the above dispatch will only change the router
|
|
34
|
+
* but won't refresh due to which we have to call the reload on location
|
|
35
|
+
* Reference: https://stackoverflow.com/questions/63060387/how-do-i-redirect-within-an-errorboundary
|
|
36
|
+
*/
|
|
37
|
+
window.location.reload();
|
|
38
|
+
},
|
|
39
|
+
children: "Home"
|
|
40
|
+
})]
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const ErrorBoundary = props => {
|
|
44
|
+
return jsx(ErrorBoundaryCommon, {
|
|
45
|
+
fallbackComponent: Fallback,
|
|
46
|
+
children: props?.children
|
|
47
|
+
});
|
|
48
|
+
};export{ErrorBoundary};//# sourceMappingURL=ErrorBoundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutErrorBoundary.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorHandlers/LayoutErrorBoundary.tsx"],"names":[],"mappings":"AAoBA,eAAO,MAAM,mBAAmB,yDAO/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {ErrorBoundaryCommon}from'@admin-layout/client';import {icons}from'../../icons/index.js';const Fallback = props => {
|
|
2
|
+
const {
|
|
3
|
+
error
|
|
4
|
+
} = props;
|
|
5
|
+
const {
|
|
6
|
+
TimesIcon
|
|
7
|
+
} = icons;
|
|
8
|
+
return jsxs("div", {
|
|
9
|
+
className: "flex flex-col items-center justify-center p-8 text-center",
|
|
10
|
+
children: [jsx("div", {
|
|
11
|
+
className: "mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-100",
|
|
12
|
+
children: jsx(TimesIcon, {
|
|
13
|
+
className: "h-8 w-8 text-red-500"
|
|
14
|
+
})
|
|
15
|
+
}), jsx("h2", {
|
|
16
|
+
className: "mb-2 text-2xl font-bold text-gray-800",
|
|
17
|
+
children: "Something Went Wrong!"
|
|
18
|
+
}), jsx("p", {
|
|
19
|
+
className: "text-gray-600",
|
|
20
|
+
children: error?.message || 'Unable to identify the cause of this error. Please try again later!'
|
|
21
|
+
})]
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const LayoutErrorBoundary = props => {
|
|
25
|
+
const {
|
|
26
|
+
children,
|
|
27
|
+
pathname
|
|
28
|
+
} = props;
|
|
29
|
+
return jsx(ErrorBoundaryCommon, {
|
|
30
|
+
fallbackComponent: Fallback,
|
|
31
|
+
pathname: pathname,
|
|
32
|
+
children: children
|
|
33
|
+
});
|
|
34
|
+
};export{LayoutErrorBoundary};//# sourceMappingURL=LayoutErrorBoundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutErrorBoundary.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorHandlers/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"403.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorPages/403.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,+CAuBpB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useNavigate}from'@remix-run/react';import assets from'@admin-layout/assets';const Error403 = () => {
|
|
2
|
+
const navigate = useNavigate();
|
|
3
|
+
const goBack = () => navigate(-1);
|
|
4
|
+
return jsx("div", {
|
|
5
|
+
className: "flex justify-center items-center",
|
|
6
|
+
children: jsxs("div", {
|
|
7
|
+
children: [jsx("div", {
|
|
8
|
+
className: "text-center",
|
|
9
|
+
children: jsx("h5", {
|
|
10
|
+
className: "text-2xl font-bold",
|
|
11
|
+
children: "Error: 403 Forbidden"
|
|
12
|
+
})
|
|
13
|
+
}), jsx("div", {
|
|
14
|
+
className: "mt-10",
|
|
15
|
+
children: jsx("img", {
|
|
16
|
+
src: assets['error-403-540x432.png'],
|
|
17
|
+
alt: "403 Error"
|
|
18
|
+
})
|
|
19
|
+
}), jsx("div", {
|
|
20
|
+
className: "flex justify-center",
|
|
21
|
+
children: jsx("button", {
|
|
22
|
+
className: "mt-8 mb-8 w-64 h-20 bg-yellow-400 rounded-full text-white hover:bg-yellow-500 transition-colors",
|
|
23
|
+
onClick: goBack,
|
|
24
|
+
children: "Go Home"
|
|
25
|
+
})
|
|
26
|
+
})]
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
};export{Error403};//# sourceMappingURL=403.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"403.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"404.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorPages/404.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,+CAuBpB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useNavigate}from'@remix-run/react';import assets from'@admin-layout/assets';const Error404 = () => {
|
|
2
|
+
const navigate = useNavigate();
|
|
3
|
+
const goBack = () => navigate(-1);
|
|
4
|
+
return jsx("div", {
|
|
5
|
+
className: "flex justify-center items-center",
|
|
6
|
+
children: jsxs("div", {
|
|
7
|
+
children: [jsx("div", {
|
|
8
|
+
className: "text-center",
|
|
9
|
+
children: jsx("h5", {
|
|
10
|
+
className: "text-2xl font-bold",
|
|
11
|
+
children: "Error: 404 Page Not Found"
|
|
12
|
+
})
|
|
13
|
+
}), jsx("div", {
|
|
14
|
+
className: "mt-10",
|
|
15
|
+
children: jsx("img", {
|
|
16
|
+
src: assets['error-404-540x432.png'],
|
|
17
|
+
alt: "404 Error"
|
|
18
|
+
})
|
|
19
|
+
}), jsx("div", {
|
|
20
|
+
className: "flex justify-center",
|
|
21
|
+
children: jsx("button", {
|
|
22
|
+
className: "mt-8 mb-8 w-64 h-20 bg-yellow-400 rounded-full text-white hover:bg-yellow-500 transition-colors",
|
|
23
|
+
onClick: goBack,
|
|
24
|
+
children: "Go Home"
|
|
25
|
+
})
|
|
26
|
+
})]
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
};export{Error404};//# sourceMappingURL=404.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"404.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"500.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorPages/500.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,+CAuBpB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useNavigate}from'@remix-run/react';import assets from'@admin-layout/assets';const Error500 = () => {
|
|
2
|
+
const navigate = useNavigate();
|
|
3
|
+
const goBack = () => navigate(-1);
|
|
4
|
+
return jsx("div", {
|
|
5
|
+
className: "flex justify-center items-center",
|
|
6
|
+
children: jsxs("div", {
|
|
7
|
+
children: [jsx("div", {
|
|
8
|
+
className: "text-center",
|
|
9
|
+
children: jsx("h5", {
|
|
10
|
+
className: "text-2xl font-bold",
|
|
11
|
+
children: "Error: 500 Unexpected Error"
|
|
12
|
+
})
|
|
13
|
+
}), jsx("div", {
|
|
14
|
+
className: "mt-10",
|
|
15
|
+
children: jsx("img", {
|
|
16
|
+
src: assets['error-500-252x475.png'],
|
|
17
|
+
alt: "500 Error"
|
|
18
|
+
})
|
|
19
|
+
}), jsx("div", {
|
|
20
|
+
className: "flex justify-center",
|
|
21
|
+
children: jsx("button", {
|
|
22
|
+
className: "mt-8 mb-8 w-64 h-20 bg-yellow-400 rounded-full text-white hover:bg-yellow-500 transition-colors",
|
|
23
|
+
onClick: goBack,
|
|
24
|
+
children: "Go Home"
|
|
25
|
+
})
|
|
26
|
+
})]
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
};export{Error500};//# sourceMappingURL=500.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"500.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorPages/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OTPInput.d.ts","sourceRoot":"","sources":["../../../src/components/OTP/OTPInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAc,MAAM,SAAS,CAAC;AAKpD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAwF5C,CAAC"}
|