@djangocfg/ui-core 2.1.102 → 2.1.103

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.
@@ -0,0 +1,190 @@
1
+ import { toast } from 'sonner';
2
+ export { toast } from 'sonner';
3
+
4
+ interface CountdownState {
5
+ days: number;
6
+ hours: number;
7
+ minutes: number;
8
+ seconds: number;
9
+ isExpired: boolean;
10
+ totalSeconds: number;
11
+ }
12
+ declare const useCountdown: (targetDate: string | null) => CountdownState;
13
+
14
+ /**
15
+ * Creates a debounced version of a callback function.
16
+ *
17
+ * @param callback The function to debounce.
18
+ * @param delay The debounce delay in milliseconds.
19
+ * @returns A debounced callback function.
20
+ */
21
+ declare function useDebouncedCallback<T extends (...args: any[]) => any>(callback: T, delay: number): (...args: Parameters<T>) => void;
22
+
23
+ /**
24
+ * useDebounce hook
25
+ *
26
+ * Debounces a value by delaying its update until after a specified delay.
27
+ */
28
+ declare function useDebounce<T>(value: T, delay?: number): T;
29
+
30
+ type DebugValue = Record<string, unknown> | unknown[] | null | undefined;
31
+ declare function useDebugTools(values: DebugValue, prefix?: string): void;
32
+
33
+ type FormEvent<T extends string = string, P = any> = {
34
+ type: T;
35
+ payload?: P;
36
+ timestamp?: number;
37
+ };
38
+ type EventListener<T extends FormEvent> = (event: T) => void;
39
+ declare class EventBus {
40
+ private listeners;
41
+ publish<T extends FormEvent>(event: T): void;
42
+ subscribe<T extends FormEvent>(listener: EventListener<T>): () => void;
43
+ }
44
+ declare const events: EventBus;
45
+ declare function useEventListener<T extends string, P>(eventType: T, handler: (payload: P) => void): void;
46
+
47
+ declare function useIsMobile(): boolean;
48
+
49
+ /**
50
+ * Hook to check if a media query matches
51
+ *
52
+ * @param query - CSS media query string
53
+ * @returns boolean indicating if the query matches
54
+ *
55
+ * @example
56
+ * const isMobile = useMediaQuery('(max-width: 768px)');
57
+ * const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
58
+ * const isLandscape = useMediaQuery('(orientation: landscape)');
59
+ */
60
+ declare function useMediaQuery(query: string): boolean;
61
+
62
+ interface UseCopyOptions {
63
+ successMessage?: string;
64
+ errorMessage?: string;
65
+ }
66
+ declare const useCopy: (options?: UseCopyOptions) => {
67
+ copyToClipboard: (text: string, customSuccessMessage?: string) => Promise<boolean>;
68
+ };
69
+
70
+ /**
71
+ * Enhanced Image Loader Hook
72
+ *
73
+ * Hook to check if an image is loaded successfully with callback support
74
+ */
75
+ interface ImageLoaderState {
76
+ isLoading: boolean;
77
+ isLoaded: boolean;
78
+ hasError: boolean;
79
+ }
80
+ interface ImageLoaderCallbacks {
81
+ onLoadStart?: () => void;
82
+ onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
83
+ onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
84
+ }
85
+ declare const useImageLoader: (src?: string, callbacks?: ImageLoaderCallbacks) => ImageLoaderState;
86
+
87
+ /**
88
+ * Toast notifications using Sonner
89
+ *
90
+ * @example
91
+ * import { toast } from '@djangocfg/ui-core/hooks';
92
+ *
93
+ * toast.success('Saved!');
94
+ * toast.error('Error', { description: 'Details here' });
95
+ * toast.promise(fetchData(), { loading: 'Loading...', success: 'Done!', error: 'Failed' });
96
+ */
97
+
98
+ type ToastFn = typeof toast;
99
+ declare function useToast(): {
100
+ toast: ToastFn;
101
+ dismiss: ToastFn['dismiss'];
102
+ };
103
+
104
+ type ResolvedTheme = 'light' | 'dark';
105
+ /**
106
+ * Hook to detect the current resolved theme (light or dark)
107
+ *
108
+ * Standalone hook - doesn't require ThemeProvider.
109
+ * Detects theme from:
110
+ * 1. 'dark' class on html element
111
+ * 2. System preference (prefers-color-scheme)
112
+ *
113
+ * For full theme control (setTheme, toggleTheme), use useThemeContext instead.
114
+ *
115
+ * @example
116
+ * ```tsx
117
+ * const theme = useResolvedTheme(); // 'light' | 'dark'
118
+ * ```
119
+ */
120
+ declare const useResolvedTheme: () => ResolvedTheme;
121
+
122
+ /**
123
+ * Options for useLocalStorage hook
124
+ */
125
+ interface UseLocalStorageOptions {
126
+ /**
127
+ * Time-to-live in milliseconds.
128
+ * After this time, value is considered expired and initialValue is returned.
129
+ * Data is automatically cleaned up on next read.
130
+ * @example 24 * 60 * 60 * 1000 // 24 hours
131
+ */
132
+ ttl?: number;
133
+ }
134
+ /**
135
+ * Simple localStorage hook with better error handling and optional TTL support
136
+ *
137
+ * IMPORTANT: To prevent hydration mismatch, this hook:
138
+ * - Always returns initialValue on first render (same as SSR)
139
+ * - Reads from localStorage only after component mounts
140
+ *
141
+ * @param key - Storage key
142
+ * @param initialValue - Default value if key doesn't exist
143
+ * @param options - Optional configuration (ttl for auto-expiration)
144
+ * @returns [value, setValue, removeValue] - Current value, setter function, and remove function
145
+ *
146
+ * @example
147
+ * // Without TTL (backwards compatible)
148
+ * const [value, setValue] = useLocalStorage('key', 'default');
149
+ *
150
+ * @example
151
+ * // With TTL (24 hours)
152
+ * const [value, setValue] = useLocalStorage('key', 'default', {
153
+ * ttl: 24 * 60 * 60 * 1000
154
+ * });
155
+ */
156
+ declare function useLocalStorage<T>(key: string, initialValue: T, options?: UseLocalStorageOptions): readonly [T, (value: T | ((val: T) => T)) => void, () => void];
157
+
158
+ /**
159
+ * Options for useSessionStorage hook
160
+ */
161
+ interface UseSessionStorageOptions {
162
+ /**
163
+ * Time-to-live in milliseconds.
164
+ * After this time, value is considered expired and initialValue is returned.
165
+ * Data is automatically cleaned up on next read.
166
+ * @example 24 * 60 * 60 * 1000 // 24 hours
167
+ */
168
+ ttl?: number;
169
+ }
170
+ /**
171
+ * Simple sessionStorage hook with better error handling and optional TTL support
172
+ *
173
+ * @param key - Storage key
174
+ * @param initialValue - Default value if key doesn't exist
175
+ * @param options - Optional configuration (ttl for auto-expiration)
176
+ * @returns [value, setValue, removeValue] - Current value, setter function, and remove function
177
+ *
178
+ * @example
179
+ * // Without TTL (backwards compatible)
180
+ * const [value, setValue] = useSessionStorage('key', 'default');
181
+ *
182
+ * @example
183
+ * // With TTL (1 hour)
184
+ * const [value, setValue] = useSessionStorage('key', 'default', {
185
+ * ttl: 60 * 60 * 1000
186
+ * });
187
+ */
188
+ declare function useSessionStorage<T>(key: string, initialValue: T, options?: UseSessionStorageOptions): readonly [T, (value: T | ((val: T) => T)) => void, () => void];
189
+
190
+ export { type ResolvedTheme, events, useCopy, useCountdown, useDebounce, useDebouncedCallback, useDebugTools, useEventListener, useImageLoader, useIsMobile, useLocalStorage, useMediaQuery, useResolvedTheme, useSessionStorage, useToast };
@@ -0,0 +1,190 @@
1
+ import { toast } from 'sonner';
2
+ export { toast } from 'sonner';
3
+
4
+ interface CountdownState {
5
+ days: number;
6
+ hours: number;
7
+ minutes: number;
8
+ seconds: number;
9
+ isExpired: boolean;
10
+ totalSeconds: number;
11
+ }
12
+ declare const useCountdown: (targetDate: string | null) => CountdownState;
13
+
14
+ /**
15
+ * Creates a debounced version of a callback function.
16
+ *
17
+ * @param callback The function to debounce.
18
+ * @param delay The debounce delay in milliseconds.
19
+ * @returns A debounced callback function.
20
+ */
21
+ declare function useDebouncedCallback<T extends (...args: any[]) => any>(callback: T, delay: number): (...args: Parameters<T>) => void;
22
+
23
+ /**
24
+ * useDebounce hook
25
+ *
26
+ * Debounces a value by delaying its update until after a specified delay.
27
+ */
28
+ declare function useDebounce<T>(value: T, delay?: number): T;
29
+
30
+ type DebugValue = Record<string, unknown> | unknown[] | null | undefined;
31
+ declare function useDebugTools(values: DebugValue, prefix?: string): void;
32
+
33
+ type FormEvent<T extends string = string, P = any> = {
34
+ type: T;
35
+ payload?: P;
36
+ timestamp?: number;
37
+ };
38
+ type EventListener<T extends FormEvent> = (event: T) => void;
39
+ declare class EventBus {
40
+ private listeners;
41
+ publish<T extends FormEvent>(event: T): void;
42
+ subscribe<T extends FormEvent>(listener: EventListener<T>): () => void;
43
+ }
44
+ declare const events: EventBus;
45
+ declare function useEventListener<T extends string, P>(eventType: T, handler: (payload: P) => void): void;
46
+
47
+ declare function useIsMobile(): boolean;
48
+
49
+ /**
50
+ * Hook to check if a media query matches
51
+ *
52
+ * @param query - CSS media query string
53
+ * @returns boolean indicating if the query matches
54
+ *
55
+ * @example
56
+ * const isMobile = useMediaQuery('(max-width: 768px)');
57
+ * const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
58
+ * const isLandscape = useMediaQuery('(orientation: landscape)');
59
+ */
60
+ declare function useMediaQuery(query: string): boolean;
61
+
62
+ interface UseCopyOptions {
63
+ successMessage?: string;
64
+ errorMessage?: string;
65
+ }
66
+ declare const useCopy: (options?: UseCopyOptions) => {
67
+ copyToClipboard: (text: string, customSuccessMessage?: string) => Promise<boolean>;
68
+ };
69
+
70
+ /**
71
+ * Enhanced Image Loader Hook
72
+ *
73
+ * Hook to check if an image is loaded successfully with callback support
74
+ */
75
+ interface ImageLoaderState {
76
+ isLoading: boolean;
77
+ isLoaded: boolean;
78
+ hasError: boolean;
79
+ }
80
+ interface ImageLoaderCallbacks {
81
+ onLoadStart?: () => void;
82
+ onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
83
+ onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
84
+ }
85
+ declare const useImageLoader: (src?: string, callbacks?: ImageLoaderCallbacks) => ImageLoaderState;
86
+
87
+ /**
88
+ * Toast notifications using Sonner
89
+ *
90
+ * @example
91
+ * import { toast } from '@djangocfg/ui-core/hooks';
92
+ *
93
+ * toast.success('Saved!');
94
+ * toast.error('Error', { description: 'Details here' });
95
+ * toast.promise(fetchData(), { loading: 'Loading...', success: 'Done!', error: 'Failed' });
96
+ */
97
+
98
+ type ToastFn = typeof toast;
99
+ declare function useToast(): {
100
+ toast: ToastFn;
101
+ dismiss: ToastFn['dismiss'];
102
+ };
103
+
104
+ type ResolvedTheme = 'light' | 'dark';
105
+ /**
106
+ * Hook to detect the current resolved theme (light or dark)
107
+ *
108
+ * Standalone hook - doesn't require ThemeProvider.
109
+ * Detects theme from:
110
+ * 1. 'dark' class on html element
111
+ * 2. System preference (prefers-color-scheme)
112
+ *
113
+ * For full theme control (setTheme, toggleTheme), use useThemeContext instead.
114
+ *
115
+ * @example
116
+ * ```tsx
117
+ * const theme = useResolvedTheme(); // 'light' | 'dark'
118
+ * ```
119
+ */
120
+ declare const useResolvedTheme: () => ResolvedTheme;
121
+
122
+ /**
123
+ * Options for useLocalStorage hook
124
+ */
125
+ interface UseLocalStorageOptions {
126
+ /**
127
+ * Time-to-live in milliseconds.
128
+ * After this time, value is considered expired and initialValue is returned.
129
+ * Data is automatically cleaned up on next read.
130
+ * @example 24 * 60 * 60 * 1000 // 24 hours
131
+ */
132
+ ttl?: number;
133
+ }
134
+ /**
135
+ * Simple localStorage hook with better error handling and optional TTL support
136
+ *
137
+ * IMPORTANT: To prevent hydration mismatch, this hook:
138
+ * - Always returns initialValue on first render (same as SSR)
139
+ * - Reads from localStorage only after component mounts
140
+ *
141
+ * @param key - Storage key
142
+ * @param initialValue - Default value if key doesn't exist
143
+ * @param options - Optional configuration (ttl for auto-expiration)
144
+ * @returns [value, setValue, removeValue] - Current value, setter function, and remove function
145
+ *
146
+ * @example
147
+ * // Without TTL (backwards compatible)
148
+ * const [value, setValue] = useLocalStorage('key', 'default');
149
+ *
150
+ * @example
151
+ * // With TTL (24 hours)
152
+ * const [value, setValue] = useLocalStorage('key', 'default', {
153
+ * ttl: 24 * 60 * 60 * 1000
154
+ * });
155
+ */
156
+ declare function useLocalStorage<T>(key: string, initialValue: T, options?: UseLocalStorageOptions): readonly [T, (value: T | ((val: T) => T)) => void, () => void];
157
+
158
+ /**
159
+ * Options for useSessionStorage hook
160
+ */
161
+ interface UseSessionStorageOptions {
162
+ /**
163
+ * Time-to-live in milliseconds.
164
+ * After this time, value is considered expired and initialValue is returned.
165
+ * Data is automatically cleaned up on next read.
166
+ * @example 24 * 60 * 60 * 1000 // 24 hours
167
+ */
168
+ ttl?: number;
169
+ }
170
+ /**
171
+ * Simple sessionStorage hook with better error handling and optional TTL support
172
+ *
173
+ * @param key - Storage key
174
+ * @param initialValue - Default value if key doesn't exist
175
+ * @param options - Optional configuration (ttl for auto-expiration)
176
+ * @returns [value, setValue, removeValue] - Current value, setter function, and remove function
177
+ *
178
+ * @example
179
+ * // Without TTL (backwards compatible)
180
+ * const [value, setValue] = useSessionStorage('key', 'default');
181
+ *
182
+ * @example
183
+ * // With TTL (1 hour)
184
+ * const [value, setValue] = useSessionStorage('key', 'default', {
185
+ * ttl: 60 * 60 * 1000
186
+ * });
187
+ */
188
+ declare function useSessionStorage<T>(key: string, initialValue: T, options?: UseSessionStorageOptions): readonly [T, (value: T | ((val: T) => T)) => void, () => void];
189
+
190
+ export { type ResolvedTheme, events, useCopy, useCountdown, useDebounce, useDebouncedCallback, useDebugTools, useEventListener, useImageLoader, useIsMobile, useLocalStorage, useMediaQuery, useResolvedTheme, useSessionStorage, useToast };
package/dist/lib.d.mts ADDED
@@ -0,0 +1,206 @@
1
+ import { ClassValue } from 'clsx';
2
+ import * as zustand from 'zustand';
3
+
4
+ declare function cn(...inputs: ClassValue[]): string;
5
+
6
+ /**
7
+ * OG Image URL Generation Utilities
8
+ *
9
+ * Client-side utilities for generating OG image URLs.
10
+ */
11
+ /**
12
+ * OG Image URL parameters
13
+ */
14
+ interface OgImageUrlParams {
15
+ /** Page title */
16
+ title: string;
17
+ /** Page description (optional) */
18
+ description?: string;
19
+ /** Site name (optional) */
20
+ siteName?: string;
21
+ /** Logo URL (optional) */
22
+ logo?: string;
23
+ /** Background type: 'gradient' or 'solid' */
24
+ backgroundType?: 'gradient' | 'solid';
25
+ /** Gradient start color (hex) */
26
+ gradientStart?: string;
27
+ /** Gradient end color (hex) */
28
+ gradientEnd?: string;
29
+ /** Background color (for solid type) */
30
+ backgroundColor?: string;
31
+ /** Title font size (px) */
32
+ titleSize?: number;
33
+ /** Title font weight */
34
+ titleWeight?: number;
35
+ /** Title text color */
36
+ titleColor?: string;
37
+ /** Description font size (px) */
38
+ descriptionSize?: number;
39
+ /** Description text color */
40
+ descriptionColor?: string;
41
+ /** Site name font size (px) */
42
+ siteNameSize?: number;
43
+ /** Site name text color */
44
+ siteNameColor?: string;
45
+ /** Padding (px) */
46
+ padding?: number;
47
+ /** Logo size (px) */
48
+ logoSize?: number;
49
+ /** Show logo flag */
50
+ showLogo?: boolean;
51
+ /** Show site name flag */
52
+ showSiteName?: boolean;
53
+ /** Additional custom parameters */
54
+ [key: string]: string | number | boolean | undefined;
55
+ }
56
+ /**
57
+ * Options for generating OG image URL
58
+ */
59
+ interface GenerateOgImageUrlOptions {
60
+ /**
61
+ * Base URL of the OG image API route
62
+ * @default 'https://djangocfg.com/api/og'
63
+ */
64
+ baseUrl?: string;
65
+ /**
66
+ * If true, encode params as base64 for safer URLs
67
+ * @default true
68
+ */
69
+ useBase64?: boolean;
70
+ }
71
+ /**
72
+ * Generate OG image URL with query parameters or base64 encoding
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // Using default baseUrl (https://djangocfg.com/api/og)
77
+ * const url = generateOgImageUrl({ title: 'My Page Title' });
78
+ *
79
+ * // With custom baseUrl
80
+ * const url = generateOgImageUrl({ title: 'My Page' }, { baseUrl: '/api/og' });
81
+ * ```
82
+ */
83
+ declare function generateOgImageUrl(params: OgImageUrlParams, options?: GenerateOgImageUrlOptions): string;
84
+ /**
85
+ * Get absolute OG image URL from relative path
86
+ */
87
+ declare function getAbsoluteOgImageUrl(relativePath: string, siteUrl: string): string;
88
+ /**
89
+ * Create OG image URL builder with preset configuration
90
+ */
91
+ declare function createOgImageUrlBuilder(defaults?: Partial<OgImageUrlParams>, options?: GenerateOgImageUrlOptions): (params: OgImageUrlParams) => string;
92
+
93
+ /**
94
+ * Logger Types
95
+ *
96
+ * Type definitions for the universal logging system.
97
+ * Compatible with Console panel in FileWorkspace IDE layout.
98
+ */
99
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success';
100
+ interface LogEntry {
101
+ /** Unique log ID */
102
+ id: string;
103
+ /** Timestamp when log was created */
104
+ timestamp: Date;
105
+ /** Log level */
106
+ level: LogLevel;
107
+ /** Component/module name that created the log */
108
+ component: string;
109
+ /** Log message */
110
+ message: string;
111
+ /** Additional data (objects, errors, etc.) */
112
+ data?: Record<string, unknown>;
113
+ /** Error stack trace (for error level) */
114
+ stack?: string;
115
+ }
116
+ interface LogFilter {
117
+ /** Filter by log levels */
118
+ levels: LogLevel[];
119
+ /** Filter by component name (partial match) */
120
+ component?: string;
121
+ /** Filter by message text (partial match) */
122
+ search?: string;
123
+ /** Filter by time range */
124
+ since?: Date;
125
+ }
126
+ interface LogStore {
127
+ /** All accumulated logs */
128
+ logs: LogEntry[];
129
+ /** Current filter settings */
130
+ filter: LogFilter;
131
+ /** Maximum logs to keep */
132
+ maxLogs: number;
133
+ /** Add new log entry */
134
+ addLog: (entry: Omit<LogEntry, 'id' | 'timestamp'>) => void;
135
+ /** Clear all logs */
136
+ clearLogs: () => void;
137
+ /** Update filter settings */
138
+ setFilter: (filter: Partial<LogFilter>) => void;
139
+ /** Reset filter to defaults */
140
+ resetFilter: () => void;
141
+ /** Get filtered logs */
142
+ getFilteredLogs: () => LogEntry[];
143
+ /** Export logs as JSON string */
144
+ exportLogs: () => string;
145
+ }
146
+ interface Logger {
147
+ debug: (message: string, data?: Record<string, unknown>) => void;
148
+ info: (message: string, data?: Record<string, unknown>) => void;
149
+ warn: (message: string, data?: Record<string, unknown>) => void;
150
+ error: (message: string, data?: Record<string, unknown>) => void;
151
+ success: (message: string, data?: Record<string, unknown>) => void;
152
+ }
153
+ /**
154
+ * Media-specific log helper methods
155
+ */
156
+ interface MediaLogger extends Logger {
157
+ /** Log source load event */
158
+ load: (src: string, type?: string) => void;
159
+ /** Log state change */
160
+ state: (state: string, details?: Record<string, unknown>) => void;
161
+ /** Log seek event */
162
+ seek: (from: number, to: number, duration: number) => void;
163
+ /** Log buffer ranges */
164
+ buffer: (buffered: TimeRanges, duration: number) => void;
165
+ /** Log generic event */
166
+ event: (name: string, data?: unknown) => void;
167
+ }
168
+
169
+ /**
170
+ * Logger
171
+ *
172
+ * Universal logger with consola + zustand store integration.
173
+ * Logs are accumulated for Console panel display.
174
+ * In production, only logs to store (no console output).
175
+ */
176
+
177
+ /**
178
+ * Create a logger for a specific component/module
179
+ */
180
+ declare function createLogger(component: string): Logger;
181
+ /**
182
+ * Create a media-specific logger with helper methods
183
+ * for AudioPlayer, VideoPlayer, ImageViewer
184
+ */
185
+ declare function createMediaLogger(component: string): MediaLogger;
186
+ /**
187
+ * Global logger for non-component code
188
+ */
189
+ declare const logger: Logger;
190
+ /**
191
+ * Quick access for one-off logs
192
+ */
193
+ declare const log: {
194
+ debug: (component: string, message: string, data?: Record<string, unknown>) => void;
195
+ info: (component: string, message: string, data?: Record<string, unknown>) => void;
196
+ warn: (component: string, message: string, data?: Record<string, unknown>) => void;
197
+ error: (component: string, message: string, data?: Record<string, unknown>) => void;
198
+ success: (component: string, message: string, data?: Record<string, unknown>) => void;
199
+ };
200
+
201
+ declare const useLogStore: zustand.UseBoundStore<zustand.StoreApi<LogStore>>;
202
+ declare const useFilteredLogs: () => LogEntry[];
203
+ declare const useLogCount: () => number;
204
+ declare const useErrorCount: () => number;
205
+
206
+ export { type GenerateOgImageUrlOptions, type LogEntry, type LogFilter, type LogLevel, type LogStore, type Logger, type MediaLogger, type OgImageUrlParams, cn, createLogger, createMediaLogger, createOgImageUrlBuilder, generateOgImageUrl, getAbsoluteOgImageUrl, log, logger, useErrorCount, useFilteredLogs, useLogCount, useLogStore };
package/dist/lib.d.ts ADDED
@@ -0,0 +1,206 @@
1
+ import { ClassValue } from 'clsx';
2
+ import * as zustand from 'zustand';
3
+
4
+ declare function cn(...inputs: ClassValue[]): string;
5
+
6
+ /**
7
+ * OG Image URL Generation Utilities
8
+ *
9
+ * Client-side utilities for generating OG image URLs.
10
+ */
11
+ /**
12
+ * OG Image URL parameters
13
+ */
14
+ interface OgImageUrlParams {
15
+ /** Page title */
16
+ title: string;
17
+ /** Page description (optional) */
18
+ description?: string;
19
+ /** Site name (optional) */
20
+ siteName?: string;
21
+ /** Logo URL (optional) */
22
+ logo?: string;
23
+ /** Background type: 'gradient' or 'solid' */
24
+ backgroundType?: 'gradient' | 'solid';
25
+ /** Gradient start color (hex) */
26
+ gradientStart?: string;
27
+ /** Gradient end color (hex) */
28
+ gradientEnd?: string;
29
+ /** Background color (for solid type) */
30
+ backgroundColor?: string;
31
+ /** Title font size (px) */
32
+ titleSize?: number;
33
+ /** Title font weight */
34
+ titleWeight?: number;
35
+ /** Title text color */
36
+ titleColor?: string;
37
+ /** Description font size (px) */
38
+ descriptionSize?: number;
39
+ /** Description text color */
40
+ descriptionColor?: string;
41
+ /** Site name font size (px) */
42
+ siteNameSize?: number;
43
+ /** Site name text color */
44
+ siteNameColor?: string;
45
+ /** Padding (px) */
46
+ padding?: number;
47
+ /** Logo size (px) */
48
+ logoSize?: number;
49
+ /** Show logo flag */
50
+ showLogo?: boolean;
51
+ /** Show site name flag */
52
+ showSiteName?: boolean;
53
+ /** Additional custom parameters */
54
+ [key: string]: string | number | boolean | undefined;
55
+ }
56
+ /**
57
+ * Options for generating OG image URL
58
+ */
59
+ interface GenerateOgImageUrlOptions {
60
+ /**
61
+ * Base URL of the OG image API route
62
+ * @default 'https://djangocfg.com/api/og'
63
+ */
64
+ baseUrl?: string;
65
+ /**
66
+ * If true, encode params as base64 for safer URLs
67
+ * @default true
68
+ */
69
+ useBase64?: boolean;
70
+ }
71
+ /**
72
+ * Generate OG image URL with query parameters or base64 encoding
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // Using default baseUrl (https://djangocfg.com/api/og)
77
+ * const url = generateOgImageUrl({ title: 'My Page Title' });
78
+ *
79
+ * // With custom baseUrl
80
+ * const url = generateOgImageUrl({ title: 'My Page' }, { baseUrl: '/api/og' });
81
+ * ```
82
+ */
83
+ declare function generateOgImageUrl(params: OgImageUrlParams, options?: GenerateOgImageUrlOptions): string;
84
+ /**
85
+ * Get absolute OG image URL from relative path
86
+ */
87
+ declare function getAbsoluteOgImageUrl(relativePath: string, siteUrl: string): string;
88
+ /**
89
+ * Create OG image URL builder with preset configuration
90
+ */
91
+ declare function createOgImageUrlBuilder(defaults?: Partial<OgImageUrlParams>, options?: GenerateOgImageUrlOptions): (params: OgImageUrlParams) => string;
92
+
93
+ /**
94
+ * Logger Types
95
+ *
96
+ * Type definitions for the universal logging system.
97
+ * Compatible with Console panel in FileWorkspace IDE layout.
98
+ */
99
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success';
100
+ interface LogEntry {
101
+ /** Unique log ID */
102
+ id: string;
103
+ /** Timestamp when log was created */
104
+ timestamp: Date;
105
+ /** Log level */
106
+ level: LogLevel;
107
+ /** Component/module name that created the log */
108
+ component: string;
109
+ /** Log message */
110
+ message: string;
111
+ /** Additional data (objects, errors, etc.) */
112
+ data?: Record<string, unknown>;
113
+ /** Error stack trace (for error level) */
114
+ stack?: string;
115
+ }
116
+ interface LogFilter {
117
+ /** Filter by log levels */
118
+ levels: LogLevel[];
119
+ /** Filter by component name (partial match) */
120
+ component?: string;
121
+ /** Filter by message text (partial match) */
122
+ search?: string;
123
+ /** Filter by time range */
124
+ since?: Date;
125
+ }
126
+ interface LogStore {
127
+ /** All accumulated logs */
128
+ logs: LogEntry[];
129
+ /** Current filter settings */
130
+ filter: LogFilter;
131
+ /** Maximum logs to keep */
132
+ maxLogs: number;
133
+ /** Add new log entry */
134
+ addLog: (entry: Omit<LogEntry, 'id' | 'timestamp'>) => void;
135
+ /** Clear all logs */
136
+ clearLogs: () => void;
137
+ /** Update filter settings */
138
+ setFilter: (filter: Partial<LogFilter>) => void;
139
+ /** Reset filter to defaults */
140
+ resetFilter: () => void;
141
+ /** Get filtered logs */
142
+ getFilteredLogs: () => LogEntry[];
143
+ /** Export logs as JSON string */
144
+ exportLogs: () => string;
145
+ }
146
+ interface Logger {
147
+ debug: (message: string, data?: Record<string, unknown>) => void;
148
+ info: (message: string, data?: Record<string, unknown>) => void;
149
+ warn: (message: string, data?: Record<string, unknown>) => void;
150
+ error: (message: string, data?: Record<string, unknown>) => void;
151
+ success: (message: string, data?: Record<string, unknown>) => void;
152
+ }
153
+ /**
154
+ * Media-specific log helper methods
155
+ */
156
+ interface MediaLogger extends Logger {
157
+ /** Log source load event */
158
+ load: (src: string, type?: string) => void;
159
+ /** Log state change */
160
+ state: (state: string, details?: Record<string, unknown>) => void;
161
+ /** Log seek event */
162
+ seek: (from: number, to: number, duration: number) => void;
163
+ /** Log buffer ranges */
164
+ buffer: (buffered: TimeRanges, duration: number) => void;
165
+ /** Log generic event */
166
+ event: (name: string, data?: unknown) => void;
167
+ }
168
+
169
+ /**
170
+ * Logger
171
+ *
172
+ * Universal logger with consola + zustand store integration.
173
+ * Logs are accumulated for Console panel display.
174
+ * In production, only logs to store (no console output).
175
+ */
176
+
177
+ /**
178
+ * Create a logger for a specific component/module
179
+ */
180
+ declare function createLogger(component: string): Logger;
181
+ /**
182
+ * Create a media-specific logger with helper methods
183
+ * for AudioPlayer, VideoPlayer, ImageViewer
184
+ */
185
+ declare function createMediaLogger(component: string): MediaLogger;
186
+ /**
187
+ * Global logger for non-component code
188
+ */
189
+ declare const logger: Logger;
190
+ /**
191
+ * Quick access for one-off logs
192
+ */
193
+ declare const log: {
194
+ debug: (component: string, message: string, data?: Record<string, unknown>) => void;
195
+ info: (component: string, message: string, data?: Record<string, unknown>) => void;
196
+ warn: (component: string, message: string, data?: Record<string, unknown>) => void;
197
+ error: (component: string, message: string, data?: Record<string, unknown>) => void;
198
+ success: (component: string, message: string, data?: Record<string, unknown>) => void;
199
+ };
200
+
201
+ declare const useLogStore: zustand.UseBoundStore<zustand.StoreApi<LogStore>>;
202
+ declare const useFilteredLogs: () => LogEntry[];
203
+ declare const useLogCount: () => number;
204
+ declare const useErrorCount: () => number;
205
+
206
+ export { type GenerateOgImageUrlOptions, type LogEntry, type LogFilter, type LogLevel, type LogStore, type Logger, type MediaLogger, type OgImageUrlParams, cn, createLogger, createMediaLogger, createOgImageUrlBuilder, generateOgImageUrl, getAbsoluteOgImageUrl, log, logger, useErrorCount, useFilteredLogs, useLogCount, useLogStore };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-core",
3
- "version": "2.1.102",
3
+ "version": "2.1.103",
4
4
  "description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -125,7 +125,7 @@
125
125
  "vaul": "1.1.2"
126
126
  },
127
127
  "devDependencies": {
128
- "@djangocfg/typescript-config": "^2.1.102",
128
+ "@djangocfg/typescript-config": "^2.1.103",
129
129
  "@types/node": "^24.7.2",
130
130
  "@types/react": "^19.1.0",
131
131
  "@types/react-dom": "^19.1.0",