@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.3 → 0.1.5

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 (164) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +131 -131
  3. package/dist/index.esm.js +148 -148
  4. package/dist/index.js +148 -148
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/components/ui/accessibility-demo.tsx +271 -0
  8. package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
  9. package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
  10. package/src/components/ui/advanced-transition-system.tsx +395 -0
  11. package/src/components/ui/animation/animated-container.tsx +166 -0
  12. package/src/components/ui/animation/index.ts +19 -0
  13. package/src/components/ui/animation/staggered-container.tsx +68 -0
  14. package/src/components/ui/animation-demo.tsx +250 -0
  15. package/src/components/ui/badge.tsx +33 -0
  16. package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
  17. package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
  18. package/src/components/ui/button.tsx +36 -0
  19. package/src/components/ui/card.tsx +207 -0
  20. package/src/components/ui/checkbox.tsx +30 -0
  21. package/src/components/ui/color-preview.tsx +411 -0
  22. package/src/components/ui/data-display/chart.tsx +653 -0
  23. package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
  24. package/src/components/ui/data-display/data-grid.tsx +680 -0
  25. package/src/components/ui/data-display/list.tsx +456 -0
  26. package/src/components/ui/data-display/table.tsx +482 -0
  27. package/src/components/ui/data-display/timeline.tsx +441 -0
  28. package/src/components/ui/data-display/tree.tsx +602 -0
  29. package/src/components/ui/data-display/types.ts +536 -0
  30. package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
  31. package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
  32. package/src/components/ui/feedback/alert.tsx +157 -0
  33. package/src/components/ui/feedback/progress.tsx +292 -0
  34. package/src/components/ui/feedback/skeleton.tsx +185 -0
  35. package/src/components/ui/feedback/toast.tsx +280 -0
  36. package/src/components/ui/feedback/types.ts +125 -0
  37. package/src/components/ui/font-preview.tsx +288 -0
  38. package/src/components/ui/form-demo.tsx +553 -0
  39. package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
  40. package/src/components/ui/input.tsx +35 -0
  41. package/src/components/ui/label.tsx +16 -0
  42. package/src/components/ui/layout-demo.tsx +367 -0
  43. package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
  44. package/src/components/ui/layouts/desktop-layout.tsx +224 -0
  45. package/src/components/ui/layouts/index.ts +10 -0
  46. package/src/components/ui/layouts/mobile-layout.tsx +162 -0
  47. package/src/components/ui/layouts/tablet-layout.tsx +197 -0
  48. package/src/components/ui/mobile-form-validation.tsx +451 -0
  49. package/src/components/ui/mobile-input-demo.tsx +201 -0
  50. package/src/components/ui/mobile-input.tsx +281 -0
  51. package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
  52. package/src/components/ui/navigation/breadcrumb.tsx +158 -0
  53. package/src/components/ui/navigation/index.ts +36 -0
  54. package/src/components/ui/navigation/menu.tsx +374 -0
  55. package/src/components/ui/navigation/navigation-demo.tsx +324 -0
  56. package/src/components/ui/navigation/pagination.tsx +272 -0
  57. package/src/components/ui/navigation/sidebar.tsx +383 -0
  58. package/src/components/ui/navigation/stepper.tsx +303 -0
  59. package/src/components/ui/navigation/tabs.tsx +205 -0
  60. package/src/components/ui/navigation/types.ts +299 -0
  61. package/src/components/ui/overlay/backdrop.tsx +81 -0
  62. package/src/components/ui/overlay/focus-manager.tsx +143 -0
  63. package/src/components/ui/overlay/index.ts +36 -0
  64. package/src/components/ui/overlay/modal.tsx +270 -0
  65. package/src/components/ui/overlay/overlay-manager.tsx +110 -0
  66. package/src/components/ui/overlay/popover.tsx +462 -0
  67. package/src/components/ui/overlay/portal.tsx +79 -0
  68. package/src/components/ui/overlay/tooltip.tsx +303 -0
  69. package/src/components/ui/overlay/types.ts +196 -0
  70. package/src/components/ui/performance-demo.tsx +596 -0
  71. package/src/components/ui/semantic-input-system-demo.tsx +502 -0
  72. package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
  73. package/src/components/ui/tablet-layout.tsx +192 -0
  74. package/src/components/ui/theme-customizer.tsx +386 -0
  75. package/src/components/ui/theme-preview.tsx +310 -0
  76. package/src/components/ui/theme-switcher.tsx +264 -0
  77. package/src/components/ui/theme-toggle.tsx +38 -0
  78. package/src/components/ui/token-demo.tsx +195 -0
  79. package/src/components/ui/touch-demo.tsx +462 -0
  80. package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
  81. package/src/components/ui/touch-friendly-interface.tsx +296 -0
  82. package/src/hooks/index.ts +190 -0
  83. package/src/hooks/use-accessibility-support.ts +518 -0
  84. package/src/hooks/use-adaptive-layout.ts +289 -0
  85. package/src/hooks/use-advanced-patterns.ts +294 -0
  86. package/src/hooks/use-advanced-transition-system.ts +393 -0
  87. package/src/hooks/use-animation-profile.ts +288 -0
  88. package/src/hooks/use-battery-animations.ts +384 -0
  89. package/src/hooks/use-battery-conscious-loading.ts +475 -0
  90. package/src/hooks/use-battery-optimization.ts +330 -0
  91. package/src/hooks/use-battery-status.ts +299 -0
  92. package/src/hooks/use-component-performance.ts +344 -0
  93. package/src/hooks/use-device-loading-states.ts +459 -0
  94. package/src/hooks/use-device.tsx +110 -0
  95. package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
  96. package/src/hooks/use-form-feedback.ts +403 -0
  97. package/src/hooks/use-form-performance.ts +513 -0
  98. package/src/hooks/use-frame-rate.ts +251 -0
  99. package/src/hooks/use-gestures.ts +338 -0
  100. package/src/hooks/use-hardware-acceleration.ts +341 -0
  101. package/src/hooks/use-input-accessibility.ts +455 -0
  102. package/src/hooks/use-input-performance.ts +506 -0
  103. package/src/hooks/use-layout-performance.ts +319 -0
  104. package/src/hooks/use-loading-accessibility.ts +535 -0
  105. package/src/hooks/use-loading-performance.ts +473 -0
  106. package/src/hooks/use-memory-usage.ts +287 -0
  107. package/src/hooks/use-mobile-form-layout.ts +464 -0
  108. package/src/hooks/use-mobile-form-validation.ts +518 -0
  109. package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
  110. package/src/hooks/use-mobile-layout.ts +302 -0
  111. package/src/hooks/use-mobile-optimization.ts +406 -0
  112. package/src/hooks/use-mobile-skeleton.ts +402 -0
  113. package/src/hooks/use-mobile-touch.ts +414 -0
  114. package/src/hooks/use-performance-throttling.ts +348 -0
  115. package/src/hooks/use-performance.ts +316 -0
  116. package/src/hooks/use-reusable-architecture.ts +414 -0
  117. package/src/hooks/use-semantic-input-types.ts +357 -0
  118. package/src/hooks/use-semantic-input.ts +565 -0
  119. package/src/hooks/use-tablet-layout.ts +384 -0
  120. package/src/hooks/use-touch-friendly-input.ts +524 -0
  121. package/src/hooks/use-touch-friendly-interface.ts +331 -0
  122. package/src/hooks/use-touch-optimization.ts +375 -0
  123. package/src/index.ts +279 -279
  124. package/src/lib/utils.ts +6 -0
  125. package/src/themes/README.md +272 -0
  126. package/src/themes/ThemeContext.tsx +31 -0
  127. package/src/themes/ThemeProvider.tsx +232 -0
  128. package/src/themes/accessibility/index.ts +27 -0
  129. package/src/themes/accessibility.ts +259 -0
  130. package/src/themes/aria-patterns.ts +420 -0
  131. package/src/themes/base-themes.ts +55 -0
  132. package/src/themes/colorManager.ts +380 -0
  133. package/src/themes/examples/dark-theme.ts +154 -0
  134. package/src/themes/examples/minimal-theme.ts +108 -0
  135. package/src/themes/focus-management.ts +701 -0
  136. package/src/themes/fontLoader.ts +201 -0
  137. package/src/themes/high-contrast.ts +621 -0
  138. package/src/themes/index.ts +19 -0
  139. package/src/themes/inheritance.ts +227 -0
  140. package/src/themes/keyboard-navigation.ts +550 -0
  141. package/src/themes/motion-reduction.ts +662 -0
  142. package/src/themes/navigation.ts +238 -0
  143. package/src/themes/screen-reader.ts +645 -0
  144. package/src/themes/systemThemeDetector.ts +182 -0
  145. package/src/themes/themeCSSUpdater.ts +262 -0
  146. package/src/themes/themePersistence.ts +238 -0
  147. package/src/themes/themes/default.ts +586 -0
  148. package/src/themes/themes/harvey.ts +554 -0
  149. package/src/themes/themes/stan-design.ts +683 -0
  150. package/src/themes/types.ts +460 -0
  151. package/src/themes/useSystemTheme.ts +48 -0
  152. package/src/themes/useTheme.ts +87 -0
  153. package/src/themes/validation.ts +462 -0
  154. package/src/tokens/index.ts +34 -0
  155. package/src/tokens/tokenExporter.ts +397 -0
  156. package/src/tokens/tokenGenerator.ts +276 -0
  157. package/src/tokens/tokenManager.ts +248 -0
  158. package/src/tokens/tokenValidator.ts +543 -0
  159. package/src/tokens/types.ts +78 -0
  160. package/src/utils/bundle-analyzer.ts +260 -0
  161. package/src/utils/bundle-splitting.ts +483 -0
  162. package/src/utils/lazy-loading.ts +441 -0
  163. package/src/utils/performance-monitor.ts +513 -0
  164. package/src/utils/tree-shaking.ts +274 -0
