jiffy-ui 1.2.0 → 1.2.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.
- package/README.md +747 -66
- package/dist/assets/fonts/Inter_Bold.ttf +0 -0
- package/dist/assets/fonts/Inter_Bold.woff +0 -0
- package/dist/assets/fonts/Inter_Bold.woff2 +0 -0
- package/dist/assets/fonts/Inter_ExtraBold.ttf +0 -0
- package/dist/assets/fonts/Inter_Regular.ttf +0 -0
- package/dist/assets/fonts/Inter_Regular.woff +0 -0
- package/dist/assets/fonts/Inter_Regular.woff2 +0 -0
- package/dist/assets/fonts/Inter_SemiBold.ttf +0 -0
- package/dist/assets/fonts/Inter_SemiBold.woff +0 -0
- package/dist/assets/fonts/Inter_SemiBold.woff2 +0 -0
- package/dist/components/Accordion/Accordion.d.ts +1 -2
- package/dist/components/Accordion/Accordion.stories.d.ts +1 -9
- package/dist/components/Actionlist/Actionlist.d.ts +1 -1
- package/dist/components/Actionlist/Actionlist.stories.d.ts +1 -1
- package/dist/components/Badge/Badge.d.ts +7 -29
- package/dist/components/Badge/Badge.stories.d.ts +46 -33
- package/dist/components/BottomSheet/BottomSheet.d.ts +3 -0
- package/dist/components/BottomSheet/BottomSheet.stories.d.ts +38 -4
- package/dist/components/CopyClipboard/CopyClipboard.d.ts +36 -6
- package/dist/components/CopyClipboard/CopyClipboard.stories.d.ts +85 -17
- package/dist/components/FlexLayout/FlexLayout.stories.d.ts +73 -0
- package/dist/components/Indicator/Indicator.d.ts +2 -3
- package/dist/components/Indicator/Indicator.stories.d.ts +1 -12
- package/dist/components/InlineStack/InlineStack.d.ts +38 -0
- package/dist/components/InlineStack/InlineStack.stories.d.ts +15 -0
- package/dist/components/MediaCard/MediaCard.d.ts +11 -51
- package/dist/components/MediaCard/MediaCard.stories.d.ts +19 -35
- package/dist/components/PageTitle/PageTitle.d.ts +2 -2
- package/dist/components/SideBar/SideBar.d.ts +4 -3
- package/dist/components/SideBar/Sidebar.stories.d.ts +4 -3
- package/dist/components/Table/Table.d.ts +27 -3
- package/dist/components/Table/Table.stories.d.ts +52 -3
- package/dist/components/Tabs/Tabs.d.ts +43 -56
- package/dist/components/Tabs/Tabs.stories.d.ts +13 -43
- package/dist/components/Thumbnail/Thumbnail.d.ts +49 -6
- package/dist/components/Thumbnail/Thumbnail.stories.d.ts +79 -9
- package/dist/components/TopBar/TopBar.d.ts +64 -4
- package/dist/components/TopBar/TopBar.stories.d.ts +24 -15
- package/dist/components/VerticalStack/VerticalStack.d.ts +38 -0
- package/dist/components/VerticalStack/VerticalStack.stories.d.ts +16 -0
- package/dist/components/index.d.ts +2 -2
- package/dist/index.css +4817 -3507
- package/dist/index.js +5 -5
- package/dist/index.modern.js +5 -5
- package/package.json +1 -1
- package/dist/assets/fonts/Roboto-Bold.ttf +0 -0
- package/dist/assets/fonts/Roboto-Light.ttf +0 -0
- package/dist/assets/fonts/Roboto-Medium.ttf +0 -0
- package/dist/assets/fonts/Roboto-Regular.ttf +0 -0
- package/dist/assets/fonts/roboto-bold.woff +0 -0
- package/dist/assets/fonts/roboto-bold.woff2 +0 -0
- package/dist/assets/fonts/roboto-light.woff +0 -0
- package/dist/assets/fonts/roboto-medium.woff +0 -0
- package/dist/assets/fonts/roboto-medium.woff2 +0 -0
- package/dist/assets/fonts/roboto-regular.woff +0 -0
- package/dist/assets/fonts/roboto-regular.woff2 +0 -0
- package/dist/components/Accordion/Accordian.stories.d.ts +0 -18
- package/dist/components/FlexItem/FlexItem.d.ts +0 -26
- package/dist/components/FlexLayout/FlexLayoutDemo.d.ts +0 -3
- package/dist/components/FlexLayout/FlexLayoutTest.d.ts +0 -3
- package/dist/components/HorizontalFlex/BootstrapStyleTest.d.ts +0 -3
- package/dist/components/HorizontalFlex/ColumnTest.d.ts +0 -3
- package/dist/components/HorizontalFlex/HorizontalFlex.d.ts +0 -30
- package/dist/components/HorizontalFlex/HorizontalFlex.stories.d.ts +0 -44
- package/dist/components/HorizontalFlex/HorizontalFlexTest.d.ts +0 -3
- package/dist/components/HorizontalFlex/StructureTest.d.ts +0 -3
- package/dist/components/Input/CheckboxGroup/CheckboxGroup.d.ts +0 -106
- package/dist/components/Input/CheckboxGroup/CheckboxGroup.stories.d.ts +0 -96
- package/dist/components/Input/RadioGroup/RadioGroup.d.ts +0 -104
- package/dist/components/Input/RadioGroup/RadioGroup.stories.d.ts +0 -96
- package/dist/components/SimpleTest/Simple.stories.d.ts +0 -9
- package/dist/components/SimpleTest/SimpleTest.d.ts +0 -3
- package/dist/components/Template/Template.stories.d.ts +0 -23
- package/dist/components/Template/TemplateDemo.d.ts +0 -4
- package/dist/components/VerticalFlex/VerticalFlex.d.ts +0 -27
- package/dist/components/VerticalFlex/VerticalFlex.stories.d.ts +0 -35
package/README.md
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
# 🚀 Jiffy UI
|
|
1
|
+
# 🚀 Jiffy UI Component Library
|
|
2
2
|
|
|
3
|
-
> A modern,
|
|
3
|
+
> A modern, accessible, and performant React component library built with TypeScript and modern design principles
|
|
4
4
|
|
|
5
5
|
[](https://github.com/JiffytechSolutions/JiffyDemo/blob/master/LICENSE)
|
|
6
6
|
[](https://www.npmjs.com/package/jiffy-ui)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
|
|
9
|
-
**Jiffy UI
|
|
9
|
+
**Jiffy UI** is a comprehensive React component library featuring 50+ production-ready components built with modern web standards, complete TypeScript support, and accessibility-first design principles.
|
|
10
10
|
|
|
11
11
|
## ✨ Features
|
|
12
12
|
|
|
13
13
|
- 🎯 **50+ Production Ready Components** - Comprehensive component library
|
|
14
|
-
- 📝 **TypeScript Native** - Fully typed API with excellent
|
|
15
|
-
- ♿ **Accessibility First** - WAI-ARIA compliant with keyboard support
|
|
16
|
-
- 🚀 **React
|
|
17
|
-
- ⚡ **
|
|
18
|
-
- 📱 **Responsive Design** - Mobile-first approach with
|
|
19
|
-
- 🎨 **
|
|
14
|
+
- 📝 **TypeScript Native** - Fully typed API with excellent developer experience
|
|
15
|
+
- ♿ **Accessibility First** - WAI-ARIA compliant with keyboard navigation support
|
|
16
|
+
- 🚀 **React 18+ Compatible** - Modern React features with Server Components support
|
|
17
|
+
- ⚡ **Performance Optimized** - React.memo, useCallback, and useMemo for optimal performance
|
|
18
|
+
- 📱 **Responsive Design** - Mobile-first approach with adaptive layouts
|
|
19
|
+
- 🎨 **Design System** - Consistent design tokens, colors, and typography
|
|
20
|
+
- 🔧 **Flexible & Extensible** - Customizable components with comprehensive prop interfaces
|
|
21
|
+
- 🧪 **Storybook Integration** - Interactive documentation with live examples
|
|
20
22
|
|
|
21
23
|
## 🚀 Quick Start
|
|
22
24
|
|
|
@@ -30,33 +32,217 @@ npm install jiffy-ui jiffy-icons
|
|
|
30
32
|
|
|
31
33
|
```jsx
|
|
32
34
|
import React from 'react';
|
|
33
|
-
import { Button, Card, TextStyle } from 'jiffy-ui';
|
|
34
|
-
import { ArrowRight } from 'jiffy-icons';
|
|
35
|
+
import { Button, Card, TextStyle, PageTitle } from 'jiffy-ui';
|
|
36
|
+
import { ArrowRight, Share } from 'jiffy-icons';
|
|
35
37
|
|
|
36
38
|
function App() {
|
|
37
39
|
return (
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
Welcome to Jiffy UI
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
<>
|
|
41
|
+
<PageTitle
|
|
42
|
+
title="Welcome to Jiffy UI"
|
|
43
|
+
subtitle="Modern, accessible React component library"
|
|
44
|
+
primaryAction={{
|
|
45
|
+
label: "Get Started",
|
|
46
|
+
variant: "Primary",
|
|
47
|
+
icon: <ArrowRight size={16} />,
|
|
48
|
+
onClick: () => console.log("Getting started!")
|
|
49
|
+
}}
|
|
50
|
+
secondaryActions={[
|
|
51
|
+
{
|
|
52
|
+
id: "share",
|
|
53
|
+
label: "Share",
|
|
54
|
+
leading: <Share size={16} />,
|
|
55
|
+
onClick: () => console.log("Sharing...")
|
|
56
|
+
}
|
|
57
|
+
]}
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
<Card type="Shadow">
|
|
61
|
+
<TextStyle as="h2" type="LgHeading">
|
|
62
|
+
Component Library
|
|
63
|
+
</TextStyle>
|
|
64
|
+
<Button
|
|
65
|
+
color="Primary"
|
|
66
|
+
icon={<ArrowRight size={16} />}
|
|
67
|
+
alignIcon="Right"
|
|
68
|
+
>
|
|
69
|
+
Explore Components
|
|
70
|
+
</Button>
|
|
71
|
+
</Card>
|
|
72
|
+
</>
|
|
50
73
|
);
|
|
51
74
|
}
|
|
52
75
|
```
|
|
53
76
|
|
|
54
77
|
## 🎮 Demo & Documentation
|
|
55
78
|
|
|
56
|
-
🔗 **[Live Demo](https://jiffytechsolutions.github.io/jiffy-ui-demo/)**
|
|
79
|
+
<!-- 🔗 **[Live Demo](https://jiffytechsolutions.github.io/jiffy-ui-demo/)** -->
|
|
57
80
|
|
|
58
81
|
Explore our interactive component playground to see all components in action with live code examples.
|
|
59
82
|
|
|
83
|
+
## 📐 Design Rules & Component Behavior
|
|
84
|
+
|
|
85
|
+
### TypeScript Interface Patterns
|
|
86
|
+
|
|
87
|
+
All components follow consistent TypeScript patterns for maximum developer experience:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
// Standard prop interface structure
|
|
91
|
+
export interface ComponentProps {
|
|
92
|
+
/** Primary content or children */
|
|
93
|
+
children?: React.ReactNode;
|
|
94
|
+
|
|
95
|
+
/** Visual variant */
|
|
96
|
+
variant?: "Primary" | "Secondary" | "Tertiary";
|
|
97
|
+
|
|
98
|
+
/** Size options */
|
|
99
|
+
size?: "Small" | "Medium" | "Large";
|
|
100
|
+
|
|
101
|
+
/** State flags */
|
|
102
|
+
disabled?: boolean;
|
|
103
|
+
loading?: boolean;
|
|
104
|
+
|
|
105
|
+
/** Event handlers */
|
|
106
|
+
onClick?: () => void;
|
|
107
|
+
|
|
108
|
+
/** Styling */
|
|
109
|
+
className?: string;
|
|
110
|
+
style?: React.CSSProperties;
|
|
111
|
+
|
|
112
|
+
/** Testing */
|
|
113
|
+
testId?: string;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Accessibility Standards
|
|
118
|
+
|
|
119
|
+
Every component implements comprehensive accessibility features:
|
|
120
|
+
|
|
121
|
+
- **Keyboard Navigation**: All interactive elements support Tab, Enter, Space, and Arrow keys
|
|
122
|
+
- **ARIA Labels**: Proper `aria-label`, `aria-describedby`, and `role` attributes
|
|
123
|
+
- **Screen Reader Support**: Semantic HTML and descriptive text for assistive technologies
|
|
124
|
+
- **Focus Management**: Visible focus indicators and logical tab order
|
|
125
|
+
- **High Contrast**: Color combinations that meet WCAG AA standards
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
// Example: Accessible button implementation
|
|
129
|
+
<button
|
|
130
|
+
className="jiffy-button"
|
|
131
|
+
onClick={handleClick}
|
|
132
|
+
disabled={disabled}
|
|
133
|
+
aria-label={ariaLabel}
|
|
134
|
+
aria-describedby={description ? `${id}-description` : undefined}
|
|
135
|
+
tabIndex={disabled ? -1 : 0}
|
|
136
|
+
>
|
|
137
|
+
{icon && <span aria-hidden="true">{icon}</span>}
|
|
138
|
+
{children}
|
|
139
|
+
</button>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Responsive Design Principles
|
|
143
|
+
|
|
144
|
+
All components follow mobile-first responsive design:
|
|
145
|
+
|
|
146
|
+
- **Breakpoint System**: `sm: 640px`, `md: 768px`, `lg: 1024px`, `xl: 1280px`
|
|
147
|
+
- **Adaptive Layouts**: Components automatically adjust for screen size
|
|
148
|
+
- **Touch-Friendly**: Minimum 44px touch targets on mobile devices
|
|
149
|
+
- **Content Prioritization**: Important content remains visible on all screen sizes
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
// Example: Responsive component behavior
|
|
153
|
+
<PageTitle
|
|
154
|
+
title="Dashboard"
|
|
155
|
+
subtitle="Overview of your account"
|
|
156
|
+
// On mobile: Actions move to dropdown
|
|
157
|
+
// On desktop: Actions shown inline
|
|
158
|
+
primaryAction={{ label: "Export", variant: "Primary" }}
|
|
159
|
+
secondaryActions={[
|
|
160
|
+
{ id: "share", label: "Share" },
|
|
161
|
+
{ id: "settings", label: "Settings" }
|
|
162
|
+
]}
|
|
163
|
+
/>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Performance Optimization Rules
|
|
167
|
+
|
|
168
|
+
Components are optimized for maximum performance:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// 1. Memoization for expensive calculations
|
|
172
|
+
const memoizedValue = useMemo(() => {
|
|
173
|
+
return expensiveCalculation(data);
|
|
174
|
+
}, [data]);
|
|
175
|
+
|
|
176
|
+
// 2. Callback optimization for event handlers
|
|
177
|
+
const handleClick = useCallback(() => {
|
|
178
|
+
onAction?.();
|
|
179
|
+
}, [onAction]);
|
|
180
|
+
|
|
181
|
+
// 3. Component memoization for stable props
|
|
182
|
+
const OptimizedComponent = React.memo(Component);
|
|
183
|
+
|
|
184
|
+
// 4. Conditional rendering optimization
|
|
185
|
+
{isVisible && <ExpensiveComponent />}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Color System & Design Tokens
|
|
189
|
+
|
|
190
|
+
Consistent color usage across all components:
|
|
191
|
+
|
|
192
|
+
```css
|
|
193
|
+
/* Primary Colors */
|
|
194
|
+
--jiffyui-primary-50: #eff6ff;
|
|
195
|
+
--jiffyui-primary-500: #3b82f6;
|
|
196
|
+
--jiffyui-primary-900: #1e3a8a;
|
|
197
|
+
|
|
198
|
+
/* Semantic Colors */
|
|
199
|
+
--jiffyui-positive: #10b981; /* Success states */
|
|
200
|
+
--jiffyui-negative: #ef4444; /* Error states */
|
|
201
|
+
--jiffyui-notice: #f59e0b; /* Warning states */
|
|
202
|
+
--jiffyui-neutral: #6b7280; /* Neutral content */
|
|
203
|
+
|
|
204
|
+
/* Text Colors */
|
|
205
|
+
--jiffyui-text-primary: #111827; /* Primary text */
|
|
206
|
+
--jiffyui-text-secondary: #6b7280; /* Secondary text */
|
|
207
|
+
--jiffyui-text-muted: #9ca3af; /* Muted text */
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Component Composition Patterns
|
|
211
|
+
|
|
212
|
+
Components are designed for maximum flexibility and composition:
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
// 1. Compound Components
|
|
216
|
+
<Card type="Shadow">
|
|
217
|
+
<Card.Header>
|
|
218
|
+
<PageTitle title="Settings" />
|
|
219
|
+
</Card.Header>
|
|
220
|
+
<Card.Content>
|
|
221
|
+
<FlexLayout direction="column" gap="16px">
|
|
222
|
+
<TextField label="Username" />
|
|
223
|
+
<Button variant="Primary">Save</Button>
|
|
224
|
+
</FlexLayout>
|
|
225
|
+
</Card.Content>
|
|
226
|
+
</Card>
|
|
227
|
+
|
|
228
|
+
// 2. Render Props Pattern
|
|
229
|
+
<ActionList
|
|
230
|
+
items={actions}
|
|
231
|
+
trigger="click"
|
|
232
|
+
>
|
|
233
|
+
<Button variant="Secondary">More Actions</Button>
|
|
234
|
+
</ActionList>
|
|
235
|
+
|
|
236
|
+
// 3. Flexible Layout Composition
|
|
237
|
+
<FlexLayout direction="row" gap="12px" align="center">
|
|
238
|
+
<Avatar src="/user.jpg" />
|
|
239
|
+
<VerticalStack gap="4px">
|
|
240
|
+
<TextStyle type="MdHeading">John Doe</TextStyle>
|
|
241
|
+
<TextStyle type="SmBody" color="muted">Product Manager</TextStyle>
|
|
242
|
+
</VerticalStack>
|
|
243
|
+
</FlexLayout>
|
|
244
|
+
```
|
|
245
|
+
|
|
60
246
|
## 📦 Available Components
|
|
61
247
|
|
|
62
248
|
### 🏗️ Layout & Structure
|
|
@@ -67,14 +253,14 @@ Explore our interactive component playground to see all components in action wit
|
|
|
67
253
|
- **Divider** - Visual separator for content sections
|
|
68
254
|
|
|
69
255
|
### 🧭 Navigation & Actions
|
|
70
|
-
- **Button** - Primary interactive element with multiple variants
|
|
71
|
-
- **ButtonGroup** - Group related buttons
|
|
72
|
-
- **ActionList** -
|
|
73
|
-
- **PageTitle** -
|
|
74
|
-
- **Breadcrumb** - Navigation breadcrumb trail
|
|
75
|
-
- **Pagination** - Navigate through paginated content
|
|
76
|
-
- **Tabs** - Tabbed interface
|
|
77
|
-
- **TextLink** - Styled text links and navigation
|
|
256
|
+
- **Button** - Primary interactive element with multiple variants and accessibility features
|
|
257
|
+
- **ButtonGroup** - Group related buttons with consistent spacing and alignment
|
|
258
|
+
- **ActionList** - Performance-optimized dropdown menu with keyboard navigation *(Recently Updated)*
|
|
259
|
+
- **PageTitle** - Modern page header with integrated actions and responsive behavior *(Recently Redesigned)*
|
|
260
|
+
- **Breadcrumb** - Navigation breadcrumb trail with overflow handling
|
|
261
|
+
- **Pagination** - Navigate through paginated content with accessibility support
|
|
262
|
+
- **Tabs** - Tabbed interface with keyboard navigation and ARIA support
|
|
263
|
+
- **TextLink** - Styled text links with proper focus states and navigation
|
|
78
264
|
|
|
79
265
|
### 📝 Form Controls & Input
|
|
80
266
|
- **TextField** - Text input with validation and multiple states
|
|
@@ -138,6 +324,270 @@ Explore our interactive component playground to see all components in action wit
|
|
|
138
324
|
### 🧪 Development & Testing
|
|
139
325
|
- **SimpleTest** - Simple test component for development
|
|
140
326
|
|
|
327
|
+
## 💡 Component Usage Examples
|
|
328
|
+
|
|
329
|
+
### PageTitle Component - Modern Page Headers
|
|
330
|
+
|
|
331
|
+
The redesigned PageTitle component provides clean, accessible page headers:
|
|
332
|
+
|
|
333
|
+
```tsx
|
|
334
|
+
import { PageTitle } from 'jiffy-ui';
|
|
335
|
+
import { Save, Share, Download, Settings } from 'react-feather';
|
|
336
|
+
|
|
337
|
+
// Basic page title
|
|
338
|
+
<PageTitle
|
|
339
|
+
title="Document Editor"
|
|
340
|
+
subtitle="Create and edit documents collaboratively"
|
|
341
|
+
/>
|
|
342
|
+
|
|
343
|
+
// Page title with navigation and actions
|
|
344
|
+
<PageTitle
|
|
345
|
+
title="User Settings"
|
|
346
|
+
subtitle="Manage your account preferences"
|
|
347
|
+
showBackButton={true}
|
|
348
|
+
onBackClick={() => navigate('/dashboard')}
|
|
349
|
+
|
|
350
|
+
primaryAction={{
|
|
351
|
+
label: "Save Changes",
|
|
352
|
+
variant: "Primary",
|
|
353
|
+
onClick: handleSave,
|
|
354
|
+
loading: isSaving
|
|
355
|
+
}}
|
|
356
|
+
|
|
357
|
+
secondaryActions={[
|
|
358
|
+
{
|
|
359
|
+
id: "export",
|
|
360
|
+
label: "Export Settings",
|
|
361
|
+
leading: <Download size={16} />,
|
|
362
|
+
description: "Download settings as JSON",
|
|
363
|
+
onClick: handleExport
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
id: "share",
|
|
367
|
+
label: "Share Profile",
|
|
368
|
+
leading: <Share size={16} />,
|
|
369
|
+
onClick: handleShare
|
|
370
|
+
}
|
|
371
|
+
]}
|
|
372
|
+
|
|
373
|
+
badge={{ text: "Premium", color: "Primary" }}
|
|
374
|
+
/>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### ActionList Component - Performance Optimized Dropdowns
|
|
378
|
+
|
|
379
|
+
Improved ActionList with infinite loop prevention and optimized rendering:
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
import { ActionList, Button } from 'jiffy-ui';
|
|
383
|
+
import { Edit, Trash2, Copy, Star } from 'react-feather';
|
|
384
|
+
|
|
385
|
+
<ActionList
|
|
386
|
+
items={[
|
|
387
|
+
{
|
|
388
|
+
id: "edit",
|
|
389
|
+
label: "Edit Document",
|
|
390
|
+
leading: <Edit size={16} />,
|
|
391
|
+
description: "Modify document content",
|
|
392
|
+
onClick: () => handleEdit()
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
id: "duplicate",
|
|
396
|
+
label: "Duplicate",
|
|
397
|
+
leading: <Copy size={16} />,
|
|
398
|
+
onClick: () => handleDuplicate()
|
|
399
|
+
},
|
|
400
|
+
{ type: "separator" },
|
|
401
|
+
{
|
|
402
|
+
id: "favorite",
|
|
403
|
+
label: "Add to Favorites",
|
|
404
|
+
leading: <Star size={16} />,
|
|
405
|
+
onClick: () => handleFavorite()
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: "delete",
|
|
409
|
+
label: "Delete",
|
|
410
|
+
leading: <Trash2 size={16} />,
|
|
411
|
+
variant: "destructive",
|
|
412
|
+
onClick: () => handleDelete()
|
|
413
|
+
}
|
|
414
|
+
]}
|
|
415
|
+
trigger="click"
|
|
416
|
+
placement="bottom-start"
|
|
417
|
+
variant="Bordered"
|
|
418
|
+
>
|
|
419
|
+
<Button variant="Secondary">Document Actions</Button>
|
|
420
|
+
</ActionList>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Responsive Table Component
|
|
424
|
+
|
|
425
|
+
Tables that adapt to different screen sizes with mobile-friendly behavior:
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
import { Table, Badge, Button } from 'jiffy-ui';
|
|
429
|
+
|
|
430
|
+
<Table
|
|
431
|
+
variant="bordered"
|
|
432
|
+
responsive={true}
|
|
433
|
+
stackOnMobile={true}
|
|
434
|
+
stickyHeader={true}
|
|
435
|
+
density="comfortable"
|
|
436
|
+
|
|
437
|
+
columns={[
|
|
438
|
+
{ key: "id", title: "Order ID", sortable: true },
|
|
439
|
+
{ key: "customer", title: "Customer", sortable: true },
|
|
440
|
+
{ key: "status", title: "Status", width: "120px" },
|
|
441
|
+
{ key: "total", title: "Total", align: "right", sortable: true },
|
|
442
|
+
{ key: "actions", title: "Actions", width: "100px" }
|
|
443
|
+
]}
|
|
444
|
+
|
|
445
|
+
data={orders.map(order => ({
|
|
446
|
+
id: order.id,
|
|
447
|
+
customer: order.customerName,
|
|
448
|
+
status: (
|
|
449
|
+
<Badge
|
|
450
|
+
color={order.status === 'completed' ? 'Positive' : 'Notice'}
|
|
451
|
+
emphasis="Intense"
|
|
452
|
+
>
|
|
453
|
+
{order.status}
|
|
454
|
+
</Badge>
|
|
455
|
+
),
|
|
456
|
+
total: `$${order.total.toFixed(2)}`,
|
|
457
|
+
actions: (
|
|
458
|
+
<Button variant="Ghost" size="Small">
|
|
459
|
+
View Details
|
|
460
|
+
</Button>
|
|
461
|
+
)
|
|
462
|
+
}))}
|
|
463
|
+
/>
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Form Layout with Validation
|
|
467
|
+
|
|
468
|
+
Comprehensive form layouts with proper spacing and validation:
|
|
469
|
+
|
|
470
|
+
```tsx
|
|
471
|
+
import {
|
|
472
|
+
Card,
|
|
473
|
+
FlexLayout,
|
|
474
|
+
VerticalStack,
|
|
475
|
+
TextField,
|
|
476
|
+
TextArea,
|
|
477
|
+
Select,
|
|
478
|
+
Button,
|
|
479
|
+
Alert
|
|
480
|
+
} from 'jiffy-ui';
|
|
481
|
+
|
|
482
|
+
<Card type="Shadow">
|
|
483
|
+
<VerticalStack gap="24px">
|
|
484
|
+
<PageTitle
|
|
485
|
+
title="Create New Project"
|
|
486
|
+
subtitle="Set up your project configuration"
|
|
487
|
+
/>
|
|
488
|
+
|
|
489
|
+
{error && (
|
|
490
|
+
<Alert variant="Negative" title="Validation Error">
|
|
491
|
+
Please fix the errors below before proceeding.
|
|
492
|
+
</Alert>
|
|
493
|
+
)}
|
|
494
|
+
|
|
495
|
+
<FlexLayout direction="column" gap="16px">
|
|
496
|
+
<TextField
|
|
497
|
+
label="Project Name"
|
|
498
|
+
placeholder="Enter project name"
|
|
499
|
+
value={projectName}
|
|
500
|
+
onChange={setProjectName}
|
|
501
|
+
error={errors.projectName}
|
|
502
|
+
required
|
|
503
|
+
/>
|
|
504
|
+
|
|
505
|
+
<TextArea
|
|
506
|
+
label="Description"
|
|
507
|
+
placeholder="Describe your project..."
|
|
508
|
+
value={description}
|
|
509
|
+
onChange={setDescription}
|
|
510
|
+
rows={4}
|
|
511
|
+
/>
|
|
512
|
+
|
|
513
|
+
<Select
|
|
514
|
+
label="Project Type"
|
|
515
|
+
value={projectType}
|
|
516
|
+
onChange={setProjectType}
|
|
517
|
+
options={[
|
|
518
|
+
{ value: "web", label: "Web Application" },
|
|
519
|
+
{ value: "mobile", label: "Mobile App" },
|
|
520
|
+
{ value: "desktop", label: "Desktop Application" }
|
|
521
|
+
]}
|
|
522
|
+
/>
|
|
523
|
+
</FlexLayout>
|
|
524
|
+
|
|
525
|
+
<FlexLayout direction="row" gap="12px" justify="flex-end">
|
|
526
|
+
<Button variant="Secondary" onClick={handleCancel}>
|
|
527
|
+
Cancel
|
|
528
|
+
</Button>
|
|
529
|
+
<Button
|
|
530
|
+
variant="Primary"
|
|
531
|
+
onClick={handleSubmit}
|
|
532
|
+
loading={isSubmitting}
|
|
533
|
+
>
|
|
534
|
+
Create Project
|
|
535
|
+
</Button>
|
|
536
|
+
</FlexLayout>
|
|
537
|
+
</VerticalStack>
|
|
538
|
+
</Card>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Media Cards with Actions
|
|
542
|
+
|
|
543
|
+
Rich media content cards with integrated actions:
|
|
544
|
+
|
|
545
|
+
```tsx
|
|
546
|
+
import { MediaCard, Badge, ActionList } from 'jiffy-ui';
|
|
547
|
+
import { Play, Download, Share, MoreHorizontal } from 'react-feather';
|
|
548
|
+
|
|
549
|
+
<MediaCard
|
|
550
|
+
type="Shadow"
|
|
551
|
+
orientation="Vertical"
|
|
552
|
+
mediaSrc="/video-thumbnail.jpg"
|
|
553
|
+
title="Introduction to React Hooks"
|
|
554
|
+
subtitle={
|
|
555
|
+
<FlexLayout direction="row" gap="8px" align="center">
|
|
556
|
+
<Badge color="Primary" size="Small">Tutorial</Badge>
|
|
557
|
+
<span>45 minutes</span>
|
|
558
|
+
</FlexLayout>
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
primaryAction={{
|
|
562
|
+
label: "Play Video",
|
|
563
|
+
variant: "Primary",
|
|
564
|
+
icon: <Play size={16} />,
|
|
565
|
+
onClick: () => playVideo()
|
|
566
|
+
}}
|
|
567
|
+
|
|
568
|
+
secondaryAction={{
|
|
569
|
+
label: "Download",
|
|
570
|
+
variant: "Secondary",
|
|
571
|
+
icon: <Download size={16} />,
|
|
572
|
+
onClick: () => downloadVideo()
|
|
573
|
+
}}
|
|
574
|
+
|
|
575
|
+
headerActions={[
|
|
576
|
+
{
|
|
577
|
+
id: "share",
|
|
578
|
+
label: "Share Video",
|
|
579
|
+
leading: <Share size={16} />,
|
|
580
|
+
onClick: () => shareVideo()
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
id: "add-playlist",
|
|
584
|
+
label: "Add to Playlist",
|
|
585
|
+
onClick: () => addToPlaylist()
|
|
586
|
+
}
|
|
587
|
+
]}
|
|
588
|
+
/>
|
|
589
|
+
```
|
|
590
|
+
|
|
141
591
|
## 🛠️ Development
|
|
142
592
|
|
|
143
593
|
### Prerequisites
|
|
@@ -163,41 +613,245 @@ npm start
|
|
|
163
613
|
|
|
164
614
|
### Available Scripts
|
|
165
615
|
|
|
166
|
-
- `npm start` - Start development server
|
|
167
|
-
- `npm build` - Build for production
|
|
168
|
-
- `npm test` - Run test suite
|
|
169
|
-
- `npm
|
|
616
|
+
- `npm start` - Start development server with Rollup watch mode
|
|
617
|
+
- `npm build` - Build component library for production
|
|
618
|
+
- `npm test` - Run test suite with React Testing Library
|
|
619
|
+
- `npm run storybook` - Start Storybook development server
|
|
620
|
+
- `npm run build-storybook` - Build Storybook for production deployment
|
|
621
|
+
|
|
622
|
+
### Building Components
|
|
623
|
+
|
|
624
|
+
Follow these guidelines when contributing new components:
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
# 1. Create component structure
|
|
628
|
+
mkdir src/components/NewComponent
|
|
629
|
+
cd src/components/NewComponent
|
|
630
|
+
|
|
631
|
+
# 2. Create required files
|
|
632
|
+
touch NewComponent.tsx # Main component file
|
|
633
|
+
touch NewComponent.css # Component styles
|
|
634
|
+
touch NewComponent.stories.tsx # Storybook stories
|
|
635
|
+
|
|
636
|
+
# 3. Follow naming conventions
|
|
637
|
+
# - PascalCase for component names
|
|
638
|
+
# - Consistent prop interface naming (ComponentProps)
|
|
639
|
+
# - CSS classes with component prefix (newcomponent-*)
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
|
|
170
643
|
|
|
644
|
+
## 🎯 Best Practices & Guidelines
|
|
171
645
|
|
|
646
|
+
### Component Development Principles
|
|
647
|
+
|
|
648
|
+
**1. Accessibility First**
|
|
649
|
+
```tsx
|
|
650
|
+
// Always include proper ARIA attributes
|
|
651
|
+
<button
|
|
652
|
+
className="jiffy-button"
|
|
653
|
+
aria-label={ariaLabel}
|
|
654
|
+
aria-describedby={hasDescription ? `${id}-description` : undefined}
|
|
655
|
+
aria-pressed={isPressed}
|
|
656
|
+
tabIndex={disabled ? -1 : 0}
|
|
657
|
+
>
|
|
658
|
+
{children}
|
|
659
|
+
</button>
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**2. Performance Optimization**
|
|
663
|
+
```tsx
|
|
664
|
+
// Use React.memo for components with stable props
|
|
665
|
+
const OptimizedComponent = React.memo(({ items, onSelect }) => {
|
|
666
|
+
// Use useMemo for expensive calculations
|
|
667
|
+
const processedItems = useMemo(() => {
|
|
668
|
+
return items.map(item => processItem(item));
|
|
669
|
+
}, [items]);
|
|
670
|
+
|
|
671
|
+
// Use useCallback for stable event handlers
|
|
672
|
+
const handleSelect = useCallback((id) => {
|
|
673
|
+
onSelect?.(id);
|
|
674
|
+
}, [onSelect]);
|
|
172
675
|
|
|
173
|
-
|
|
676
|
+
return (
|
|
677
|
+
<div>
|
|
678
|
+
{processedItems.map(item => (
|
|
679
|
+
<Item key={item.id} onSelect={handleSelect} />
|
|
680
|
+
))}
|
|
681
|
+
</div>
|
|
682
|
+
);
|
|
683
|
+
});
|
|
684
|
+
```
|
|
174
685
|
|
|
175
|
-
|
|
686
|
+
**3. TypeScript Best Practices**
|
|
176
687
|
```tsx
|
|
177
|
-
interface
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
688
|
+
// Use consistent prop interface patterns
|
|
689
|
+
export interface ComponentProps {
|
|
690
|
+
/** Primary prop with clear description */
|
|
691
|
+
children?: React.ReactNode;
|
|
692
|
+
|
|
693
|
+
/** Use union types for variants */
|
|
694
|
+
variant?: "Primary" | "Secondary" | "Tertiary";
|
|
695
|
+
|
|
696
|
+
/** Optional props with defaults in implementation */
|
|
697
|
+
size?: "Small" | "Medium" | "Large";
|
|
698
|
+
|
|
699
|
+
/** Event handlers with proper typing */
|
|
700
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
701
|
+
|
|
702
|
+
/** Extend HTML attributes when appropriate */
|
|
703
|
+
className?: string;
|
|
704
|
+
style?: React.CSSProperties;
|
|
705
|
+
|
|
706
|
+
/** Test identifiers for automation */
|
|
707
|
+
testId?: string;
|
|
182
708
|
}
|
|
183
709
|
```
|
|
184
710
|
|
|
185
|
-
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
711
|
+
**4. Responsive Design Guidelines**
|
|
712
|
+
```tsx
|
|
713
|
+
// Follow mobile-first approach
|
|
714
|
+
<div className="component">
|
|
715
|
+
{/* Mobile: Stack vertically */}
|
|
716
|
+
<div className="component-mobile">
|
|
717
|
+
<ActionList items={actions} trigger="click">
|
|
718
|
+
<Button>Actions</Button>
|
|
719
|
+
</ActionList>
|
|
720
|
+
</div>
|
|
721
|
+
|
|
722
|
+
{/* Desktop: Show inline */}
|
|
723
|
+
<div className="component-desktop hidden md:flex">
|
|
724
|
+
{actions.map(action => (
|
|
725
|
+
<Button key={action.id} onClick={action.onClick}>
|
|
726
|
+
{action.label}
|
|
727
|
+
</Button>
|
|
728
|
+
))}
|
|
729
|
+
</div>
|
|
730
|
+
</div>
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
**5. Error Handling & Loading States**
|
|
734
|
+
```tsx
|
|
735
|
+
const DataComponent = ({ onLoad, onError }) => {
|
|
736
|
+
const [loading, setLoading] = useState(false);
|
|
737
|
+
const [error, setError] = useState(null);
|
|
738
|
+
const [data, setData] = useState(null);
|
|
739
|
+
|
|
740
|
+
return (
|
|
741
|
+
<>
|
|
742
|
+
{error && (
|
|
743
|
+
<Alert variant="Negative" title="Error Loading Data">
|
|
744
|
+
{error.message}
|
|
745
|
+
</Alert>
|
|
746
|
+
)}
|
|
747
|
+
|
|
748
|
+
{loading ? (
|
|
749
|
+
<Skeleton type="list" />
|
|
750
|
+
) : (
|
|
751
|
+
<Table data={data} loading={loading} />
|
|
752
|
+
)}
|
|
753
|
+
</>
|
|
754
|
+
);
|
|
755
|
+
};
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Testing Guidelines
|
|
759
|
+
|
|
760
|
+
**Component Testing with React Testing Library**
|
|
761
|
+
```tsx
|
|
762
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
763
|
+
import userEvent from '@testing-library/user-event';
|
|
764
|
+
import Button from './Button';
|
|
765
|
+
|
|
766
|
+
describe('Button Component', () => {
|
|
767
|
+
test('renders with correct accessibility attributes', () => {
|
|
768
|
+
render(
|
|
769
|
+
<Button variant="Primary" testId="test-button">
|
|
770
|
+
Click me
|
|
771
|
+
</Button>
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
const button = screen.getByTestId('test-button');
|
|
775
|
+
expect(button).toHaveAttribute('type', 'button');
|
|
776
|
+
expect(button).toHaveAccessibleName('Click me');
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
test('handles keyboard navigation', async () => {
|
|
780
|
+
const handleClick = jest.fn();
|
|
781
|
+
render(<Button onClick={handleClick}>Click me</Button>);
|
|
782
|
+
|
|
783
|
+
const button = screen.getByRole('button');
|
|
784
|
+
|
|
785
|
+
// Test keyboard activation
|
|
786
|
+
await userEvent.type(button, '{enter}');
|
|
787
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
788
|
+
|
|
789
|
+
await userEvent.type(button, ' ');
|
|
790
|
+
expect(handleClick).toHaveBeenCalledTimes(2);
|
|
791
|
+
});
|
|
792
|
+
});
|
|
192
793
|
```
|
|
193
794
|
|
|
194
|
-
###
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
795
|
+
### Storybook Documentation
|
|
796
|
+
|
|
797
|
+
**Create Comprehensive Stories**
|
|
798
|
+
```tsx
|
|
799
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
800
|
+
import Component from './Component';
|
|
801
|
+
|
|
802
|
+
const meta: Meta<typeof Component> = {
|
|
803
|
+
title: 'Components/Component',
|
|
804
|
+
component: Component,
|
|
805
|
+
parameters: {
|
|
806
|
+
docs: {
|
|
807
|
+
description: {
|
|
808
|
+
component: `
|
|
809
|
+
A comprehensive component that demonstrates all the design principles
|
|
810
|
+
and accessibility features of the Jiffy UI library.
|
|
811
|
+
|
|
812
|
+
## Features
|
|
813
|
+
- ✅ Fully accessible with ARIA support
|
|
814
|
+
- ✅ Responsive design with mobile-first approach
|
|
815
|
+
- ✅ Performance optimized with React.memo
|
|
816
|
+
- ✅ TypeScript native with complete type safety
|
|
817
|
+
`
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
argTypes: {
|
|
822
|
+
variant: {
|
|
823
|
+
control: { type: 'select' },
|
|
824
|
+
options: ['Primary', 'Secondary', 'Tertiary'],
|
|
825
|
+
description: 'Visual variant of the component'
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
export default meta;
|
|
831
|
+
type Story = StoryObj<typeof Component>;
|
|
832
|
+
|
|
833
|
+
// Default story
|
|
834
|
+
export const Default: Story = {
|
|
835
|
+
args: {
|
|
836
|
+
children: 'Component content'
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// Accessibility demonstration
|
|
841
|
+
export const AccessibilityDemo: Story = {
|
|
842
|
+
args: {
|
|
843
|
+
children: 'Accessible component',
|
|
844
|
+
'aria-label': 'Descriptive label for screen readers'
|
|
845
|
+
},
|
|
846
|
+
parameters: {
|
|
847
|
+
docs: {
|
|
848
|
+
description: {
|
|
849
|
+
story: 'This story demonstrates proper accessibility implementation.'
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
```
|
|
201
855
|
|
|
202
856
|
## 🤝 Contributing
|
|
203
857
|
|
|
@@ -215,24 +869,51 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
|
|
|
215
869
|
|
|
216
870
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
217
871
|
|
|
872
|
+
## 📊 Component Library Stats
|
|
873
|
+
|
|
874
|
+
- **50+ Components**: Comprehensive coverage of UI patterns
|
|
875
|
+
- **100% TypeScript**: Full type safety and excellent IntelliSense
|
|
876
|
+
- **Accessibility Compliant**: WCAG 2.1 AA standards
|
|
877
|
+
- **Performance Optimized**: React.memo, lazy loading, and code splitting
|
|
878
|
+
- **Mobile-First**: Responsive design for all screen sizes
|
|
879
|
+
- **Tree Shakeable**: Import only what you need
|
|
880
|
+
- **Production Ready**: Used in enterprise applications
|
|
881
|
+
|
|
218
882
|
## 🙏 Acknowledgments
|
|
219
883
|
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
-
|
|
884
|
+
- **React Team**: For the amazing React library and ecosystem
|
|
885
|
+
- **TypeScript Team**: For bringing type safety to JavaScript
|
|
886
|
+
- **Storybook Team**: For the excellent component development environment
|
|
887
|
+
- **React Testing Library**: For promoting accessible testing practices
|
|
888
|
+
- **Rollup**: For efficient module bundling
|
|
889
|
+
- **Community Contributors**: For feedback, bug reports, and feature requests
|
|
890
|
+
|
|
891
|
+
## 📞 Support & Community
|
|
892
|
+
|
|
893
|
+
- 📧 **Email**: support@jiffytech.com
|
|
894
|
+
- 🐛 **Issues**: [GitHub Issues](https://github.com/JiffytechSolutions/JiffyDemo/issues)
|
|
895
|
+
- 💬 **Discussions**: [GitHub Discussions](https://github.com/JiffytechSolutions/JiffyDemo/discussions)
|
|
896
|
+
- 📖 **Documentation**: [Component Documentation](https://jiffytechsolutions.github.io/jiffy-ui-demo/)
|
|
897
|
+
- 🎮 **Live Demo**: [Interactive Playground](https://jiffytechsolutions.github.io/jiffy-ui-demo/)
|
|
223
898
|
|
|
224
|
-
##
|
|
899
|
+
## 🏷️ Versioning & Releases
|
|
225
900
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
-
|
|
901
|
+
We follow [Semantic Versioning](https://semver.org/) for our releases:
|
|
902
|
+
|
|
903
|
+
- **Major** (`x.0.0`): Breaking changes requiring migration
|
|
904
|
+
- **Minor** (`0.x.0`): New features and components, backward compatible
|
|
905
|
+
- **Patch** (`0.0.x`): Bug fixes and performance improvements
|
|
906
|
+
|
|
907
|
+
Check our [Release Notes](https://github.com/JiffytechSolutions/jiffy-ui/releases) for detailed changelogs.
|
|
229
908
|
|
|
230
909
|
---
|
|
231
910
|
|
|
232
911
|
<div align="center">
|
|
233
912
|
|
|
234
|
-
**[🚀 Get Started](https://jiffytechsolutions.github.io/
|
|
913
|
+
**[🚀 Get Started](https://jiffytechsolutions.github.io/jiffy-ui-demo/)** • **[📚 Documentation](https://jiffytechsolutions.github.io/jiffy-ui-demo/storybook/)** • **[🎮 Live Demo](https://jiffytechsolutions.github.io/jiffy-ui-demo/)** • **[📦 NPM Package](https://www.npmjs.com/package/jiffy-ui)**
|
|
914
|
+
|
|
915
|
+
Made with ❤️ by the **Jiffy Tech Solutions** team
|
|
235
916
|
|
|
236
|
-
|
|
917
|
+
*Building the future of React component libraries, one component at a time.*
|
|
237
918
|
|
|
238
919
|
</div>
|