@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.2.26 → 0.2.28
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/CHANGELOG.md +1 -1
- package/dist/components/ui/data-display/data-grid.d.ts.map +1 -1
- package/dist/components/ui/data-display/table.d.ts.map +1 -1
- package/dist/components/ui/data-display/types.d.ts +7 -5
- package/dist/components/ui/data-display/types.d.ts.map +1 -1
- package/dist/components/ui/feedback/index.d.ts +10 -0
- package/dist/components/ui/feedback/index.d.ts.map +1 -0
- package/dist/components/ui/feedback/index.esm.js +10 -0
- package/dist/components/ui/feedback/index.js +10 -0
- package/dist/components/ui/feedback/status-alert-example.d.ts +3 -0
- package/dist/components/ui/feedback/status-alert-example.d.ts.map +1 -0
- package/dist/components/ui/feedback/status-alert-example.esm.js +68 -0
- package/dist/components/ui/feedback/status-alert-example.js +68 -0
- package/dist/components/ui/feedback/toast-context.d.ts +27 -0
- package/dist/components/ui/feedback/toast-context.d.ts.map +1 -0
- package/dist/components/ui/feedback/toast-context.esm.js +95 -0
- package/dist/components/ui/feedback/toast-context.js +95 -0
- package/dist/components/ui/feedback/toast-example.d.ts +4 -0
- package/dist/components/ui/feedback/toast-example.d.ts.map +1 -0
- package/dist/components/ui/feedback/toast-example.esm.js +40 -0
- package/dist/components/ui/feedback/toast-example.js +40 -0
- package/dist/components/ui/feedback/toast-renderer.d.ts +11 -0
- package/dist/components/ui/feedback/toast-renderer.d.ts.map +1 -0
- package/dist/components/ui/feedback/toast-renderer.esm.js +23 -0
- package/dist/components/ui/feedback/toast-renderer.js +23 -0
- package/dist/components/ui/feedback/toast.d.ts.map +1 -1
- package/dist/components/ui/feedback/toast.esm.js +3 -3
- package/dist/components/ui/feedback/toast.js +3 -3
- package/dist/components/ui/feedback/types.d.ts +22 -5
- package/dist/components/ui/feedback/types.d.ts.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +5 -2
- package/dist/index.js +5 -2
- package/dist/styles.css +1 -1
- package/dist/themes/types.d.ts +1 -0
- package/dist/themes/types.d.ts.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/data-display/data-grid.tsx +8 -7
- package/src/components/ui/data-display/table.tsx +10 -9
- package/src/components/ui/data-display/types.ts +9 -5
- package/src/components/ui/feedback/index.ts +35 -0
- package/src/components/ui/feedback/status-alert-example.ts +71 -0
- package/src/components/ui/feedback/toast-context.tsx +145 -0
- package/src/components/ui/feedback/toast-example.tsx +65 -0
- package/src/components/ui/feedback/toast-renderer.tsx +61 -0
- package/src/components/ui/feedback/toast.tsx +7 -5
- package/src/components/ui/feedback/types.ts +24 -5
- package/src/index.ts +7 -2
- package/src/themes/types.ts +4 -0
- package/src/types.ts +4 -0
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useState, useCallback, useMemo, useRef, useEffect } from 'react';;
|
|
5
|
-
import {
|
|
6
|
-
DataGridProps,
|
|
7
|
-
DataGridColumnProps,
|
|
8
|
-
SortableColumn,
|
|
9
|
-
FilterConfig
|
|
5
|
+
import {
|
|
6
|
+
DataGridProps,
|
|
7
|
+
DataGridColumnProps,
|
|
8
|
+
SortableColumn,
|
|
9
|
+
FilterConfig,
|
|
10
|
+
ThemeName
|
|
10
11
|
} from './types.js';
|
|
11
12
|
|
|
12
13
|
// Simple icon components
|
|
@@ -144,7 +145,7 @@ const ColumnPanel: React.FC<{
|
|
|
144
145
|
groups?: string[];
|
|
145
146
|
onGroupChange?: (groups: string[]) => void;
|
|
146
147
|
onColumnToggle?: (columnKey: string, visible: boolean) => void;
|
|
147
|
-
theme:
|
|
148
|
+
theme: ThemeName;
|
|
148
149
|
size: 'sm' | 'md' | 'lg';
|
|
149
150
|
onClose: () => void;
|
|
150
151
|
}> = ({ columns, groups = [], onGroupChange, onColumnToggle, size, onClose }) => {
|
|
@@ -235,7 +236,7 @@ const DataGridToolbar: React.FC<{
|
|
|
235
236
|
groups?: string[];
|
|
236
237
|
onGroupChange?: (groups: string[]) => void;
|
|
237
238
|
columns: SortableColumn[];
|
|
238
|
-
theme:
|
|
239
|
+
theme: ThemeName;
|
|
239
240
|
size: 'sm' | 'md' | 'lg';
|
|
240
241
|
}> = ({
|
|
241
242
|
searchable,
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useState, useCallback } from 'react';;
|
|
5
|
-
import {
|
|
6
|
-
TableProps,
|
|
7
|
-
TableRowProps,
|
|
8
|
-
SortableColumn,
|
|
9
|
-
SortConfig,
|
|
5
|
+
import {
|
|
6
|
+
TableProps,
|
|
7
|
+
TableRowProps,
|
|
8
|
+
SortableColumn,
|
|
9
|
+
SortConfig,
|
|
10
10
|
PaginationConfig,
|
|
11
|
-
FilterConfig
|
|
11
|
+
FilterConfig,
|
|
12
|
+
ThemeName
|
|
12
13
|
} from './types.js';
|
|
13
14
|
|
|
14
15
|
// Simple icon components
|
|
@@ -51,7 +52,7 @@ const TableHeader: React.FC<{
|
|
|
51
52
|
selectable?: boolean;
|
|
52
53
|
onSelectAll?: (checked: boolean) => void;
|
|
53
54
|
allSelected?: boolean;
|
|
54
|
-
theme:
|
|
55
|
+
theme: ThemeName;
|
|
55
56
|
size: 'sm' | 'md' | 'lg';
|
|
56
57
|
variant: 'default' | 'bordered' | 'striped' | 'compact';
|
|
57
58
|
}> = ({
|
|
@@ -176,7 +177,7 @@ const SearchFilterBar: React.FC<{
|
|
|
176
177
|
searchValue?: string;
|
|
177
178
|
onSearchChange?: (value: string) => void;
|
|
178
179
|
filters?: FilterConfig[];
|
|
179
|
-
theme:
|
|
180
|
+
theme: ThemeName;
|
|
180
181
|
size: 'sm' | 'md' | 'lg';
|
|
181
182
|
}> = ({
|
|
182
183
|
searchable,
|
|
@@ -227,7 +228,7 @@ const TablePagination: React.FC<{
|
|
|
227
228
|
pagination?: PaginationConfig;
|
|
228
229
|
onPageChange?: (page: number) => void;
|
|
229
230
|
onPageSizeChange?: (pageSize: number) => void;
|
|
230
|
-
theme:
|
|
231
|
+
theme: ThemeName;
|
|
231
232
|
size: 'sm' | 'md' | 'lg';
|
|
232
233
|
}> = ({ pagination, onPageChange, onPageSizeChange, size }) => {
|
|
233
234
|
// const { getTheme } = useTheme();
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
// Comprehensive type definitions for all data display components
|
|
3
3
|
|
|
4
4
|
import * as React from 'react';;
|
|
5
|
+
import { ThemeName } from '../../../themes/types.js';
|
|
6
|
+
|
|
7
|
+
// Re-export ThemeName for data display components
|
|
8
|
+
export type { ThemeName };
|
|
5
9
|
|
|
6
10
|
// ============================================================================
|
|
7
11
|
// COMMON INTERFACES
|
|
@@ -9,7 +13,7 @@ import * as React from 'react';;
|
|
|
9
13
|
|
|
10
14
|
export interface DataDisplayBaseProps {
|
|
11
15
|
className?: string;
|
|
12
|
-
theme?:
|
|
16
|
+
theme?: ThemeName;
|
|
13
17
|
size?: 'sm' | 'md' | 'lg';
|
|
14
18
|
variant?: 'default' | 'bordered' | 'striped';
|
|
15
19
|
loading?: boolean;
|
|
@@ -83,7 +87,7 @@ export interface TableRowProps {
|
|
|
83
87
|
onSelect: (checked: boolean) => void;
|
|
84
88
|
onExpand: () => void;
|
|
85
89
|
onClick: () => void;
|
|
86
|
-
theme:
|
|
90
|
+
theme: ThemeName;
|
|
87
91
|
size: 'sm' | 'md' | 'lg';
|
|
88
92
|
variant: 'default' | 'bordered' | 'striped' | 'compact';
|
|
89
93
|
}
|
|
@@ -131,7 +135,7 @@ export interface DataGridColumnProps {
|
|
|
131
135
|
onSort: () => void;
|
|
132
136
|
onResize: (width: number) => void;
|
|
133
137
|
sortConfig?: SortConfig;
|
|
134
|
-
theme:
|
|
138
|
+
theme: ThemeName;
|
|
135
139
|
size: 'sm' | 'md' | 'lg';
|
|
136
140
|
resizable: boolean;
|
|
137
141
|
}
|
|
@@ -265,7 +269,7 @@ export interface TreeItemProps {
|
|
|
265
269
|
onToggleExpand?: (nodeId: string, expanded: boolean) => void;
|
|
266
270
|
onSelectionChange?: (nodeId: string, selected: boolean) => void;
|
|
267
271
|
onClick?: (node: TreeNode, event: React.MouseEvent) => void;
|
|
268
|
-
theme:
|
|
272
|
+
theme: ThemeName;
|
|
269
273
|
size: 'sm' | 'md' | 'lg';
|
|
270
274
|
variant: 'default' | 'bordered' | 'striped';
|
|
271
275
|
draggable?: boolean;
|
|
@@ -342,7 +346,7 @@ export interface TimelineItemProps {
|
|
|
342
346
|
mode: 'left' | 'right' | 'alternate';
|
|
343
347
|
actions: TimelineAction[];
|
|
344
348
|
onClick?: (item: TimelineItem) => void;
|
|
345
|
-
theme:
|
|
349
|
+
theme: ThemeName;
|
|
346
350
|
size: 'sm' | 'md' | 'lg';
|
|
347
351
|
variant: 'default' | 'bordered' | 'striped';
|
|
348
352
|
showConnector: boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Feedback Components - Main Export
|
|
2
|
+
export { Alert } from './alert';
|
|
3
|
+
export { Progress } from './progress';
|
|
4
|
+
export { Toast, ToastContainer } from './toast';
|
|
5
|
+
export { Skeleton } from './skeleton';
|
|
6
|
+
|
|
7
|
+
// Toast Management
|
|
8
|
+
export { ToastProvider, useToast, useToastHelpers } from './toast-context';
|
|
9
|
+
export { ToastRenderer, GlobalToastRenderer } from './toast-renderer';
|
|
10
|
+
|
|
11
|
+
// Types
|
|
12
|
+
export type {
|
|
13
|
+
AlertProps,
|
|
14
|
+
AlertAction,
|
|
15
|
+
StatusAlertData,
|
|
16
|
+
ToastProps,
|
|
17
|
+
ToastAction,
|
|
18
|
+
ToastContainerProps,
|
|
19
|
+
ProgressProps,
|
|
20
|
+
ProgressStep,
|
|
21
|
+
SkeletonProps,
|
|
22
|
+
SkeletonTextProps,
|
|
23
|
+
SkeletonAvatarProps,
|
|
24
|
+
SkeletonButtonProps,
|
|
25
|
+
FeedbackBaseProps
|
|
26
|
+
} from './types';
|
|
27
|
+
|
|
28
|
+
export type {
|
|
29
|
+
ToastInstance,
|
|
30
|
+
ToastContextValue,
|
|
31
|
+
ToastProviderProps
|
|
32
|
+
} from './toast-context';
|
|
33
|
+
|
|
34
|
+
// Examples
|
|
35
|
+
export { statusAlertExamples } from './status-alert-example';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// StatusAlertData Usage Example
|
|
2
|
+
import { StatusAlertData } from './types.js';
|
|
3
|
+
|
|
4
|
+
// Simple StatusAlertData examples
|
|
5
|
+
export const statusAlertExamples: StatusAlertData[] = [
|
|
6
|
+
{
|
|
7
|
+
id: 'success-alert',
|
|
8
|
+
title: 'Success',
|
|
9
|
+
message: 'Your changes have been saved successfully.',
|
|
10
|
+
type: 'success',
|
|
11
|
+
dismissible: true,
|
|
12
|
+
onDismiss: () => console.log('Success alert dismissed'),
|
|
13
|
+
showIcon: true,
|
|
14
|
+
closable: true,
|
|
15
|
+
size: 'md',
|
|
16
|
+
variant: 'default'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'warning-alert',
|
|
20
|
+
title: 'Warning',
|
|
21
|
+
message: 'Please review your settings before proceeding.',
|
|
22
|
+
type: 'warning',
|
|
23
|
+
dismissible: true,
|
|
24
|
+
actions: [
|
|
25
|
+
{
|
|
26
|
+
label: 'Review Settings',
|
|
27
|
+
onClick: () => console.log('Review settings clicked'),
|
|
28
|
+
variant: 'primary'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
label: 'Dismiss',
|
|
32
|
+
onClick: () => console.log('Dismissed'),
|
|
33
|
+
variant: 'secondary'
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
showIcon: true,
|
|
37
|
+
size: 'md',
|
|
38
|
+
variant: 'bordered'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'error-alert',
|
|
42
|
+
title: 'Error',
|
|
43
|
+
message: 'An error occurred while processing your request.',
|
|
44
|
+
type: 'error',
|
|
45
|
+
dismissible: true,
|
|
46
|
+
onDismiss: () => console.log('Error alert dismissed'),
|
|
47
|
+
actions: [
|
|
48
|
+
{
|
|
49
|
+
label: 'Retry',
|
|
50
|
+
onClick: () => console.log('Retry clicked'),
|
|
51
|
+
variant: 'primary'
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
showIcon: true,
|
|
55
|
+
closable: true,
|
|
56
|
+
size: 'lg',
|
|
57
|
+
variant: 'filled'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'info-alert',
|
|
61
|
+
title: 'Information',
|
|
62
|
+
message: 'System maintenance is scheduled for tonight.',
|
|
63
|
+
type: 'info',
|
|
64
|
+
dismissible: false,
|
|
65
|
+
persistent: true,
|
|
66
|
+
showIcon: true,
|
|
67
|
+
size: 'md',
|
|
68
|
+
variant: 'default',
|
|
69
|
+
theme: 'stan-design'
|
|
70
|
+
}
|
|
71
|
+
];
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { createContext, useContext, useState, useCallback, useRef } from 'react';;
|
|
5
|
+
import { ToastProps } from './types.js';
|
|
6
|
+
|
|
7
|
+
export interface ToastInstance extends Omit<ToastProps, 'id'> {
|
|
8
|
+
id: string;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ToastContextValue {
|
|
13
|
+
toasts: ToastInstance[];
|
|
14
|
+
addToast: (toast: Omit<ToastInstance, 'id' | 'createdAt'>) => string;
|
|
15
|
+
removeToast: (id: string) => void;
|
|
16
|
+
clearAllToasts: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ToastContext = createContext<ToastContextValue | undefined>(undefined);
|
|
20
|
+
|
|
21
|
+
export interface ToastProviderProps {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
maxToasts?: number;
|
|
24
|
+
defaultDuration?: number;
|
|
25
|
+
defaultPosition?: ToastProps['position'];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const ToastProvider: React.FC<ToastProviderProps> = ({
|
|
29
|
+
children,
|
|
30
|
+
maxToasts = 5,
|
|
31
|
+
defaultDuration = 5000,
|
|
32
|
+
defaultPosition = 'top-right'
|
|
33
|
+
}) => {
|
|
34
|
+
const [toasts, setToasts] = useState<ToastInstance[]>([]);
|
|
35
|
+
const timeoutRefs = useRef<Map<string, NodeJS.Timeout>>(new Map());
|
|
36
|
+
|
|
37
|
+
const removeToast = useCallback((id: string) => {
|
|
38
|
+
setToasts(prev => prev.filter(toast => toast.id !== id));
|
|
39
|
+
|
|
40
|
+
const timeoutId = timeoutRefs.current.get(id);
|
|
41
|
+
if (timeoutId) {
|
|
42
|
+
clearTimeout(timeoutId);
|
|
43
|
+
timeoutRefs.current.delete(id);
|
|
44
|
+
}
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
const addToast = useCallback((toastData: Omit<ToastInstance, 'id' | 'createdAt'>) => {
|
|
48
|
+
const id = `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
49
|
+
const toast: ToastInstance = {
|
|
50
|
+
...toastData,
|
|
51
|
+
id,
|
|
52
|
+
createdAt: Date.now(),
|
|
53
|
+
duration: toastData.duration ?? defaultDuration,
|
|
54
|
+
position: toastData.position ?? defaultPosition,
|
|
55
|
+
autoClose: toastData.autoClose ?? true,
|
|
56
|
+
pauseOnHover: toastData.pauseOnHover ?? true,
|
|
57
|
+
closable: toastData.closable ?? true,
|
|
58
|
+
showIcon: toastData.showIcon ?? true,
|
|
59
|
+
size: toastData.size ?? 'md',
|
|
60
|
+
variant: toastData.variant ?? 'default'
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
setToasts(prev => {
|
|
64
|
+
const newToasts = [toast, ...prev];
|
|
65
|
+
|
|
66
|
+
if (newToasts.length > maxToasts) {
|
|
67
|
+
const toastsToRemove = newToasts.slice(maxToasts);
|
|
68
|
+
toastsToRemove.forEach(t => {
|
|
69
|
+
const timeoutId = timeoutRefs.current.get(t.id);
|
|
70
|
+
if (timeoutId) {
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
timeoutRefs.current.delete(t.id);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return newToasts.slice(0, maxToasts);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return newToasts;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (toast.autoClose && toast.duration && toast.duration > 0) {
|
|
82
|
+
const timeoutId = setTimeout(() => {
|
|
83
|
+
removeToast(id);
|
|
84
|
+
}, toast.duration);
|
|
85
|
+
|
|
86
|
+
timeoutRefs.current.set(id, timeoutId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return id;
|
|
90
|
+
}, [defaultDuration, defaultPosition, maxToasts, removeToast]);
|
|
91
|
+
|
|
92
|
+
const clearAllToasts = useCallback(() => {
|
|
93
|
+
timeoutRefs.current.forEach(timeoutId => clearTimeout(timeoutId));
|
|
94
|
+
timeoutRefs.current.clear();
|
|
95
|
+
setToasts([]);
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
const contextValue: ToastContextValue = {
|
|
99
|
+
toasts,
|
|
100
|
+
addToast,
|
|
101
|
+
removeToast,
|
|
102
|
+
clearAllToasts
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<ToastContext.Provider value={contextValue}>
|
|
107
|
+
{children}
|
|
108
|
+
</ToastContext.Provider>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const useToast = (): ToastContextValue => {
|
|
113
|
+
const context = useContext(ToastContext);
|
|
114
|
+
if (!context) {
|
|
115
|
+
throw new Error('useToast must be used within a ToastProvider');
|
|
116
|
+
}
|
|
117
|
+
return context;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const useToastHelpers = () => {
|
|
121
|
+
const { addToast } = useToast();
|
|
122
|
+
|
|
123
|
+
const showSuccess = useCallback((message: string, title?: string, options?: Partial<ToastInstance>) => {
|
|
124
|
+
return addToast({ type: 'success', message, title, ...options });
|
|
125
|
+
}, [addToast]);
|
|
126
|
+
|
|
127
|
+
const showError = useCallback((message: string, title?: string, options?: Partial<ToastInstance>) => {
|
|
128
|
+
return addToast({ type: 'error', message, title, ...options });
|
|
129
|
+
}, [addToast]);
|
|
130
|
+
|
|
131
|
+
const showWarning = useCallback((message: string, title?: string, options?: Partial<ToastInstance>) => {
|
|
132
|
+
return addToast({ type: 'warning', message, title, ...options });
|
|
133
|
+
}, [addToast]);
|
|
134
|
+
|
|
135
|
+
const showInfo = useCallback((message: string, title?: string, options?: Partial<ToastInstance>) => {
|
|
136
|
+
return addToast({ type: 'info', message, title, ...options });
|
|
137
|
+
}, [addToast]);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
showSuccess,
|
|
141
|
+
showError,
|
|
142
|
+
showWarning,
|
|
143
|
+
showInfo
|
|
144
|
+
};
|
|
145
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';;
|
|
4
|
+
import { ToastProvider, useToastHelpers, GlobalToastRenderer } from './index.js';
|
|
5
|
+
|
|
6
|
+
const ToastDemo: React.FC = () => {
|
|
7
|
+
const { showSuccess, showError, showWarning, showInfo } = useToastHelpers();
|
|
8
|
+
|
|
9
|
+
const handleSuccess = () => {
|
|
10
|
+
showSuccess('Operation completed successfully!', 'Success');
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const handleError = () => {
|
|
14
|
+
showError('Something went wrong. Please try again.', 'Error');
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const handleWarning = () => {
|
|
18
|
+
showWarning('This action cannot be undone.', 'Warning');
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleInfo = () => {
|
|
22
|
+
showInfo('New update available.', 'Information');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleCustomAction = () => {
|
|
26
|
+
showSuccess('File uploaded successfully!', 'Upload Complete', {
|
|
27
|
+
actions: [
|
|
28
|
+
{
|
|
29
|
+
label: 'View File',
|
|
30
|
+
onClick: () => console.log('View file clicked'),
|
|
31
|
+
variant: 'primary'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'Share',
|
|
35
|
+
onClick: () => console.log('Share clicked'),
|
|
36
|
+
variant: 'secondary'
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div style={{ padding: '20px' }}>
|
|
44
|
+
<h2>Toast Component Test</h2>
|
|
45
|
+
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
46
|
+
<button onClick={handleSuccess}>Show Success</button>
|
|
47
|
+
<button onClick={handleError}>Show Error</button>
|
|
48
|
+
<button onClick={handleWarning}>Show Warning</button>
|
|
49
|
+
<button onClick={handleInfo}>Show Info</button>
|
|
50
|
+
<button onClick={handleCustomAction}>Show With Actions</button>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const ToastExample: React.FC = () => {
|
|
57
|
+
return (
|
|
58
|
+
<ToastProvider maxToasts={5} defaultDuration={5000}>
|
|
59
|
+
<ToastDemo />
|
|
60
|
+
<GlobalToastRenderer />
|
|
61
|
+
</ToastProvider>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default ToastExample;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as React from 'react';;
|
|
2
|
+
import { Toast, ToastContainer } from './toast.js';
|
|
3
|
+
import { useToast } from './toast-context.js';
|
|
4
|
+
import { ToastProps } from './types.js';
|
|
5
|
+
|
|
6
|
+
export interface ToastRendererProps {
|
|
7
|
+
position?: ToastProps['position'];
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ToastRenderer: React.FC<ToastRendererProps> = ({
|
|
12
|
+
position = 'top-right',
|
|
13
|
+
className = ''
|
|
14
|
+
}) => {
|
|
15
|
+
const { toasts, removeToast } = useToast();
|
|
16
|
+
|
|
17
|
+
const positionToasts = toasts.filter(toast =>
|
|
18
|
+
(toast.position || 'top-right') === position
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (positionToasts.length === 0) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<ToastContainer position={position} className={className}>
|
|
27
|
+
{positionToasts.map((toast) => (
|
|
28
|
+
<Toast
|
|
29
|
+
key={toast.id}
|
|
30
|
+
{...toast}
|
|
31
|
+
onClose={() => removeToast(toast.id)}
|
|
32
|
+
/>
|
|
33
|
+
))}
|
|
34
|
+
</ToastContainer>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const GlobalToastRenderer: React.FC<{ className?: string }> = ({
|
|
39
|
+
className = ''
|
|
40
|
+
}) => {
|
|
41
|
+
const positions: ToastProps['position'][] = [
|
|
42
|
+
'top-left',
|
|
43
|
+
'top-center',
|
|
44
|
+
'top-right',
|
|
45
|
+
'bottom-left',
|
|
46
|
+
'bottom-center',
|
|
47
|
+
'bottom-right'
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<>
|
|
52
|
+
{positions.map(position => (
|
|
53
|
+
<ToastRenderer
|
|
54
|
+
key={position}
|
|
55
|
+
position={position}
|
|
56
|
+
className={className}
|
|
57
|
+
/>
|
|
58
|
+
))}
|
|
59
|
+
</>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -97,14 +97,14 @@ const getToastColors = (type: ToastProps['type'], colors: any) => {
|
|
|
97
97
|
// Toast Action Button Component
|
|
98
98
|
const ToastActionButton: React.FC<ToastAction> = ({
|
|
99
99
|
label,
|
|
100
|
-
|
|
100
|
+
onClick,
|
|
101
101
|
variant = 'primary'
|
|
102
102
|
}) => {
|
|
103
103
|
return (
|
|
104
104
|
<button
|
|
105
105
|
type="button"
|
|
106
106
|
className={`toast__action-button toast__action-button--${variant}`}
|
|
107
|
-
onClick={
|
|
107
|
+
onClick={onClick}
|
|
108
108
|
>
|
|
109
109
|
{label}
|
|
110
110
|
</button>
|
|
@@ -235,9 +235,11 @@ export const Toast: React.FC<ToastProps> = ({
|
|
|
235
235
|
</h3>
|
|
236
236
|
)}
|
|
237
237
|
|
|
238
|
-
|
|
239
|
-
{
|
|
240
|
-
|
|
238
|
+
{message && (
|
|
239
|
+
<div className={`toast__message ${!title ? 'toast__message--only' : ''}`}>
|
|
240
|
+
{message}
|
|
241
|
+
</div>
|
|
242
|
+
)}
|
|
241
243
|
|
|
242
244
|
{actions.length > 0 && (
|
|
243
245
|
<div className="toast__actions">
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';;
|
|
2
|
+
import { ThemeName } from '../../../themes/types.js';
|
|
2
3
|
|
|
3
4
|
// Base props for all feedback components
|
|
4
5
|
export interface FeedbackBaseProps {
|
|
5
6
|
className?: string;
|
|
6
|
-
theme?:
|
|
7
|
+
theme?: ThemeName;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
// Alert Component Types
|
|
@@ -30,15 +31,33 @@ export interface AlertAction {
|
|
|
30
31
|
size?: 'sm' | 'md' | 'lg';
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// Status Alert Data Interface
|
|
35
|
+
export interface StatusAlertData {
|
|
36
|
+
id?: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
message?: string;
|
|
39
|
+
children?: React.ReactNode;
|
|
40
|
+
type: 'success' | 'warning' | 'error' | 'info';
|
|
41
|
+
dismissible?: boolean;
|
|
42
|
+
onDismiss?: () => void;
|
|
43
|
+
icon?: React.ReactNode;
|
|
44
|
+
actions?: AlertAction[];
|
|
45
|
+
showIcon?: boolean;
|
|
46
|
+
closable?: boolean;
|
|
47
|
+
persistent?: boolean;
|
|
48
|
+
size?: 'sm' | 'md' | 'lg';
|
|
49
|
+
variant?: 'default' | 'bordered' | 'filled';
|
|
50
|
+
theme?: ThemeName;
|
|
51
|
+
}
|
|
52
|
+
|
|
33
53
|
// Toast Component Types
|
|
34
54
|
export interface ToastProps extends FeedbackBaseProps {
|
|
35
55
|
id: string;
|
|
36
56
|
title?: string;
|
|
37
|
-
message
|
|
57
|
+
message?: string;
|
|
38
58
|
type: 'success' | 'warning' | 'error' | 'info' | 'default';
|
|
39
59
|
duration?: number; // milliseconds, 0 = persistent
|
|
40
60
|
onClose?: () => void;
|
|
41
|
-
onAction?: (action: string) => void;
|
|
42
61
|
actions?: ToastAction[];
|
|
43
62
|
icon?: React.ReactNode;
|
|
44
63
|
showIcon?: boolean;
|
|
@@ -54,7 +73,7 @@ export interface ToastProps extends FeedbackBaseProps {
|
|
|
54
73
|
|
|
55
74
|
export interface ToastAction {
|
|
56
75
|
label: string;
|
|
57
|
-
|
|
76
|
+
onClick: () => void;
|
|
58
77
|
variant?: 'primary' | 'secondary' | 'ghost';
|
|
59
78
|
}
|
|
60
79
|
|
|
@@ -66,7 +85,7 @@ export interface ToastContainerProps {
|
|
|
66
85
|
draggable?: boolean;
|
|
67
86
|
progress?: boolean;
|
|
68
87
|
className?: string;
|
|
69
|
-
theme?:
|
|
88
|
+
theme?: ThemeName;
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
// Progress Component Types
|
package/src/index.ts
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Production-ready design system package with stan-design theme
|
|
4
4
|
*
|
|
5
5
|
* Auto-generated exports for:
|
|
6
|
-
* -
|
|
6
|
+
* - 43 UI components
|
|
7
7
|
* - 67 custom hooks
|
|
8
8
|
* - 6 utility functions
|
|
9
9
|
* - 29 theme system components
|
|
10
|
-
* -
|
|
10
|
+
* - 133 TypeScript types
|
|
11
11
|
* - 4 design tokens
|
|
12
12
|
* - 0 build plugins
|
|
13
13
|
* - Complete CSS system (61+ files)
|
|
@@ -46,6 +46,9 @@ export { Tree } from './components/ui/data-display/tree.js';
|
|
|
46
46
|
export { Alert } from './components/ui/feedback/alert.js';
|
|
47
47
|
export { Progress } from './components/ui/feedback/progress.js';
|
|
48
48
|
export { SkeletonText } from './components/ui/feedback/skeleton.js';
|
|
49
|
+
export { ToastProvider } from './components/ui/feedback/toast-context.js';
|
|
50
|
+
export { ToastExample } from './components/ui/feedback/toast-example.js';
|
|
51
|
+
export { ToastRenderer } from './components/ui/feedback/toast-renderer.js';
|
|
49
52
|
export { Toast } from './components/ui/feedback/toast.js';
|
|
50
53
|
export { Backdrop } from './components/ui/overlay/backdrop.js';
|
|
51
54
|
export { FocusManager } from './components/ui/overlay/focus-manager.js';
|
|
@@ -200,6 +203,7 @@ export type { NavigationAccessibility } from './components/ui/navigation/types.j
|
|
|
200
203
|
export type { FeedbackBaseProps } from './components/ui/feedback/types.js';
|
|
201
204
|
export type { AlertProps } from './components/ui/feedback/types.js';
|
|
202
205
|
export type { AlertAction } from './components/ui/feedback/types.js';
|
|
206
|
+
export type { StatusAlertData } from './components/ui/feedback/types.js';
|
|
203
207
|
export type { ToastProps } from './components/ui/feedback/types.js';
|
|
204
208
|
export type { ToastAction } from './components/ui/feedback/types.js';
|
|
205
209
|
export type { ToastContainerProps } from './components/ui/feedback/types.js';
|
|
@@ -255,6 +259,7 @@ export type { PopoverContentProps } from './components/ui/overlay/types.js';
|
|
|
255
259
|
export type { PopoverHeaderProps } from './components/ui/overlay/types.js';
|
|
256
260
|
export type { PopoverBodyProps } from './components/ui/overlay/types.js';
|
|
257
261
|
export type { PopoverFooterProps } from './components/ui/overlay/types.js';
|
|
262
|
+
export type { ThemeName } from './themes/types.js';
|
|
258
263
|
export type { MultiThemeConfig } from './themes/types.js';
|
|
259
264
|
export type { FontThemeConfig } from './themes/types.js';
|
|
260
265
|
export type { FontConfig } from './themes/types.js';
|
package/src/themes/types.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// Multi-Theme System Type Definitions
|
|
2
2
|
// This file defines the core interfaces for theme configuration
|
|
3
3
|
|
|
4
|
+
// Theme Name Type - extensible for new themes
|
|
5
|
+
// Note: 'enterprise' is used in tests but may not have a full theme implementation
|
|
6
|
+
export type ThemeName = 'default' | 'stan-design' | 'harvey' | 'enterprise' | string;
|
|
7
|
+
|
|
4
8
|
export interface MultiThemeConfig {
|
|
5
9
|
fonts: FontThemeConfig;
|
|
6
10
|
colors: ColorThemeConfig;
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// Multi-Theme System Type Definitions
|
|
2
2
|
// This file defines the core interfaces for theme configuration
|
|
3
3
|
|
|
4
|
+
// Theme Name Type - extensible for new themes
|
|
5
|
+
// Note: 'enterprise' is used in tests but may not have a full theme implementation
|
|
6
|
+
export type ThemeName = 'default' | 'stan-design' | 'harvey' | 'enterprise' | string;
|
|
7
|
+
|
|
4
8
|
export interface MultiThemeConfig {
|
|
5
9
|
fonts: FontThemeConfig;
|
|
6
10
|
colors: ColorThemeConfig;
|