@justin_evo/evo-ui 1.0.1
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/dist/Alert/Alert.d.ts +11 -0
- package/dist/AutoComplete/AutoComplete.d.ts +95 -0
- package/dist/Badge/Badge.d.ts +23 -0
- package/dist/Breadcrumb/Breadcrumb.d.ts +16 -0
- package/dist/Button/Button.d.ts +54 -0
- package/dist/Card/Card.d.ts +60 -0
- package/dist/Checkbox/Checkbox.d.ts +16 -0
- package/dist/CommandPalette/CommandPalette.d.ts +17 -0
- package/dist/Container/Container.d.ts +10 -0
- package/dist/Divider/Divider.d.ts +7 -0
- package/dist/Form/Form.d.ts +61 -0
- package/dist/Grid/Grid.d.ts +23 -0
- package/dist/ImageCropper/ImageCropper.d.ts +111 -0
- package/dist/Input/Input.d.ts +12 -0
- package/dist/Modal/Modal.d.ts +26 -0
- package/dist/Nav/Nav.d.ts +63 -0
- package/dist/Notification/Notification.d.ts +186 -0
- package/dist/Pagination/Pagination.d.ts +10 -0
- package/dist/Radio/Radio.d.ts +20 -0
- package/dist/RichTextArea/RichTextArea.d.ts +70 -0
- package/dist/Select/Select.d.ts +44 -0
- package/dist/Skeleton/Skeleton.d.ts +23 -0
- package/dist/Stack/Stack.d.ts +16 -0
- package/dist/Table/Table.d.ts +77 -0
- package/dist/Tabs/Tabs.d.ts +28 -0
- package/dist/Theme/ThemeProvider.d.ts +96 -0
- package/dist/Theme/ThemeToggle.d.ts +22 -0
- package/dist/Toggle/Toggle.d.ts +11 -0
- package/dist/Tooltip/Tooltip.d.ts +10 -0
- package/dist/TopNav/TopNav.d.ts +76 -0
- package/dist/TreeSelect/TreeSelect.d.ts +50 -0
- package/dist/declarations.d.ts +6 -0
- package/dist/evo-ui.css +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.es.js +5688 -0
- package/package.json +52 -0
- package/src/Alert/Alert.tsx +49 -0
- package/src/AutoComplete/AutoComplete.tsx +810 -0
- package/src/Badge/Badge.tsx +53 -0
- package/src/Breadcrumb/Breadcrumb.tsx +53 -0
- package/src/Button/Button.tsx +125 -0
- package/src/Card/Card.tsx +257 -0
- package/src/Checkbox/Checkbox.tsx +59 -0
- package/src/CommandPalette/CommandPalette.tsx +185 -0
- package/src/Container/Container.tsx +31 -0
- package/src/Divider/Divider.tsx +31 -0
- package/src/Form/Form.tsx +185 -0
- package/src/Grid/Grid.tsx +66 -0
- package/src/ImageCropper/ImageCropper.tsx +911 -0
- package/src/Input/Input.tsx +74 -0
- package/src/Modal/Modal.tsx +77 -0
- package/src/Nav/Nav.tsx +626 -0
- package/src/Notification/Notification.tsx +1503 -0
- package/src/Pagination/Pagination.tsx +76 -0
- package/src/Radio/Radio.tsx +69 -0
- package/src/RichTextArea/RichTextArea.tsx +869 -0
- package/src/Select/Select.tsx +515 -0
- package/src/Skeleton/Skeleton.tsx +70 -0
- package/src/Stack/Stack.tsx +52 -0
- package/src/Table/Table.tsx +335 -0
- package/src/Tabs/Tabs.tsx +90 -0
- package/src/Theme/ThemeProvider.tsx +253 -0
- package/src/Theme/ThemeToggle.tsx +79 -0
- package/src/Toggle/Toggle.tsx +48 -0
- package/src/Tooltip/Tooltip.tsx +38 -0
- package/src/TopNav/TopNav.tsx +994 -0
- package/src/TreeSelect/TreeSelect.tsx +825 -0
- package/src/css/alert.module.scss +93 -0
- package/src/css/autocomplete.module.scss +416 -0
- package/src/css/badge.module.scss +82 -0
- package/src/css/base/_color.scss +159 -0
- package/src/css/base/_theme.scss +237 -0
- package/src/css/base/_variables.scss +161 -0
- package/src/css/breadcrumb.module.scss +50 -0
- package/src/css/button.module.scss +385 -0
- package/src/css/card.module.scss +217 -0
- package/src/css/checkbox.module.scss +120 -0
- package/src/css/commandpalette.module.scss +211 -0
- package/src/css/container.module.scss +18 -0
- package/src/css/divider.module.scss +41 -0
- package/src/css/form.module.scss +245 -0
- package/src/css/imagecropper.module.scss +397 -0
- package/src/css/input.module.scss +89 -0
- package/src/css/modal.module.scss +105 -0
- package/src/css/nav.module.scss +339 -0
- package/src/css/notification.module.scss +691 -0
- package/src/css/pagination.module.scss +63 -0
- package/src/css/radio.module.scss +89 -0
- package/src/css/richtextarea.module.scss +307 -0
- package/src/css/select.module.scss +525 -0
- package/src/css/skeleton.module.scss +30 -0
- package/src/css/table.module.scss +386 -0
- package/src/css/tabs.module.scss +63 -0
- package/src/css/theme-toggle.module.scss +83 -0
- package/src/css/toggle.module.scss +54 -0
- package/src/css/tooltip.module.scss +97 -0
- package/src/css/topnav.module.scss +396 -0
- package/src/css/treeselect.module.scss +558 -0
- package/src/css/utilities/_borders.scss +111 -0
- package/src/css/utilities/_colors.scss +66 -0
- package/src/css/utilities/_effects.scss +216 -0
- package/src/css/utilities/_layout.scss +181 -0
- package/src/css/utilities/_position.scss +75 -0
- package/src/css/utilities/_sizing.scss +138 -0
- package/src/css/utilities/_spacing.scss +99 -0
- package/src/css/utilities/_typography.scss +121 -0
- package/src/css/utilities/index.scss +24 -0
- package/src/declarations.d.ts +6 -0
- package/src/index.ts +60 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type EvoNotificationSeverity = 'success' | 'error' | 'warning' | 'info';
|
|
3
|
+
export type EvoNotificationAnchor = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
4
|
+
export interface EvoNotificationAction {
|
|
5
|
+
label: string;
|
|
6
|
+
onClick: (e: React.MouseEvent) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface EvoToastOptions {
|
|
9
|
+
id?: string;
|
|
10
|
+
title?: ReactNode;
|
|
11
|
+
description?: ReactNode;
|
|
12
|
+
severity?: EvoNotificationSeverity;
|
|
13
|
+
icon?: ReactNode;
|
|
14
|
+
duration?: number;
|
|
15
|
+
persistent?: boolean;
|
|
16
|
+
anchor?: EvoNotificationAnchor;
|
|
17
|
+
action?: EvoNotificationAction;
|
|
18
|
+
dismissible?: boolean;
|
|
19
|
+
onDismiss?: (id: string) => void;
|
|
20
|
+
onAutoClose?: (id: string) => void;
|
|
21
|
+
className?: string;
|
|
22
|
+
inbox?: boolean | Partial<EvoInboxItemInput>;
|
|
23
|
+
/**
|
|
24
|
+
* Coalescing key. Toasts pushed with the same `groupKey` while an earlier
|
|
25
|
+
* one is still on screen fold into it — the card refreshes in place and
|
|
26
|
+
* shows an incremented count badge instead of stacking a duplicate.
|
|
27
|
+
* Ignored when an explicit `id` is supplied (id matching takes priority).
|
|
28
|
+
*/
|
|
29
|
+
groupKey?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Determinate progress, 0–1. When set, the toast renders a progress bar.
|
|
32
|
+
* Values outside the range are clamped. Usually driven via
|
|
33
|
+
* `evoNotify.toast.progress()`, but valid on any toast.
|
|
34
|
+
*/
|
|
35
|
+
progress?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface EvoPromiseMessages<T> {
|
|
38
|
+
loading: ReactNode | EvoToastOptions;
|
|
39
|
+
success: ReactNode | ((value: T) => ReactNode | EvoToastOptions);
|
|
40
|
+
error: ReactNode | ((err: unknown) => ReactNode | EvoToastOptions);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Handle returned by `evoNotify.toast.progress()`. Drives a determinate
|
|
44
|
+
* progress bar and resolves the toast to a success or error end state.
|
|
45
|
+
*/
|
|
46
|
+
export interface EvoToastProgressHandle {
|
|
47
|
+
/** The underlying toast id — usable with `evoNotify.toast.dismiss`. */
|
|
48
|
+
readonly id: string;
|
|
49
|
+
/** Set the bar fill, 0–1 (values outside the range are clamped). */
|
|
50
|
+
setProgress: (value: number) => void;
|
|
51
|
+
/** Patch any toast option (title, description, severity, …). */
|
|
52
|
+
update: (options: EvoToastOptions) => void;
|
|
53
|
+
/** Resolve as success: bar fills to 100%, the toast then auto-dismisses. */
|
|
54
|
+
done: (options?: EvoToastOptions) => void;
|
|
55
|
+
/** Resolve as error: the toast becomes dismissible and auto-dismisses. */
|
|
56
|
+
fail: (options?: EvoToastOptions) => void;
|
|
57
|
+
/** Dismiss the toast immediately. */
|
|
58
|
+
dismiss: () => void;
|
|
59
|
+
}
|
|
60
|
+
export interface EvoInboxItemInput {
|
|
61
|
+
id?: string;
|
|
62
|
+
title: ReactNode;
|
|
63
|
+
description?: ReactNode;
|
|
64
|
+
severity?: EvoNotificationSeverity;
|
|
65
|
+
icon?: ReactNode;
|
|
66
|
+
avatarUrl?: string;
|
|
67
|
+
timestamp?: number | Date;
|
|
68
|
+
read?: boolean;
|
|
69
|
+
action?: EvoNotificationAction;
|
|
70
|
+
onClick?: (item: EvoInboxItem) => void;
|
|
71
|
+
meta?: Record<string, unknown>;
|
|
72
|
+
toast?: boolean | Partial<EvoToastOptions>;
|
|
73
|
+
}
|
|
74
|
+
export interface EvoInboxItem {
|
|
75
|
+
id: string;
|
|
76
|
+
title: ReactNode;
|
|
77
|
+
description?: ReactNode;
|
|
78
|
+
severity: EvoNotificationSeverity;
|
|
79
|
+
icon?: ReactNode;
|
|
80
|
+
avatarUrl?: string;
|
|
81
|
+
timestamp: number;
|
|
82
|
+
read: boolean;
|
|
83
|
+
action?: EvoNotificationAction;
|
|
84
|
+
onClick?: (item: EvoInboxItem) => void;
|
|
85
|
+
meta?: Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
export interface EvoNotifyAPI {
|
|
88
|
+
toast: {
|
|
89
|
+
(message: ReactNode, options?: EvoToastOptions): string;
|
|
90
|
+
success: (message: ReactNode, options?: EvoToastOptions) => string;
|
|
91
|
+
error: (message: ReactNode, options?: EvoToastOptions) => string;
|
|
92
|
+
warning: (message: ReactNode, options?: EvoToastOptions) => string;
|
|
93
|
+
info: (message: ReactNode, options?: EvoToastOptions) => string;
|
|
94
|
+
loading: (message: ReactNode, options?: EvoToastOptions) => string;
|
|
95
|
+
promise: <T>(p: Promise<T> | (() => Promise<T>), msgs: EvoPromiseMessages<T>) => string;
|
|
96
|
+
progress: (message: ReactNode, options?: EvoToastOptions) => EvoToastProgressHandle;
|
|
97
|
+
update: (id: string, options: EvoToastOptions) => void;
|
|
98
|
+
dismiss: (id?: string) => void;
|
|
99
|
+
};
|
|
100
|
+
push: (item: EvoInboxItemInput) => string;
|
|
101
|
+
inbox: {
|
|
102
|
+
markRead: (id: string) => void;
|
|
103
|
+
markUnread: (id: string) => void;
|
|
104
|
+
markAllRead: () => void;
|
|
105
|
+
remove: (id: string) => void;
|
|
106
|
+
clear: () => void;
|
|
107
|
+
setItems: (items: EvoInboxItem[]) => void;
|
|
108
|
+
getState: () => {
|
|
109
|
+
items: EvoInboxItem[];
|
|
110
|
+
unread: number;
|
|
111
|
+
};
|
|
112
|
+
subscribe: (fn: (s: {
|
|
113
|
+
items: EvoInboxItem[];
|
|
114
|
+
unread: number;
|
|
115
|
+
}) => void) => () => void;
|
|
116
|
+
};
|
|
117
|
+
dismissAll: () => void;
|
|
118
|
+
}
|
|
119
|
+
export declare const evoNotify: EvoNotifyAPI;
|
|
120
|
+
export interface EvoNotificationProviderProps {
|
|
121
|
+
children: ReactNode;
|
|
122
|
+
defaultAnchor?: EvoNotificationAnchor;
|
|
123
|
+
maxVisible?: number;
|
|
124
|
+
defaultDuration?: number;
|
|
125
|
+
pauseOnFocusLoss?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* When true, `error` toasts stay until dismissed instead of auto-closing.
|
|
128
|
+
* Recommended for accessibility — errors should not vanish on a timer.
|
|
129
|
+
* A per-toast `duration` or `persistent` still overrides this.
|
|
130
|
+
*/
|
|
131
|
+
persistErrors?: boolean;
|
|
132
|
+
inboxItems?: EvoInboxItem[];
|
|
133
|
+
onInboxChange?: (items: EvoInboxItem[]) => void;
|
|
134
|
+
}
|
|
135
|
+
export declare const EvoNotificationProvider: {
|
|
136
|
+
({ children, defaultAnchor, maxVisible, defaultDuration, pauseOnFocusLoss, persistErrors, inboxItems, onInboxChange, }: EvoNotificationProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
137
|
+
displayName: string;
|
|
138
|
+
};
|
|
139
|
+
export interface EvoNotificationToasterProps {
|
|
140
|
+
anchor?: EvoNotificationAnchor;
|
|
141
|
+
className?: string;
|
|
142
|
+
}
|
|
143
|
+
export declare const EvoNotificationToaster: {
|
|
144
|
+
({ anchor, className }: EvoNotificationToasterProps): import('react').ReactPortal | null;
|
|
145
|
+
displayName: string;
|
|
146
|
+
};
|
|
147
|
+
export interface EvoNotificationBellProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
148
|
+
variant?: 'solid' | 'ghost';
|
|
149
|
+
size?: 'sm' | 'md' | 'lg';
|
|
150
|
+
hideZero?: boolean;
|
|
151
|
+
maxBadgeCount?: number;
|
|
152
|
+
panelPlacement?: 'bottom-end' | 'bottom-start' | 'bottom' | 'top-end' | 'top-start';
|
|
153
|
+
renderPanel?: 'popover' | 'none';
|
|
154
|
+
panelTitle?: ReactNode;
|
|
155
|
+
panelEmptyState?: ReactNode;
|
|
156
|
+
}
|
|
157
|
+
export declare const EvoNotificationBell: import('react').ForwardRefExoticComponent<EvoNotificationBellProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
158
|
+
export interface EvoNotificationPanelProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
159
|
+
open?: boolean;
|
|
160
|
+
onClose?: () => void;
|
|
161
|
+
title?: ReactNode;
|
|
162
|
+
emptyState?: ReactNode;
|
|
163
|
+
loading?: boolean;
|
|
164
|
+
error?: ReactNode;
|
|
165
|
+
showMarkAllRead?: boolean;
|
|
166
|
+
maxHeight?: number | string;
|
|
167
|
+
}
|
|
168
|
+
export declare const EvoNotificationPanel: import('react').ForwardRefExoticComponent<EvoNotificationPanelProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
169
|
+
export interface EvoNotificationItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClick'> {
|
|
170
|
+
item: EvoInboxItem;
|
|
171
|
+
onClick?: (item: EvoInboxItem) => void;
|
|
172
|
+
}
|
|
173
|
+
export declare const EvoNotificationItem: import('react').ForwardRefExoticComponent<EvoNotificationItemProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
174
|
+
export declare function useEvoInbox(): {
|
|
175
|
+
items: EvoInboxItem[];
|
|
176
|
+
unread: number;
|
|
177
|
+
};
|
|
178
|
+
type EvoNotificationNS = {
|
|
179
|
+
Provider: typeof EvoNotificationProvider;
|
|
180
|
+
Toaster: typeof EvoNotificationToaster;
|
|
181
|
+
Bell: typeof EvoNotificationBell;
|
|
182
|
+
Panel: typeof EvoNotificationPanel;
|
|
183
|
+
Item: typeof EvoNotificationItem;
|
|
184
|
+
};
|
|
185
|
+
export declare const EvoNotification: EvoNotificationNS;
|
|
186
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface EvoPaginationProps {
|
|
2
|
+
total: number;
|
|
3
|
+
page: number;
|
|
4
|
+
pageSize?: number;
|
|
5
|
+
siblingCount?: number;
|
|
6
|
+
onChange: (page: number) => void;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const EvoPagination: ({ total, page, pageSize, siblingCount, onChange, className, }: EvoPaginationProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
interface EvoRadioGroupProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
name: string;
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (value: string) => void;
|
|
7
|
+
label?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
interface EvoRadioProps {
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const EvoRadio: {
|
|
17
|
+
({ value, label, disabled, className }: EvoRadioProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
Group: ({ children, name, value, onChange, label, className, }: EvoRadioGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type EvoRichTextBuiltInTool = 'bold' | 'italic' | 'underline' | 'strike' | 'h1' | 'h2' | 'h3' | 'paragraph' | 'ul' | 'ol' | 'quote' | 'code' | 'link' | 'image' | 'align-left' | 'align-center' | 'align-right' | 'clear' | 'undo' | 'redo' | 'divider';
|
|
3
|
+
export interface EvoRichTextCustomTool {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
icon: React.ReactNode;
|
|
7
|
+
onAction: (api: EvoRichTextHandle) => void;
|
|
8
|
+
isActive?: () => boolean;
|
|
9
|
+
}
|
|
10
|
+
export type EvoRichTextTool = EvoRichTextBuiltInTool | EvoRichTextCustomTool;
|
|
11
|
+
export interface EvoRichTextHandle {
|
|
12
|
+
/** Returns the current HTML content. */
|
|
13
|
+
getHTML: () => string;
|
|
14
|
+
/** Replaces the editor content with the given HTML. */
|
|
15
|
+
setHTML: (html: string) => void;
|
|
16
|
+
/** Returns the current plain text content. */
|
|
17
|
+
getText: () => string;
|
|
18
|
+
/** Focuses the editor. */
|
|
19
|
+
focus: () => void;
|
|
20
|
+
/** Inserts an image at the caret. */
|
|
21
|
+
insertImage: (src: string, alt?: string) => void;
|
|
22
|
+
/** Inserts arbitrary HTML at the caret. */
|
|
23
|
+
insertHTML: (html: string) => void;
|
|
24
|
+
/** Clears all content. */
|
|
25
|
+
clear: () => void;
|
|
26
|
+
}
|
|
27
|
+
export interface EvoRichTextAreaProps {
|
|
28
|
+
/** Controlled HTML value. */
|
|
29
|
+
value?: string;
|
|
30
|
+
/** Initial HTML for uncontrolled use. */
|
|
31
|
+
defaultValue?: string;
|
|
32
|
+
/** Fires whenever the content changes. Receives sanitized HTML. */
|
|
33
|
+
onChange?: (html: string) => void;
|
|
34
|
+
/** Which tools to render in the toolbar. Pass [] for no toolbar. */
|
|
35
|
+
tools?: EvoRichTextTool[];
|
|
36
|
+
/** Placeholder shown when empty. */
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
/** Minimum editor height (CSS). */
|
|
39
|
+
minHeight?: number | string;
|
|
40
|
+
/** Maximum editor height before it scrolls (CSS). */
|
|
41
|
+
maxHeight?: number | string;
|
|
42
|
+
/** Disables editing. */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Read-only — same look, no editing. */
|
|
45
|
+
readOnly?: boolean;
|
|
46
|
+
/** Optional label rendered above. */
|
|
47
|
+
label?: string;
|
|
48
|
+
/** Helper text rendered below (hidden if `error` set). */
|
|
49
|
+
helperText?: string;
|
|
50
|
+
/** Error message — also marks the field invalid. */
|
|
51
|
+
error?: string;
|
|
52
|
+
/** Stretch to container width. */
|
|
53
|
+
fullWidth?: boolean;
|
|
54
|
+
/** Custom upload handler. Resolve with the URL to embed. */
|
|
55
|
+
onImageUpload?: (file: File) => Promise<string>;
|
|
56
|
+
/** Accepted image MIME types for the file picker. */
|
|
57
|
+
acceptedImageTypes?: string[];
|
|
58
|
+
/** Maximum image size in bytes. Larger images are rejected. */
|
|
59
|
+
maxImageSize?: number;
|
|
60
|
+
/** Fires when an image fails validation or upload. */
|
|
61
|
+
onImageError?: (error: {
|
|
62
|
+
code: 'too-large' | 'wrong-type' | 'upload-failed';
|
|
63
|
+
message: string;
|
|
64
|
+
}) => void;
|
|
65
|
+
/** Optional class name for the root. */
|
|
66
|
+
className?: string;
|
|
67
|
+
/** Optional id (forwarded to the editable surface). */
|
|
68
|
+
id?: string;
|
|
69
|
+
}
|
|
70
|
+
export declare const EvoRichTextArea: React.ForwardRefExoticComponent<EvoRichTextAreaProps & React.RefAttributes<EvoRichTextHandle>>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface SelectOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface EvoSelectBaseProps {
|
|
10
|
+
label?: string;
|
|
11
|
+
options: SelectOption[];
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
helperText?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
size?: 'sm' | 'md' | 'lg';
|
|
16
|
+
fullWidth?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
searchable?: boolean;
|
|
19
|
+
clearable?: boolean;
|
|
20
|
+
id?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface EvoSelectSingleProps extends EvoSelectBaseProps {
|
|
25
|
+
multiple?: false;
|
|
26
|
+
value?: string;
|
|
27
|
+
defaultValue?: string;
|
|
28
|
+
onChange?: (value: string) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface EvoSelectMultipleProps extends EvoSelectBaseProps {
|
|
31
|
+
multiple: true;
|
|
32
|
+
value?: string[];
|
|
33
|
+
defaultValue?: string[];
|
|
34
|
+
onChange?: (value: string[]) => void;
|
|
35
|
+
/** How the trigger displays selected items. Defaults to 'chips'. */
|
|
36
|
+
multipleDisplay?: 'chips' | 'count';
|
|
37
|
+
/** Maximum number of options that can be selected at once. */
|
|
38
|
+
maxSelections?: number;
|
|
39
|
+
/** Show Select-all / Clear-all buttons at the top of the menu. */
|
|
40
|
+
showSelectAll?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export type EvoSelectProps = EvoSelectSingleProps | EvoSelectMultipleProps;
|
|
43
|
+
export declare const EvoSelect: (props: EvoSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface EvoSkeletonProps {
|
|
2
|
+
width?: number | string;
|
|
3
|
+
height?: number | string;
|
|
4
|
+
borderRadius?: number | string;
|
|
5
|
+
className?: string;
|
|
6
|
+
animated?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface EvoSkeletonTextProps {
|
|
9
|
+
lines?: number;
|
|
10
|
+
className?: string;
|
|
11
|
+
animated?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface EvoSkeletonCircleProps {
|
|
14
|
+
size?: number | string;
|
|
15
|
+
className?: string;
|
|
16
|
+
animated?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const EvoSkeleton: {
|
|
19
|
+
({ width, height, borderRadius, className, animated, }: EvoSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
Text: ({ lines, className, animated }: EvoSkeletonTextProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
Circle: ({ size, className, animated }: EvoSkeletonCircleProps) => import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as React, CSSProperties } from 'react';
|
|
2
|
+
type Direction = 'row' | 'column';
|
|
3
|
+
type Align = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
|
|
4
|
+
type Justify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
5
|
+
interface EvoStackProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
direction?: Direction;
|
|
8
|
+
gap?: number | string;
|
|
9
|
+
align?: Align;
|
|
10
|
+
justify?: Justify;
|
|
11
|
+
wrap?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
export declare const EvoStack: ({ children, direction, gap, align, justify, wrap, className, style, }: EvoStackProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type TableSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export type TableAlign = 'left' | 'center' | 'right';
|
|
4
|
+
export type TableSortDirection = 'asc' | 'desc';
|
|
5
|
+
export type TableResponsive = 'scroll' | 'stack';
|
|
6
|
+
export interface TableSortState {
|
|
7
|
+
key: string;
|
|
8
|
+
direction: TableSortDirection;
|
|
9
|
+
}
|
|
10
|
+
export interface TableColumn<T> {
|
|
11
|
+
/** Key in the data object. Supports dot notation for nested paths ('role.name'). */
|
|
12
|
+
key: string;
|
|
13
|
+
/** Display label or node for the column header. */
|
|
14
|
+
header: React.ReactNode;
|
|
15
|
+
/** Optional fixed width, e.g. '120px' or '10%'. */
|
|
16
|
+
width?: string;
|
|
17
|
+
/** Cell alignment. Defaults to 'left'. */
|
|
18
|
+
align?: TableAlign;
|
|
19
|
+
/** Enable click-to-sort on this column. */
|
|
20
|
+
sortable?: boolean;
|
|
21
|
+
/** Custom comparator. Falls back to a numeric-aware string compare. */
|
|
22
|
+
sortFn?: (a: T, b: T, direction: TableSortDirection) => number;
|
|
23
|
+
/** Custom cell renderer. Defaults to string coercion. */
|
|
24
|
+
render?: (value: unknown, row: T, rowIndex: number) => React.ReactNode;
|
|
25
|
+
/** Extra class for cells in this column. */
|
|
26
|
+
cellClassName?: string;
|
|
27
|
+
/** Extra class for the header cell. */
|
|
28
|
+
headerClassName?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface EvoTableProps<T extends Record<string, unknown>> {
|
|
31
|
+
/** Column definitions. */
|
|
32
|
+
columns: TableColumn<T>[];
|
|
33
|
+
/** Row data array. */
|
|
34
|
+
data: T[];
|
|
35
|
+
/** Density variant — controls cell padding and font size. Default 'md'. */
|
|
36
|
+
size?: TableSize;
|
|
37
|
+
/** Alternating row backgrounds. */
|
|
38
|
+
striped?: boolean;
|
|
39
|
+
/** Highlight rows on hover. Default true. */
|
|
40
|
+
hoverable?: boolean;
|
|
41
|
+
/** Add vertical dividers between columns. Default false. */
|
|
42
|
+
bordered?: boolean;
|
|
43
|
+
/** Keep the header pinned while the body scrolls. */
|
|
44
|
+
stickyHeader?: boolean;
|
|
45
|
+
/** Show skeleton rows in place of data. */
|
|
46
|
+
loading?: boolean;
|
|
47
|
+
/** Skeleton row count when loading. Default 5. */
|
|
48
|
+
loadingRows?: number;
|
|
49
|
+
/** Stable key for each row. Pass a property name or a getter. */
|
|
50
|
+
rowKey?: keyof T | ((row: T, index: number) => React.Key);
|
|
51
|
+
/** Custom empty-state slot. Takes priority over `emptyText`. */
|
|
52
|
+
emptyState?: React.ReactNode;
|
|
53
|
+
/** Plain-text fallback when data is empty. */
|
|
54
|
+
emptyText?: string;
|
|
55
|
+
/** Fires on single row click. */
|
|
56
|
+
onRowClick?: (row: T, index: number) => void;
|
|
57
|
+
/** Fires on row double-click. */
|
|
58
|
+
onRowDoubleClick?: (row: T, index: number) => void;
|
|
59
|
+
/** Add custom classes to specific rows. */
|
|
60
|
+
getRowClassName?: (row: T, index: number) => string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Small-viewport behaviour.
|
|
63
|
+
* - `scroll` (default): horizontal scroll with a thin scrollbar.
|
|
64
|
+
* - `stack`: under ~640px each row becomes a labelled card.
|
|
65
|
+
*/
|
|
66
|
+
responsive?: TableResponsive;
|
|
67
|
+
/** Optional caption rendered above the table. */
|
|
68
|
+
caption?: React.ReactNode;
|
|
69
|
+
/** Controlled sort state. Pair with `onSortChange`. */
|
|
70
|
+
sort?: TableSortState | null;
|
|
71
|
+
/** Sort change callback. */
|
|
72
|
+
onSortChange?: (next: TableSortState | null) => void;
|
|
73
|
+
/** Initial sort for uncontrolled mode. */
|
|
74
|
+
defaultSort?: TableSortState;
|
|
75
|
+
className?: string;
|
|
76
|
+
}
|
|
77
|
+
export declare const EvoTable: <T extends Record<string, unknown>>({ columns, data, size, striped, hoverable, bordered, stickyHeader, loading, loadingRows, rowKey, emptyState, emptyText, onRowClick, onRowDoubleClick, getRowClassName, responsive, caption, sort, onSortChange, defaultSort, className, }: EvoTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
interface EvoTabsProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
defaultTab?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
interface EvoTabsListProps {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
interface EvoTabProps {
|
|
12
|
+
id: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
interface EvoTabsPanelProps {
|
|
18
|
+
id: string;
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const EvoTabs: {
|
|
23
|
+
({ children, defaultTab, className }: EvoTabsProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
List: ({ children, className }: EvoTabsListProps) => import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
Tab: ({ id, children, disabled, className }: EvoTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
Panel: ({ id, children, className }: EvoTabsPanelProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The three theme modes EvoUI supports.
|
|
4
|
+
* - `'light'` / `'dark'` — force the theme regardless of OS preference.
|
|
5
|
+
* - `'system'` — follow the user's OS-level color-scheme preference.
|
|
6
|
+
*/
|
|
7
|
+
export type EvoTheme = 'light' | 'dark' | 'system';
|
|
8
|
+
/**
|
|
9
|
+
* The actually-applied theme after resolving `'system'` against
|
|
10
|
+
* `window.matchMedia('(prefers-color-scheme: dark)')`. Always either
|
|
11
|
+
* `'light'` or `'dark'` — never `'system'`.
|
|
12
|
+
*/
|
|
13
|
+
export type EvoResolvedTheme = 'light' | 'dark';
|
|
14
|
+
export interface EvoThemeContextValue {
|
|
15
|
+
/** The user-selected mode (may be `'system'`). */
|
|
16
|
+
theme: EvoTheme;
|
|
17
|
+
/** The mode that is actually painted right now (`'light'` or `'dark'`). */
|
|
18
|
+
resolvedTheme: EvoResolvedTheme;
|
|
19
|
+
/** Switch to a specific mode. */
|
|
20
|
+
setTheme: (theme: EvoTheme) => void;
|
|
21
|
+
/** Convenience: flip between light and dark (treats `'system'` as its resolved value). */
|
|
22
|
+
toggleTheme: () => void;
|
|
23
|
+
}
|
|
24
|
+
export interface EvoThemeProviderProps {
|
|
25
|
+
/** Subtree to provide the theme to. */
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Initial theme used before any persisted value is read.
|
|
29
|
+
* @default 'system'
|
|
30
|
+
*/
|
|
31
|
+
defaultTheme?: EvoTheme;
|
|
32
|
+
/**
|
|
33
|
+
* localStorage key used to persist the user's choice across reloads.
|
|
34
|
+
* Pass `null` to disable persistence entirely.
|
|
35
|
+
* @default 'evo-ui-theme'
|
|
36
|
+
*/
|
|
37
|
+
storageKey?: string | null;
|
|
38
|
+
/**
|
|
39
|
+
* HTML attribute written to the document root. Most apps want
|
|
40
|
+
* `'data-theme'`; pass `'class'` to instead toggle `light` / `dark`
|
|
41
|
+
* as className (useful if you're sharing tokens with Tailwind).
|
|
42
|
+
* @default 'data-theme'
|
|
43
|
+
*/
|
|
44
|
+
attribute?: 'data-theme' | 'class';
|
|
45
|
+
/**
|
|
46
|
+
* Animate color transitions when the theme flips.
|
|
47
|
+
* Automatically disabled for users with `prefers-reduced-motion`.
|
|
48
|
+
* @default true
|
|
49
|
+
*/
|
|
50
|
+
enableTransitions?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Element to apply the theme attribute to.
|
|
53
|
+
* @default document.documentElement
|
|
54
|
+
*/
|
|
55
|
+
target?: HTMLElement;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Provides EvoUI theming context to descendant components.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* import { EvoThemeProvider } from '@justin_evo/evo-ui';
|
|
63
|
+
*
|
|
64
|
+
* <EvoThemeProvider defaultTheme="system">
|
|
65
|
+
* <App />
|
|
66
|
+
* </EvoThemeProvider>
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare const EvoThemeProvider: ({ children, defaultTheme, storageKey, attribute, enableTransitions, target, }: EvoThemeProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
70
|
+
/**
|
|
71
|
+
* Read and update the EvoUI theme.
|
|
72
|
+
*
|
|
73
|
+
* Must be called from a descendant of `<EvoThemeProvider>`. If used
|
|
74
|
+
* outside the provider, returns a no-op object with `resolvedTheme`
|
|
75
|
+
* set to whatever is currently on `document.documentElement`.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* const { resolvedTheme, setTheme, toggleTheme } = useEvoTheme();
|
|
80
|
+
* <button onClick={toggleTheme}>
|
|
81
|
+
* {resolvedTheme === 'dark' ? '☀️' : '🌙'}
|
|
82
|
+
* </button>
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare const useEvoTheme: () => EvoThemeContextValue;
|
|
86
|
+
/**
|
|
87
|
+
* Inline script that applies the persisted theme before React hydrates,
|
|
88
|
+
* preventing the white-flash on first paint in dark mode. Drop into your
|
|
89
|
+
* `<head>` (or Next.js `<Script strategy="beforeInteractive">`):
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```html
|
|
93
|
+
* <script dangerouslySetInnerHTML={{ __html: getEvoThemeScript() }} />
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare const getEvoThemeScript: (storageKey?: string) => string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface EvoThemeToggleProps {
|
|
2
|
+
/** Visual size of the toggle. @default 'md' */
|
|
3
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
|
+
/** Accessible label. @default 'Toggle color theme' */
|
|
5
|
+
ariaLabel?: string;
|
|
6
|
+
/** Extra className to merge with the built-in styles. */
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A drop-in button that flips between light and dark mode.
|
|
11
|
+
*
|
|
12
|
+
* Sits inside an `<EvoThemeProvider>`. The icon and animation
|
|
13
|
+
* automatically reflect the resolved theme.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <EvoThemeProvider>
|
|
18
|
+
* <EvoThemeToggle />
|
|
19
|
+
* </EvoThemeProvider>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const EvoThemeToggle: ({ size, ariaLabel, className, }: EvoThemeToggleProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type ToggleSize = 'sm' | 'md' | 'lg';
|
|
2
|
+
interface EvoToggleProps {
|
|
3
|
+
checked: boolean;
|
|
4
|
+
onChange: (checked: boolean) => void;
|
|
5
|
+
label?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
size?: ToggleSize;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const EvoToggle: ({ checked, onChange, label, disabled, size, className, }: EvoToggleProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
3
|
+
interface EvoTooltipProps {
|
|
4
|
+
content: React.ReactNode;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
placement?: TooltipPlacement;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const EvoTooltip: ({ content, children, placement, className, }: EvoTooltipProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|