@@ -0,0 +1,441 @@
1
+ import React, { useState, useMemo } from 'react';
2
+ import {
3
+ TimelineProps,
4
+ TimelineItem,
5
+ TimelineAction,
6
+ TimelineItemProps
7
+ } from './types';
8
+
9
+ // Simple icon components (inline SVG)
10
+ const CalendarIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
11
+ <svg
12
+ className={`timeline__icon ${className}`}
13
+ fill="none"
14
+ stroke="currentColor"
15
+ viewBox="0 0 24 24"
16
+ >
17
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
18
+ </svg>
19
+ );
20
+
21
+ const ClockIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
22
+ <svg
23
+ className={`timeline__icon ${className}`}
24
+ fill="none"
25
+ stroke="currentColor"
26
+ viewBox="0 0 24 24"
27
+ >
28
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
29
+ </svg>
30
+ );
31
+
32
+ const UserIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
33
+ <svg
34
+ className={`timeline__icon ${className}`}
35
+ fill="none"
36
+ stroke="currentColor"
37
+ viewBox="0 0 24 24"
38
+ >
39
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
40
+ </svg>
41
+ );
42
+
43
+ const BellIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
44
+ <svg
45
+ className={`timeline__icon ${className}`}
46
+ fill="none"
47
+ stroke="currentColor"
48
+ viewBox="0 0 24 24"
49
+ >
50
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 17h5l-5 5-5-5h5V3h5v14z" />
51
+ </svg>
52
+ );
53
+
54
+ const SearchIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
55
+ <svg
56
+ className={`timeline__icon ${className}`}
57
+ fill="none"
58
+ stroke="currentColor"
59
+ viewBox="0 0 24 24"
60
+ >
61
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
62
+ </svg>
63
+ );
64
+
65
+ const FilterIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
66
+ <svg
67
+ className={`timeline__icon ${className}`}
68
+ fill="none"
69
+ stroke="currentColor"
70
+ viewBox="0 0 24 24"
71
+ >
72
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.414A1 1 0 013 6.707V4z" />
73
+ </svg>
74
+ );
75
+
76
+ const DotsIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
77
+ <svg
78
+ className={`timeline__icon ${className}`}
79
+ fill="none"
80
+ stroke="currentColor"
81
+ viewBox="0 0 24 24"
82
+ >
83
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
84
+ </svg>
85
+ );
86
+
87
+ // Timeline Search and Filter Bar
88
+ const TimelineSearchFilterBar: React.FC<{
89
+ searchable: boolean;
90
+ searchValue: string;
91
+ onSearchChange: (value: string) => void;
92
+ filterable: boolean;
93
+ theme: string;
94
+ size: 'sm' | 'md' | 'lg';
95
+ }> = ({
96
+ searchable,
97
+ searchValue,
98
+ onSearchChange,
99
+ filterable,
100
+ size
101
+ }) => {
102
+
103
+ if (!searchable && !filterable) return null;
104
+
105
+ return (
106
+ <div className={`timeline__search-filter-bar timeline__search-filter-bar--${size}`}>
107
+ {searchable && (
108
+ <div className="timeline__search-container">
109
+ <div className="timeline__search-icon">
110
+ <SearchIcon />
111
+ </div>
112
+ <input
113
+ type="text"
114
+ value={searchValue}
115
+ onChange={(e) => onSearchChange(e.target.value)}
116
+ placeholder="Search timeline..."
117
+ className={`timeline__search-input timeline__search-input--${size}`}
118
+ />
119
+ </div>
120
+ )}
121
+
122
+ {filterable && (
123
+ <button className={`timeline__filter-button timeline__filter-button--${size}`}>
124
+ <FilterIcon className="timeline__filter-icon" />
125
+ <span className="timeline__filter-text">Filter</span>
126
+ </button>
127
+ )}
128
+ </div>
129
+ );
130
+ };
131
+
132
+ // Timeline Item Actions Component
133
+ const TimelineItemActions: React.FC<{
134
+ actions: TimelineAction[];
135
+ item: TimelineItem;
136
+ theme: string;
137
+ size: 'sm' | 'md' | 'lg';
138
+ }> = ({ actions, item, size }) => {
139
+ const [showMenu, setShowMenu] = useState(false);
140
+
141
+ if (actions.length === 0) return null;
142
+
143
+ // If only one action, show it directly
144
+ if (actions.length === 1) {
145
+ const action = actions[0];
146
+ return (
147
+ <button
148
+ onClick={(e) => {
149
+ e.stopPropagation();
150
+ action.onClick(item);
151
+ }}
152
+ className={`timeline__action-button timeline__action-button--${size} ${action.variant === 'danger' ? 'timeline__action-button--danger' : ''}`}
153
+ title={action.label}
154
+ >
155
+ {action.icon || <DotsIcon className="timeline__action-icon" />}
156
+ </button>
157
+ );
158
+ }
159
+
160
+ // Multiple actions - show dropdown menu
161
+ return (
162
+ <div className="timeline__action-dropdown">
163
+ <button
164
+ onClick={(e) => {
165
+ e.stopPropagation();
166
+ setShowMenu(!showMenu);
167
+ }}
168
+ className={`timeline__action-button timeline__action-button--${size}`}
169
+ >
170
+ <DotsIcon className="timeline__action-icon" />
171
+ </button>
172
+
173
+ {showMenu && (
174
+ <>
175
+ {/* Backdrop */}
176
+ <div
177
+ className="timeline__action-backdrop"
178
+ onClick={() => setShowMenu(false)}
179
+ />
180
+
181
+ {/* Menu */}
182
+ <div className="timeline__action-menu">
183
+ {actions.map((action, index) => (
184
+ <button
185
+ key={index}
186
+ onClick={(e) => {
187
+ e.stopPropagation();
188
+ action.onClick(item);
189
+ setShowMenu(false);
190
+ }}
191
+ className={`timeline__action-menu-item ${action.variant === 'danger' ? 'timeline__action-menu-item--danger' : ''}`}
192
+ >
193
+ {action.icon && <span className="timeline__action-menu-icon">{action.icon}</span>}
194
+ {action.label}
195
+ </button>
196
+ ))}
197
+ </div>
198
+ </>
199
+ )}
200
+ </div>
201
+ );
202
+ };
203
+
204
+ // Individual Timeline Item Component
205
+ const TimelineItemComponent: React.FC<TimelineItemProps> = ({
206
+ item,
207
+ position,
208
+ isLast,
209
+ mode,
210
+ actions,
211
+ onClick,
212
+ theme,
213
+ size,
214
+ variant,
215
+ showConnector
216
+ }) => {
217
+ // const { getTheme } = useTheme();
218
+ // const themeConfig = getTheme(theme);
219
+ // const colors = themeConfig?.colors || getDefaultColors();
220
+
221
+ const isClickable = !!onClick;
222
+
223
+ const getIcon = () => {
224
+ if (item.icon) {
225
+ return item.icon;
226
+ }
227
+
228
+ switch (item.type) {
229
+ case 'event': return <CalendarIcon className="timeline__dot-icon" />;
230
+ case 'task': return <ClockIcon className="timeline__dot-icon" />;
231
+ case 'user': return <UserIcon className="timeline__dot-icon" />;
232
+ case 'system': return <BellIcon className="timeline__dot-icon" />;
233
+ default: return null;
234
+ }
235
+ };
236
+
237
+ const formatTimestamp = (timestamp: string) => {
238
+ const date = new Date(timestamp);
239
+ return date.toLocaleString();
240
+ };
241
+
242
+ return (
243
+ <div className={`timeline__item timeline__item--${mode} timeline__item--${position} timeline__item--${size}`}>
244
+ {/* Content */}
245
+ <div
246
+ className={`timeline__item-content timeline__item-content--${size} timeline__item-content--${variant} ${isClickable ? 'timeline__item-content--clickable' : ''}`}
247
+ onClick={isClickable ? () => onClick(item) : undefined}
248
+ >
249
+ <div className={`timeline__item-content-wrapper timeline__item-content-wrapper--${position}`}>
250
+ {/* Header */}
251
+ <div className="timeline__item-header">
252
+ <div className="timeline__item-text">
253
+ <h3 className="timeline__item-title">
254
+ {item.title}
255
+ </h3>
256
+ <p className="timeline__item-timestamp">
257
+ {formatTimestamp(item.timestamp)}
258
+ </p>
259
+ </div>
260
+
261
+ {/* Actions */}
262
+ <div className="timeline__item-actions">
263
+ <TimelineItemActions
264
+ actions={actions}
265
+ item={item}
266
+ theme={theme}
267
+ size={size}
268
+ />
269
+ </div>
270
+ </div>
271
+
272
+ {/* Content */}
273
+ {item.description && (
274
+ <p className="timeline__item-description">
275
+ {item.description}
276
+ </p>
277
+ )}
278
+
279
+ {/* Additional Content */}
280
+ {item.content && (
281
+ <div className="timeline__item-content-extra">
282
+ {item.content}
283
+ </div>
284
+ )}
285
+
286
+ {/* Metadata */}
287
+ {item.metadata && (
288
+ <div className="timeline__item-metadata">
289
+ {item.metadata.author && (
290
+ <span className="timeline__item-author">
291
+ By {item.metadata.author}
292
+ </span>
293
+ )}
294
+ {item.metadata.category && (
295
+ <span className="timeline__item-category">
296
+ {item.metadata.category}
297
+ </span>
298
+ )}
299
+ {item.metadata.tags && item.metadata.tags.map((tag, index) => (
300
+ <span
301
+ key={index}
302
+ className="timeline__item-tag"
303
+ >
304
+ #{tag}
305
+ </span>
306
+ ))}
307
+ </div>
308
+ )}
309
+ </div>
310
+ </div>
311
+
312
+ {/* Timeline Dot */}
313
+ <div className="timeline__dot-container">
314
+ <div
315
+ className={`timeline__dot timeline__dot--${size} timeline__dot--${item.status || 'default'}`}
316
+ >
317
+ {getIcon()}
318
+ </div>
319
+
320
+ {/* Connector Line */}
321
+ {showConnector && !isLast && (
322
+ <div className={`timeline__connector timeline__connector--${size}`} />
323
+ )}
324
+ </div>
325
+ </div>
326
+ );
327
+ };
328
+
329
+ // Main Timeline Component
330
+ export const Timeline: React.FC<TimelineProps> = ({
331
+ items,
332
+ mode = 'left',
333
+ reverse = false,
334
+ actions = [],
335
+ onItemClick,
336
+ searchable = false,
337
+ searchValue = '',
338
+ onSearchChange,
339
+ filterable = false,
340
+ // filters = [], // TODO: Implement filter functionality
341
+ // onFiltersChange, // TODO: Implement filter functionality
342
+ showConnector = true,
343
+ loading = false,
344
+ error = null,
345
+ emptyMessage = 'No timeline items',
346
+ className = '',
347
+ theme = 'stan-design',
348
+ size = 'md',
349
+ variant = 'default'
350
+ }) => {
351
+
352
+ // Filter items based on search
353
+ const filteredItems = useMemo(() => {
354
+ if (!searchable || !searchValue.trim()) return items;
355
+
356
+ const searchLower = searchValue.toLowerCase();
357
+ return items.filter(item =>
358
+ item.title.toLowerCase().includes(searchLower) ||
359
+ item.description?.toLowerCase().includes(searchLower) ||
360
+ item.metadata?.author?.toLowerCase().includes(searchLower) ||
361
+ item.metadata?.category?.toLowerCase().includes(searchLower) ||
362
+ item.metadata?.tags?.some(tag => tag.toLowerCase().includes(searchLower))
363
+ );
364
+ }, [items, searchable, searchValue]);
365
+
366
+ // Sort items by timestamp
367
+ const sortedItems = useMemo(() => {
368
+ const sorted = [...filteredItems].sort((a, b) => {
369
+ const dateA = new Date(a.timestamp).getTime();
370
+ const dateB = new Date(b.timestamp).getTime();
371
+ return reverse ? dateB - dateA : dateA - dateB;
372
+ });
373
+
374
+ return sorted;
375
+ }, [filteredItems, reverse]);
376
+
377
+ if (loading) {
378
+ return (
379
+ <div className={`timeline__loading ${className || ''}`}>
380
+ Loading timeline...
381
+ </div>
382
+ );
383
+ }
384
+
385
+ if (error) {
386
+ return (
387
+ <div className={`timeline__error ${className || ''}`}>
388
+ {error}
389
+ </div>
390
+ );
391
+ }
392
+
393
+ return (
394
+ <div className={`timeline__container ${className || ''}`}>
395
+ {/* Search and Filter Bar */}
396
+ <TimelineSearchFilterBar
397
+ searchable={searchable}
398
+ searchValue={searchValue}
399
+ onSearchChange={onSearchChange || (() => {})}
400
+ filterable={filterable}
401
+ theme={theme}
402
+ size={size}
403
+ />
404
+
405
+ {/* Timeline Container */}
406
+ <div className="timeline__timeline">
407
+ {sortedItems.length === 0 ? (
408
+ <div className="timeline__empty">
409
+ {emptyMessage}
410
+ </div>
411
+ ) : (
412
+ <div className="timeline__items">
413
+ {sortedItems.map((item, index) => {
414
+ const position = mode === 'alternate'
415
+ ? (index % 2 === 0 ? 'left' : 'right')
416
+ : mode;
417
+
418
+ return (
419
+ <TimelineItemComponent
420
+ key={item.id}
421
+ item={item}
422
+ position={position}
423
+ isLast={index === sortedItems.length - 1}
424
+ mode={mode}
425
+ actions={actions}
426
+ onClick={onItemClick}
427
+ theme={theme}
428
+ size={size}
429
+ variant={variant}
430
+ showConnector={showConnector}
431
+ />
432
+ );
433
+ })}
434
+ </div>
435
+ )}
436
+ </div>
437
+ </div>
438
+ );
439
+ };
440
+
441
+ export default Timeline;