@chaos_team/chaos-ui 1.0.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 (49) hide show
  1. package/CHANGELOG.md +286 -0
  2. package/LICENSE +21 -0
  3. package/README.md +295 -0
  4. package/THIRD_PARTY_NOTICES.md +22 -0
  5. package/dist/business.cjs +26 -0
  6. package/dist/business.d.cts +10311 -0
  7. package/dist/business.d.ts +10311 -0
  8. package/dist/business.js +26 -0
  9. package/dist/format-BUpOzeCo.d.cts +8 -0
  10. package/dist/format-BUpOzeCo.d.ts +8 -0
  11. package/dist/hooks.cjs +8 -0
  12. package/dist/hooks.d.cts +1148 -0
  13. package/dist/hooks.d.ts +1148 -0
  14. package/dist/hooks.js +8 -0
  15. package/dist/index.cjs +6 -0
  16. package/dist/index.d.cts +5616 -0
  17. package/dist/index.d.ts +5616 -0
  18. package/dist/index.js +6 -0
  19. package/dist/lib.cjs +42 -0
  20. package/dist/lib.d.cts +804 -0
  21. package/dist/lib.d.ts +804 -0
  22. package/dist/lib.js +42 -0
  23. package/dist/message-KJli9tvf.d.cts +71 -0
  24. package/dist/message-KJli9tvf.d.ts +71 -0
  25. package/dist/message-provider-BI-P3CNq.d.cts +11 -0
  26. package/dist/message-provider-BI-P3CNq.d.ts +11 -0
  27. package/dist/next.cjs +6 -0
  28. package/dist/next.d.cts +103 -0
  29. package/dist/next.d.ts +103 -0
  30. package/dist/next.js +6 -0
  31. package/dist/theme-toggle-JL_jZE-w.d.cts +81 -0
  32. package/dist/theme-toggle-JL_jZE-w.d.ts +81 -0
  33. package/dist/time-picker-H1AaecnE.d.cts +452 -0
  34. package/dist/time-picker-H1AaecnE.d.ts +452 -0
  35. package/dist/ui/icons.cjs +6 -0
  36. package/dist/ui/icons.d.cts +3 -0
  37. package/dist/ui/icons.d.ts +3 -0
  38. package/dist/ui/icons.js +6 -0
  39. package/dist/ui-icons.cjs +6 -0
  40. package/dist/ui-icons.d.cts +205 -0
  41. package/dist/ui-icons.d.ts +205 -0
  42. package/dist/ui-icons.js +6 -0
  43. package/dist/ui.cjs +6 -0
  44. package/dist/ui.d.cts +39 -0
  45. package/dist/ui.d.ts +39 -0
  46. package/dist/ui.js +6 -0
  47. package/package.json +265 -0
  48. package/styles.css +1300 -0
  49. package/styles.css.d.ts +11 -0
@@ -0,0 +1,1148 @@
1
+ import { M as MessageOptions } from './message-KJli9tvf.js';
2
+ import * as React$1 from 'react';
3
+ import * as react_hook_form from 'react-hook-form';
4
+ import { FieldValues, UseFormProps, Resolver } from 'react-hook-form';
5
+ import { UseQueryOptions, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
6
+ export { UseMutationOptions, UseMutationResult, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
7
+
8
+ /**
9
+ * @hook useBreakpoint
10
+ * @category hooks/responsive
11
+ * @since 0.2.0
12
+ * @description 响应式断点检测 / Responsive breakpoint detection
13
+ * @returns Current breakpoint key ('xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl')
14
+ * @example
15
+ * const bp = useBreakpoint();
16
+ * if (bp === 'xs') { ... }
17
+ */
18
+ declare const breakpoints: {
19
+ readonly xs: 0;
20
+ readonly sm: 640;
21
+ readonly md: 768;
22
+ readonly lg: 1024;
23
+ readonly xl: 1280;
24
+ readonly "2xl": 1536;
25
+ };
26
+ type Breakpoint = keyof typeof breakpoints;
27
+ declare function useBreakpoint(): Breakpoint | undefined;
28
+ declare function useIsBreakpoint(breakpoint: Breakpoint): boolean;
29
+
30
+ /**
31
+ * @hook useEventListener
32
+ * @category hooks/effect
33
+ * @since 0.2.0
34
+ * @description DOM 事件订阅 / DOM event listener hook
35
+ * @example
36
+ * useEventListener(window, 'resize', () => console.log('resized'));
37
+ * useEventListener(document, 'keydown', handler);
38
+ */
39
+ declare function useEventListener<T extends HTMLElement | Window | Document | MediaQueryList, K extends keyof WindowEventMap>(target: T | null | undefined, eventName: K, handler: (event: WindowEventMap[K]) => void, options?: AddEventListenerOptions): void;
40
+ declare function useEventListener(target: HTMLElement | Window | Document | MediaQueryList | null | undefined, eventName: string, handler: (event: Event) => void, options?: AddEventListenerOptions): void;
41
+
42
+ /**
43
+ * @hook useKey
44
+ * @category hooks/effect
45
+ * @since 0.2.0
46
+ * @description 键盘事件 Hook / Keyboard event hook
47
+ * @example
48
+ * useKey('Escape', () => close());
49
+ * useKey(['Meta+k', 'Control+k'], () => openPalette());
50
+ */
51
+ type KeyFilter = string | string[] | ((event: KeyboardEvent) => boolean);
52
+ type KeyHandler = (event: KeyboardEvent) => void;
53
+ interface UseKeyOptions {
54
+ /** Event type: 'keydown' | 'keyup' | 'keypress' / 事件类型 */
55
+ event?: "keydown" | "keyup" | "keypress";
56
+ /** Target element (default: window) / 目标元素 */
57
+ target?: HTMLElement | Window | Document | null;
58
+ /** Whether to prevent default / 是否阻止默认行为 */
59
+ preventDefault?: boolean;
60
+ /** Whether the hook is active / 是否激活 */
61
+ enabled?: boolean;
62
+ }
63
+ declare function useKey(keys: KeyFilter, handler: KeyHandler, options?: UseKeyOptions): void;
64
+ declare function useKeyCombo(combo: string, handler: KeyHandler, options?: UseKeyOptions): void;
65
+
66
+ interface MessageInstance {
67
+ success: (content: React.ReactNode, options?: MessageOptions) => string | number;
68
+ error: (content: React.ReactNode, options?: MessageOptions) => string | number;
69
+ warning: (content: React.ReactNode, options?: MessageOptions) => string | number;
70
+ info: (content: React.ReactNode, options?: MessageOptions) => string | number;
71
+ loading: (content: React.ReactNode, options?: MessageOptions) => string | number;
72
+ promise: <T>(promise: Promise<T>, options: {
73
+ loading?: React.ReactNode;
74
+ success?: React.ReactNode | ((data: T) => React.ReactNode);
75
+ error?: React.ReactNode | ((err: unknown) => React.ReactNode);
76
+ }) => Promise<T>;
77
+ destroy: (id?: string | number) => void;
78
+ }
79
+ declare function useMessage(): MessageInstance;
80
+
81
+ /**
82
+ * @hook useNotification
83
+ * @category hooks/feedback
84
+ * @since 0.2.0
85
+ * @description 命令式通知 API / Imperative notification API (antd App.useApp().notification equivalent)
86
+ * @example
87
+ * const notification = useNotification();
88
+ * notification.open({ title: 'New Order', description: 'Order #123 received' });
89
+ */
90
+ interface NotificationOptions {
91
+ id?: string | number;
92
+ title: React$1.ReactNode;
93
+ description?: React$1.ReactNode;
94
+ type?: "success" | "error" | "warning" | "info";
95
+ duration?: number;
96
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center";
97
+ action?: {
98
+ label: string;
99
+ onClick: () => void;
100
+ };
101
+ dismissible?: boolean;
102
+ }
103
+ interface NotificationInstance {
104
+ open: (options: NotificationOptions) => string | number;
105
+ success: (options: Omit<NotificationOptions, "type">) => string | number;
106
+ error: (options: Omit<NotificationOptions, "type">) => string | number;
107
+ warning: (options: Omit<NotificationOptions, "type">) => string | number;
108
+ info: (options: Omit<NotificationOptions, "type">) => string | number;
109
+ close: (id?: string | number) => void;
110
+ closeAll: () => void;
111
+ }
112
+ declare function useNotification(): NotificationInstance;
113
+
114
+ /**
115
+ * @hook useModal
116
+ * @category hooks/feedback
117
+ * @since 0.2.0
118
+ * @description 命令式模态框 API / Imperative modal API (antd Modal.confirm equivalent)
119
+ * @example
120
+ * const modal = useModal();
121
+ * modal.confirm({ title: 'Delete?', content: 'Are you sure?', onOk: handleDelete });
122
+ */
123
+ interface ModalOptions {
124
+ title?: React$1.ReactNode;
125
+ content?: React$1.ReactNode;
126
+ okText?: string;
127
+ cancelText?: string;
128
+ okVariant?: "default" | "destructive";
129
+ onOk?: () => void | Promise<void>;
130
+ onCancel?: () => void;
131
+ width?: string | number;
132
+ closable?: boolean;
133
+ maskClosable?: boolean;
134
+ }
135
+ interface ModalInstance {
136
+ confirm: (options: ModalOptions) => void;
137
+ info: (options: Omit<ModalOptions, "okVariant" | "cancelText">) => void;
138
+ warning: (options: Omit<ModalOptions, "okVariant">) => void;
139
+ success: (options: Omit<ModalOptions, "okVariant">) => void;
140
+ error: (options: Omit<ModalOptions, "okVariant">) => void;
141
+ }
142
+ declare function useModal(): ModalInstance;
143
+ /**
144
+ * Helper component to render the modal from useModal
145
+ * Usage:
146
+ * const modal = useModal();
147
+ * return (<>
148
+ * {modal.confirm.modal}
149
+ * <Button onClick={() => modal.confirm({ title: 'Hi' })}>Open</Button>
150
+ * </>)
151
+ */
152
+ declare function ModalRenderer({ modal }: {
153
+ modal: ModalInstance;
154
+ }): React$1.JSX.Element;
155
+
156
+ type AsyncStatus = "idle" | "pending" | "success" | "error";
157
+ declare function useAsync<T, Args extends unknown[] = []>(fn: (...args: Args) => Promise<T>, immediate?: boolean): {
158
+ run: (...args: Args) => Promise<T | undefined>;
159
+ isLoading: boolean;
160
+ status: AsyncStatus;
161
+ data: T | undefined;
162
+ error: Error | undefined;
163
+ };
164
+
165
+ type Handler = (event: MouseEvent | TouchEvent) => void;
166
+ declare function useClickOutside<T extends HTMLElement = HTMLElement>(ref: React$1.RefObject<T | null>, handler: Handler, enabled?: boolean): void;
167
+
168
+ declare function useCopyToClipboard(): [
169
+ boolean,
170
+ (value: string) => Promise<boolean>,
171
+ () => void
172
+ ];
173
+
174
+ declare function useCountdown(target: Date | number | string): {
175
+ days: number;
176
+ hours: number;
177
+ minutes: number;
178
+ seconds: number;
179
+ isFinished: boolean;
180
+ totalSeconds: number;
181
+ };
182
+
183
+ declare function useDebounce<T>(value: T, delay?: number): T;
184
+
185
+ type KeyCombo = string;
186
+ type HotkeyHandler = (event: KeyboardEvent) => void;
187
+ interface HotkeyOptions {
188
+ enabled?: boolean;
189
+ preventDefault?: boolean;
190
+ allowInInputs?: boolean;
191
+ }
192
+ declare function useHotkeys(keys: Record<KeyCombo, HotkeyHandler>, options?: HotkeyOptions): void;
193
+
194
+ interface UseInfiniteScrollOptions {
195
+ threshold?: number;
196
+ rootMargin?: string;
197
+ enabled?: boolean;
198
+ }
199
+ declare function useInfiniteScroll<T>(loadMore: () => Promise<{
200
+ items: T[];
201
+ hasMore: boolean;
202
+ }> | {
203
+ items: T[];
204
+ hasMore: boolean;
205
+ }, options?: UseInfiniteScrollOptions): {
206
+ items: T[];
207
+ hasMore: boolean;
208
+ loading: boolean;
209
+ error: Error | null;
210
+ sentinelRef: React$1.RefObject<HTMLDivElement | null>;
211
+ loadMore: () => Promise<void>;
212
+ reset: () => void;
213
+ };
214
+
215
+ interface Options {
216
+ root?: Element | null;
217
+ rootMargin?: string;
218
+ threshold?: number | number[];
219
+ triggerOnce?: boolean;
220
+ enabled?: boolean;
221
+ }
222
+ declare function useIntersectionObserver<T extends Element>(ref: React$1.RefObject<T | null>, options?: Options): IntersectionObserverEntry | null;
223
+ declare function useInView<T extends Element>(ref: React$1.RefObject<T | null>, options?: Omit<Options, "enabled">): boolean;
224
+
225
+ declare function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void, () => void];
226
+
227
+ declare function useMediaQuery(query: string): boolean;
228
+ declare const useIsDesktop: (breakpoint?: number) => boolean;
229
+ declare const useIsTablet: (min?: number, max?: number) => boolean;
230
+
231
+ declare function useIsMobile(): boolean;
232
+
233
+ interface PaginationState {
234
+ page: number;
235
+ pageSize: number;
236
+ }
237
+ interface PaginationResult extends PaginationState {
238
+ total: number;
239
+ totalPages: number;
240
+ offset: number;
241
+ hasNext: boolean;
242
+ hasPrev: boolean;
243
+ setPage: (page: number) => void;
244
+ setPageSize: (size: number) => void;
245
+ next: () => void;
246
+ prev: () => void;
247
+ first: () => void;
248
+ last: () => void;
249
+ }
250
+ declare function usePagination(total: number, initial?: Partial<PaginationState>): PaginationResult;
251
+
252
+ declare function usePrevious<T>(value: T): T | undefined;
253
+
254
+ declare function useStep(max: number, initial?: number): {
255
+ step: number;
256
+ next: () => void;
257
+ prev: () => void;
258
+ goTo: (i: number) => void;
259
+ reset: () => void;
260
+ isFirst: boolean;
261
+ isLast: boolean;
262
+ };
263
+
264
+ declare function useThrottle<T>(value: T, interval?: number): T;
265
+
266
+ declare function useToggle(initial?: boolean): [boolean, () => void, (value: boolean) => void];
267
+
268
+ declare const supportedLocales: readonly ["zh-CN", "en-US"];
269
+ type SupportedLocale = (typeof supportedLocales)[number];
270
+ declare function getStoredLocale(): string;
271
+ interface LocaleContextValue {
272
+ locale: string;
273
+ setLocale: (locale: string) => void;
274
+ supportedLocales: readonly string[];
275
+ }
276
+ interface LocaleProviderProps {
277
+ initialLocale?: string;
278
+ children: React.ReactNode;
279
+ }
280
+ declare function LocaleProvider({ initialLocale, children, }: LocaleProviderProps): React$1.JSX.Element;
281
+ declare function useLocale(): LocaleContextValue;
282
+
283
+ /**
284
+ * @hook useCrud
285
+ * @category hooks/business
286
+ * @since 0.5.0
287
+ * @description Generic CRUD state manager. Uses separate type params for
288
+ * the data row (T) and the form (F), so interfaces with optional fields
289
+ * like `shortName?: string` work without type errors.
290
+ *
291
+ * Supports multi-field filtering (`filters`) and pre-submit validation
292
+ * (`onValidate`), replacing the per-page useAsync + usePagination + useEffect
293
+ * boilerplate duplicated across business list pages.
294
+ * / 通用 CRUD 状态管理 hook,分离行类型和表单类型,支持多字段筛选与提交前校验。
295
+ * @keywords crud, hook, pagination, form, modal, state, filter, validate
296
+ * @example
297
+ * const crud = useCrud<Company, Partial<Company>>({
298
+ * fetcher: (page, pageSize, filters) =>
299
+ * api.list({ page, pageSize, ...filters }),
300
+ * filterFields: [
301
+ * { name: "keyword", type: "search" },
302
+ * { name: "status", type: "select", options: [...] },
303
+ * ],
304
+ * onValidate: (form) => (form.code ? null : "请填写必填项"),
305
+ * emptyForm: { id: 0, name: "", shortName: "" },
306
+ * rowKey: "id",
307
+ * successMessage: { create: "公司创建成功", update: "更新成功", delete: "已删除" },
308
+ * });
309
+ * crud.setFilters({ keyword: "x", status: "OPEN" });
310
+ */
311
+ /** Per-operation success messages / 按操作分别配置成功消息 */
312
+ interface SuccessMessageMap {
313
+ create?: string;
314
+ update?: string;
315
+ delete?: string;
316
+ }
317
+ type SuccessMessage = string | false | SuccessMessageMap;
318
+ /** Filter field descriptor (drives generated filter UI). / 筛选字段描述 */
319
+ interface FilterField {
320
+ name: string;
321
+ type: "search" | "select";
322
+ /** Options for `select` type / select 类型的选项 */
323
+ options?: {
324
+ label: string;
325
+ value: string | number;
326
+ }[];
327
+ /** Placeholder / 占位文案 */
328
+ placeholder?: string;
329
+ }
330
+ /** Aggregated filter values (string-keyed). / 筛选值聚合 */
331
+ type Filters = Record<string, unknown>;
332
+ interface UseCrudConfig<T, F = Partial<T>> {
333
+ /**
334
+ * Fetcher receives page, pageSize, and the current filters object.
335
+ * Replaces the old single-`keyword` signature so multi-filter pages
336
+ * (keyword + status + categoryId + ...) don't need hand-rolled wiring.
337
+ * / 获取数据,filters 替代旧的单 keyword 签名
338
+ */
339
+ fetcher: (page: number, pageSize: number, filters: Filters) => Promise<{
340
+ list: T[];
341
+ total: number;
342
+ }>;
343
+ onCreate?: (form: F) => Promise<unknown>;
344
+ onUpdate?: (id: string | number, form: F) => Promise<unknown>;
345
+ onDelete?: (id: string | number) => Promise<unknown>;
346
+ rowKey?: keyof T & string;
347
+ /** Empty form template — type F, independent of T's required fields / 空表单模板 */
348
+ emptyForm: F;
349
+ defaultPageSize?: number;
350
+ /**
351
+ * Pre-submit validation. Return an error message string to block submit
352
+ * (shown via message.error), or `null` to proceed.
353
+ * / 提交前校验:返回错误文案拦截提交,null 放行
354
+ */
355
+ onValidate?: (form: F) => string | null;
356
+ /** Filter field descriptors (for generated filter UI). / 筛选字段描述 */
357
+ filterFields?: FilterField[];
358
+ /** Initial filter values. / 初始筛选值 */
359
+ defaultFilters?: Filters;
360
+ /**
361
+ * Success message after create/update/delete.
362
+ * - `string` — used for all operations
363
+ * - `false` — disable success messages
364
+ * - `{ create?, update?, delete? }` — per-operation messages
365
+ * / 成功提示:字符串=全部, false=禁用, 对象=按操作分别配置
366
+ */
367
+ successMessage?: SuccessMessage;
368
+ deleteConfirmTitle?: string;
369
+ }
370
+ interface UseCrudReturn<T, F = Partial<T>> {
371
+ data: T[];
372
+ total: number;
373
+ loading: boolean;
374
+ /** Current filter values / 当前筛选值 */
375
+ filters: Filters;
376
+ /**
377
+ * Merge a partial patch into filters (shallow merge) and reset to page 1.
378
+ * / 合并筛选值(浅合并)并重置到第 1 页
379
+ */
380
+ setFilters: (patch: Filters) => void;
381
+ /** Replace filters entirely and reset to page 1. / 整体替换筛选值 */
382
+ resetFilters: (next: Filters) => void;
383
+ pagination: ReturnType<typeof usePagination>;
384
+ modalOpen: boolean;
385
+ setModalOpen: (v: boolean) => void;
386
+ editing: T | null;
387
+ form: F;
388
+ setForm: React$1.Dispatch<React$1.SetStateAction<F>>;
389
+ /** Update a single form field / 更新单个表单字段 */
390
+ updateFormField: <K extends keyof F>(key: K, value: F[K]) => void;
391
+ handleAdd: () => void;
392
+ handleEdit: (record: T) => void;
393
+ handleSubmit: () => Promise<void>;
394
+ handleDelete: (record: T) => Promise<void>;
395
+ refresh: () => void;
396
+ isEdit: boolean;
397
+ }
398
+ declare function useCrud<T extends Record<string, unknown>, F = Partial<T>>(config: UseCrudConfig<T, F>): UseCrudReturn<T, F>;
399
+
400
+ /**
401
+ * @hook usePageTitle
402
+ * @category hooks/browser
403
+ * @since 0.5.0
404
+ * @description Sets `document.title` with a template. Eliminates the manual
405
+ * `useEffect(() => { document.title = ... }, [pathname])` pattern.
406
+ * / 设置页面标题,自动拼接 title template,消除手动 useEffect 模式
407
+ * @keywords title, page, document, browser, hook
408
+ * @example
409
+ * usePageTitle("订单列表", { template: "{title} · 清香园营销管理系统" })
410
+ * // → "订单列表 · 清香园营销管理系统"
411
+ */
412
+ interface UsePageTitleOptions {
413
+ /** Title template. `{title}` placeholder is replaced with the title arg.
414
+ * / 标题模板,{title} 占位符会被替换 */
415
+ template?: string;
416
+ /** Fallback title when no title is provided / 无标题时的回退值 */
417
+ defaultTitle?: string;
418
+ }
419
+ declare function usePageTitle(title?: string, { template, defaultTitle }?: UsePageTitleOptions): void;
420
+
421
+ /**
422
+ * @hook useConfirmAsync
423
+ * @category hooks/feedback
424
+ * @since 0.5.0
425
+ * @description Imperative confirm API. Two usage modes:
426
+ *
427
+ * 1. **Hook mode** — requires rendering `<ConfirmDialog />` in JSX:
428
+ * const [confirm, ConfirmDialog] = useConfirmAsync();
429
+ * const ok = await confirm({ title: "Delete?" });
430
+ * return <>{ConfirmDialog}</>
431
+ *
432
+ * 2. **Provider mode** — auto-mounts via `ConfirmProvider`, no JSX needed:
433
+ * // In app root:
434
+ * <ConfirmProvider>...</ConfirmProvider>
435
+ * // Anywhere:
436
+ * const confirmed = await confirmAsync({ title: "Delete?" });
437
+ *
438
+ * / 命令式确认 API,支持手动挂载和 Provider 自动挂载两种模式
439
+ * @keywords confirm, dialog, imperative, async, modal, provider
440
+ */
441
+ interface ConfirmOptions {
442
+ title?: string;
443
+ content?: React$1.ReactNode;
444
+ okText?: string;
445
+ cancelText?: string;
446
+ okVariant?: "default" | "destructive";
447
+ icon?: React$1.ReactNode;
448
+ }
449
+ type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
450
+ /**
451
+ * `confirmAsync` — global imperative confirm when ConfirmProvider is mounted.
452
+ * Call from any component without rendering a dialog yourself.
453
+ * / 全局命令式确认,需 ConfirmProvider 包裹
454
+ * @throws Error if called outside ConfirmProvider
455
+ */
456
+ declare function confirmAsync(options: ConfirmOptions): Promise<boolean>;
457
+ interface ConfirmProviderProps {
458
+ children: React$1.ReactNode;
459
+ /** Default options merged into every call / 全局默认选项 */
460
+ defaultOptions?: ConfirmOptions;
461
+ }
462
+ declare function ConfirmProvider({ children, defaultOptions }: ConfirmProviderProps): React$1.JSX.Element;
463
+ declare function useConfirmAsync(): [
464
+ (options: ConfirmOptions) => Promise<boolean>,
465
+ () => React$1.ReactNode
466
+ ];
467
+ declare function useConfirmContext(): ConfirmFn;
468
+
469
+ interface ValidationRule {
470
+ type: "required" | "min" | "max" | "pattern" | "custom";
471
+ message: string;
472
+ value?: number | RegExp | ((v: unknown) => boolean);
473
+ }
474
+ interface UseFieldValidationOptions {
475
+ rules?: ValidationRule[];
476
+ externalError?: string;
477
+ validateOnBlur?: boolean;
478
+ validateOnChange?: boolean;
479
+ }
480
+ declare function useFieldValidation(options?: UseFieldValidationOptions): {
481
+ error: string | undefined;
482
+ onBlur: (e: React$1.FocusEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;
483
+ onChange: (e: React$1.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;
484
+ validate: (value: unknown) => string | undefined;
485
+ reset: () => void;
486
+ touched: boolean;
487
+ };
488
+
489
+ interface NetworkState {
490
+ online: boolean;
491
+ downlink?: number | undefined;
492
+ effectiveType?: string | undefined;
493
+ rtt?: number | undefined;
494
+ saveData?: boolean | undefined;
495
+ }
496
+ /**
497
+ * Tracks browser online/offline status and network info via Navigator.connection API.
498
+ * @since 0.2.0
499
+ */
500
+ declare function useNetworkStatus(): NetworkState;
501
+
502
+ /**
503
+ * Tracks page visibility changes (tab focus/blur, minimize).
504
+ * @param onChange - Optional callback when visibility changes
505
+ * @returns Whether the page is currently visible
506
+ * @since 0.2.0
507
+ */
508
+ declare function useVisibilityChange(onChange?: (visible: boolean) => void): boolean;
509
+
510
+ interface WindowSize {
511
+ width: number;
512
+ height: number;
513
+ }
514
+ /**
515
+ * Reactive window dimensions, updated on resize (debounced).
516
+ * @param debounceMs - Debounce delay in ms (default 100)
517
+ * @since 0.2.0
518
+ */
519
+ declare function useWindowSize(debounceMs?: number): WindowSize;
520
+
521
+ interface ScrollState {
522
+ x: number;
523
+ y: number;
524
+ isScrolled: boolean;
525
+ /** Scroll direction: 'up' | 'down' | null (initial) */
526
+ direction: "up" | "down" | null;
527
+ }
528
+ /**
529
+ * Tracks scroll position and direction.
530
+ * @param throttleMs - Throttle interval in ms (default 50)
531
+ * @param target - Scroll target element ref (defaults to window)
532
+ * @since 0.2.0
533
+ */
534
+ declare function useScroll(throttleMs?: number, target?: React$1.RefObject<HTMLElement | null>): ScrollState;
535
+ /**
536
+ * Convenience hook: returns just the scroll direction.
537
+ * @since 0.2.0
538
+ */
539
+ declare function useScrollDirection(throttleMs?: number, target?: React$1.RefObject<HTMLElement | null>): "up" | "down" | null;
540
+
541
+ type Orientation = "portrait" | "landscape";
542
+ /**
543
+ * Tracks device screen orientation.
544
+ * @since 0.2.0
545
+ */
546
+ declare function useOrientation(): Orientation;
547
+
548
+ interface UseClipboardReturn {
549
+ /** Copies text to clipboard */
550
+ copy: (text: string) => Promise<boolean>;
551
+ /** Whether a copy operation is in progress */
552
+ copying: boolean;
553
+ /** Whether the last copy was successful */
554
+ copied: boolean;
555
+ /** Recently copied text */
556
+ value: string | null;
557
+ /** Reset copied state */
558
+ reset: () => void;
559
+ }
560
+ /**
561
+ * Copy text to clipboard with state tracking.
562
+ * Unifies the existing use-copy-to-clipboard under a standard API.
563
+ *
564
+ * @param timeout - How long "copied" stays true (ms, default 2000)
565
+ * @since 0.2.0
566
+ */
567
+ declare function useClipboard(timeout?: number): UseClipboardReturn;
568
+
569
+ /**
570
+ * Enhanced form hook wrapping react-hook-form with enterprise defaults.
571
+ * - `mode: "onTouched"` by default (fewer re-renders)
572
+ * - `reValidateMode: "onChange"`
573
+ * - Standardized dirty/submit tracking
574
+ *
575
+ * @since 0.2.0
576
+ */
577
+ declare function useForm<TFieldValues extends FieldValues = FieldValues, TContext = unknown>(props?: UseFormProps<TFieldValues, TContext>): react_hook_form.UseFormReturn<TFieldValues, TContext, TFieldValues>;
578
+
579
+ /**
580
+ * Schema-driven wrapper around {@link useForm}.
581
+ *
582
+ * - Accepts a zod schema and wires it through `zodResolver` automatically.
583
+ * - For yup / valibot / custom schema libraries, pass `resolver` directly
584
+ * (e.g. `yupResolver(schema)`); `schema` and custom resolvers are mutually
585
+ * exclusive — `resolver` wins when both are supplied.
586
+ * - When neither is supplied, behaves like plain {@link useForm} so the hook
587
+ * is safely composable inside mixed caller code paths.
588
+ *
589
+ * `zod` and `@hookform/resolvers` are declared as optional peer dependencies;
590
+ * consumers adopting schema-driven forms must install them.
591
+ *
592
+ * @since 1.1.0
593
+ * @example
594
+ * const form = useFormSchema({
595
+ * schema: loginSchema,
596
+ * defaultValues: { email: "", password: "" },
597
+ * })
598
+ */
599
+ interface UseFormSchemaOptions<TFieldValues extends FieldValues = FieldValues, TContext = unknown> extends Omit<UseFormProps<TFieldValues, TContext>, "resolver"> {
600
+ /**
601
+ * Zod schema. Auto-detected via `zodResolver`; for other libraries use
602
+ * `resolver` instead. `z.infer<typeof schema>` must align with
603
+ * `TFieldValues` (the hook will infer it for you when omitted).
604
+ *
605
+ * Typed loosely (`unknown`) intentionally: zod v3/v4 surface slightly
606
+ * different generic arities and we pass the schema straight into
607
+ * `zodResolver`, which is the single source of truth for shape.
608
+ */
609
+ schema?: unknown;
610
+ /**
611
+ * Explicit react-hook-form resolver. Takes precedence over `schema`.
612
+ * Pass `yupResolver` / `valibotResolver` / a custom resolver here.
613
+ */
614
+ resolver?: Resolver<TFieldValues, TContext>;
615
+ }
616
+ /**
617
+ * Infer field values from a zod schema.
618
+ *
619
+ * @example
620
+ * const form = useFormSchema({
621
+ * schema: z.object({ email: z.string() }),
622
+ * defaultValues: { email: "" },
623
+ * })
624
+ */
625
+ declare function useFormSchema<TFieldValues extends FieldValues = FieldValues, TContext = unknown>(options?: UseFormSchemaOptions<TFieldValues, TContext>): react_hook_form.UseFormReturn<TFieldValues, TContext, TFieldValues>;
626
+ /**
627
+ * Convenience adapter mirroring `packages/chaos-design-ui` usage so consumers
628
+ * can write `const resolver = zodResolverAdapter(loginSchema)` without
629
+ * importing `@hookform/resolvers/zod` themselves.
630
+ */
631
+ declare function zodResolverAdapter<TFieldValues extends FieldValues>(schema: unknown): Resolver<TFieldValues>;
632
+
633
+ /**
634
+ * @hook usePermission
635
+ * @category hooks/auth
636
+ * @since 0.7.0
637
+ * @description 权限校验 Hook,配合 PermissionProvider 使用。
638
+ * 提供当前用户权限列表和校验函数。
639
+ * / Permission hook — works with PermissionProvider to check user permissions.
640
+ * @keywords permission, auth, role, access, guard
641
+ * @example
642
+ * const { hasPermission, hasAny, hasAll } = usePermission();
643
+ * if (hasPermission("order:create")) { ... }
644
+ */
645
+ type PermissionCheck = (permission: string) => boolean;
646
+ interface PermissionContextValue {
647
+ /** All permissions the current user holds / 当前用户拥有的权限列表 */
648
+ permissions: string[];
649
+ /** Check a single permission / 校验单个权限 */
650
+ hasPermission: PermissionCheck;
651
+ /** Check if user has ANY of the given permissions / 满足任一权限 */
652
+ hasAny: (permissions: string[]) => boolean;
653
+ /** Check if user has ALL of the given permissions / 满足全部权限 */
654
+ hasAll: (permissions: string[]) => boolean;
655
+ }
656
+ declare const PermissionContext: React$1.Context<PermissionContextValue>;
657
+ interface PermissionProviderProps {
658
+ /** Permission codes granted to the current user / 当前用户的权限码列表 */
659
+ permissions: string[];
660
+ children: React$1.ReactNode;
661
+ }
662
+ declare function PermissionProvider({ permissions, children, }: PermissionProviderProps): React$1.JSX.Element;
663
+ declare function usePermission(): PermissionContextValue;
664
+
665
+ /**
666
+ * @hook useApproval
667
+ * @category Data
668
+ * @since 1.0.0-beta.0
669
+ * @description Drives an approval action (approve/reject/transfer) with async state and result tracking.
670
+ * @param submit Async handler invoked with the action type and optional comment.
671
+ * @example
672
+ * const { submit, status, data, error, isLoading } = useApproval(async (action) => api.post(...));
673
+ */
674
+ type ApprovalAction = "approve" | "reject" | "transfer";
675
+ interface UseApprovalResult<T> {
676
+ submit: (action: ApprovalAction, comment?: string) => Promise<T | undefined>;
677
+ status: "idle" | "pending" | "success" | "error";
678
+ data: T | undefined;
679
+ error: Error | undefined;
680
+ isLoading: boolean;
681
+ }
682
+ declare function useApproval<T = unknown>(handler: (action: ApprovalAction, comment?: string) => Promise<T>): UseApprovalResult<T>;
683
+
684
+ /**
685
+ * @hook useAsyncTask
686
+ * @category Data
687
+ * @since 1.0.0-beta.0
688
+ * @description Trigger a one-shot async task with progress, retry, and abort.
689
+ * @param task Async function returning a result.
690
+ * @example
691
+ * const { run, status, data, error, isLoading, abort } = useAsyncTask(async (signal) => {...});
692
+ */
693
+ interface UseAsyncTaskResult<T> {
694
+ run: (...args: never[]) => Promise<T | undefined>;
695
+ status: "idle" | "pending" | "success" | "error";
696
+ data: T | undefined;
697
+ error: Error | undefined;
698
+ isLoading: boolean;
699
+ abort: () => void;
700
+ reset: () => void;
701
+ }
702
+ declare function useAsyncTask<T>(task: (signal: AbortSignal) => Promise<T>): UseAsyncTaskResult<T>;
703
+
704
+ /**
705
+ * @hook useBill
706
+ * @category Data
707
+ * @since 1.0.0-beta.0
708
+ * @description Tracks a bill/document's lifecycle state (draft → submitted → approved → paid → void) with transitions and history.
709
+ * @param initial Initial status.
710
+ * @example
711
+ * const { status, transition, history, can } = useBill("draft");
712
+ */
713
+ type BillStatus = "draft" | "submitted" | "approved" | "rejected" | "paid" | "void";
714
+ interface UseBillState {
715
+ status: BillStatus;
716
+ transition: (next: BillStatus) => boolean;
717
+ can: (next: BillStatus) => boolean;
718
+ history: BillStatus[];
719
+ reset: (status?: BillStatus) => void;
720
+ }
721
+ declare function useBill(initial?: BillStatus): UseBillState;
722
+
723
+ /**
724
+ * @hook useDataScope
725
+ * @category Data
726
+ * @since 1.0.0-beta.0
727
+ * @description Tracks the active data scope (e.g. company/department/period) used to filter business queries, with persistence and change subscription.
728
+ * @param initial Initial scope.
729
+ * @param options storageKey to persist to localStorage.
730
+ * @example
731
+ * const { scope, setScope, subscribe } = useDataScope({ companyId: "1" });
732
+ */
733
+ type DataScope = Record<string, string | number | boolean | undefined>;
734
+ interface UseDataScopeState<S extends DataScope> {
735
+ scope: S;
736
+ setScope: (next: S | ((prev: S) => S)) => void;
737
+ patch: (partial: Partial<S>) => void;
738
+ reset: () => void;
739
+ subscribe: (fn: (scope: S) => void) => () => void;
740
+ }
741
+ declare function useDataScope<S extends DataScope>(initial: S, options?: {
742
+ storageKey?: string;
743
+ }): UseDataScopeState<S>;
744
+
745
+ /**
746
+ * @hook useDict
747
+ * @category Data
748
+ * @since 1.0.0-beta.0
749
+ * @description Loads and caches a dictionary (key/label/code options) by dict type, with loading/error state and a label lookup helper.
750
+ * @param dictType Dictionary type key. Falsy skips loading.
751
+ * @param fetcher Returns the options for the given dict type.
752
+ * @example
753
+ * const { options, isLoading, getLabel } = useDict("gender", fetchDict);
754
+ */
755
+ interface DictOption {
756
+ value: string;
757
+ label: string;
758
+ disabled?: boolean;
759
+ }
760
+ interface UseDictState {
761
+ options: DictOption[];
762
+ isLoading: boolean;
763
+ error: Error | undefined;
764
+ getLabel: (value: string) => string;
765
+ refresh: () => void;
766
+ }
767
+ declare function useDict(dictType: string | null, fetcher: (type: string) => Promise<DictOption[]>): UseDictState;
768
+
769
+ /**
770
+ * @hook useExport
771
+ * @category Data
772
+ * @since 1.0.0-beta.0
773
+ * @description Triggers a file export (download) with progress, abort, and blob/text support.
774
+ * @example
775
+ * const { exportFile, isLoading, error } = useExport();
776
+ * await exportFile(() => fetch("/api/export").then(r => r.blob()), "report.xlsx");
777
+ */
778
+ interface UseExportResult {
779
+ exportFile: (source: () => Promise<Blob | string>, filename: string, mime?: string) => Promise<void>;
780
+ isLoading: boolean;
781
+ error: Error | undefined;
782
+ progress: number;
783
+ abort: () => void;
784
+ }
785
+ declare function useExport(): UseExportResult;
786
+
787
+ /**
788
+ * @hook useFetch
789
+ * @category Data
790
+ * @since 1.0.0-beta.0
791
+ * @description Lightweight fetch hook with abort, re-fetch, and manual trigger.
792
+ * @param input Request URL or Request object.
793
+ * @param init Fetch init options.
794
+ * @example
795
+ * const { data, error, isLoading, refetch } = useFetch("/api/users");
796
+ */
797
+ interface UseFetchState<T> {
798
+ data: T | undefined;
799
+ error: Error | undefined;
800
+ isLoading: boolean;
801
+ }
802
+ declare function useFetch<T = unknown>(input: string | URL | Request, init?: RequestInit): UseFetchState<T> & {
803
+ refetch: () => void;
804
+ };
805
+
806
+ /**
807
+ * @hook useFormTable
808
+ * @category Data
809
+ * @since 1.0.0-beta.0
810
+ * @description Editable table rows backed by a form-like state: add/update/remove rows with field-level validation and dirty tracking.
811
+ * @param initial Initial rows.
812
+ * @param config validate, id generator.
813
+ * @example
814
+ * const { rows, addRow, updateRow, removeRow, errors, isValid, dirty } = useFormTable([{ id: "1", name: "" }]);
815
+ */
816
+ interface UseFormTableConfig<T> {
817
+ validate?: (row: T, index: number) => Record<string, string>;
818
+ createId?: () => string;
819
+ }
820
+ interface UseFormTableResult<T> {
821
+ rows: T[];
822
+ addRow: (row: T) => void;
823
+ updateRow: (index: number, patch: Partial<T>) => void;
824
+ removeRow: (index: number) => void;
825
+ setRows: (rows: T[]) => void;
826
+ reset: (rows?: T[]) => void;
827
+ errors: Record<number, Record<string, string>>;
828
+ isValid: boolean;
829
+ dirty: boolean;
830
+ }
831
+ declare function useFormTable<T extends {
832
+ id?: string;
833
+ }>(initial: T[], config?: UseFormTableConfig<T>): UseFormTableResult<T>;
834
+
835
+ /**
836
+ * @hook useIdle
837
+ * @category Data
838
+ * @since 1.0.0-beta.0
839
+ * @description Tracks whether the user has been idle (no mouse/keyboard/touch/scroll) for a duration.
840
+ * @param timeout Idle threshold in ms (default 60_000).
841
+ * @param events Activity events to listen for.
842
+ * @example
843
+ * const isIdle = useIdle(30_000);
844
+ */
845
+ declare function useIdle(timeout?: number, events?: string[]): boolean;
846
+
847
+ /**
848
+ * @hook useImport
849
+ * @category Data
850
+ * @since 1.0.0-beta.0
851
+ * @description Drive a file import: parse an uploaded file (text/json/csv), track progress, validation errors, and parsed rows.
852
+ * @example
853
+ * const { importFile, rows, errors, isLoading, progress } = useImport();
854
+ */
855
+ interface ImportError {
856
+ row: number;
857
+ message: string;
858
+ }
859
+ interface UseImportResult<T> {
860
+ rows: T[];
861
+ errors: ImportError[];
862
+ isLoading: boolean;
863
+ progress: number;
864
+ importFile: (file: File, parser: (text: string, file: File) => T[] | Promise<T[]>) => Promise<T[]>;
865
+ reset: () => void;
866
+ }
867
+ declare function useImport<T = Record<string, unknown>>(): UseImportResult<T>;
868
+
869
+ /**
870
+ * @hook useLineEditor
871
+ * @category Data
872
+ * @since 1.0.0-beta.0
873
+ * @description Inline line editor: tracks edit/draft state for a single value, with commit/cancel, validation, and dirty flag. Used by editable table cells and inline-edit fields.
874
+ * @param value The committed value.
875
+ * @param options onCommit, validate, autoFocus.
876
+ * @example
877
+ * const { draft, setDraft, commit, cancel, isEditing, start, isValid } = useLineEditor("foo");
878
+ */
879
+ interface UseLineEditorOptions<T> {
880
+ onCommit?: (value: T) => void | Promise<void>;
881
+ validate?: (value: T) => string | null;
882
+ autoFocus?: boolean;
883
+ }
884
+ interface UseLineEditorResult<T> {
885
+ value: T;
886
+ draft: T;
887
+ isEditing: boolean;
888
+ error: string | null;
889
+ isValid: boolean;
890
+ dirty: boolean;
891
+ start: () => void;
892
+ setDraft: (value: T) => void;
893
+ commit: () => Promise<void>;
894
+ cancel: () => void;
895
+ }
896
+ declare function useLineEditor<T>(value: T, options?: UseLineEditorOptions<T>): UseLineEditorResult<T>;
897
+
898
+ /**
899
+ * @hook useNetworkQuality
900
+ * @category Data
901
+ * @since 1.0.0-beta.0
902
+ * @description Estimates network quality via navigator.connection (effectiveType, downlink, rtt) plus online/offline status.
903
+ * @example
904
+ * const { online, effectiveType, downlink, rtt } = useNetworkQuality();
905
+ */
906
+ interface UseNetworkQualityState {
907
+ online: boolean;
908
+ effectiveType: string | undefined;
909
+ downlink: number | undefined;
910
+ rtt: number | undefined;
911
+ saveData: boolean | undefined;
912
+ }
913
+ declare function useNetworkQuality(): UseNetworkQualityState;
914
+
915
+ /**
916
+ * @hook usePrint
917
+ * @category Data
918
+ * @since 1.0.0-beta.0
919
+ * @description Programmatic print helper: print a DOM node (via clone into a hidden iframe) or the whole window, with before/after hooks and cleanup.
920
+ * @example
921
+ * const { print, isPrinting } = usePrint();
922
+ * await print(ref.current, { title: "Invoice" });
923
+ */
924
+ interface UsePrintOptions {
925
+ title?: string;
926
+ beforePrint?: () => void;
927
+ afterPrint?: () => void;
928
+ cssText?: string;
929
+ }
930
+ interface UsePrintResult {
931
+ print: (target?: HTMLElement | null, options?: UsePrintOptions) => Promise<void>;
932
+ isPrinting: boolean;
933
+ }
934
+ declare function usePrint(): UsePrintResult;
935
+
936
+ /**
937
+ * @hook useRedo
938
+ * @category Data
939
+ * @since 1.0.0-beta.0
940
+ * @description Tracks redo history for an externally-managed undo stack. Pair with {@link useUndo} when you need separate redo state, or use `useUndo` which includes both. This hook exposes the redo queue length and a way to push/peek/pop.
941
+ * @param initial Redo queue seed (default empty).
942
+ * @example
943
+ * const { redoCount, push, pop, peek } = useRedo<string>();
944
+ */
945
+ interface UseRedoState<T> {
946
+ redoCount: number;
947
+ push: (value: T) => void;
948
+ pop: () => T | undefined;
949
+ peek: () => T | undefined;
950
+ clear: () => void;
951
+ }
952
+ declare function useRedo<T>(): UseRedoState<T>;
953
+
954
+ /**
955
+ * @hook useSse
956
+ * @category Data
957
+ * @since 1.0.0-beta.0
958
+ * @description Subscribe to a Server-Sent Events stream. Auto-reconnect and cleanup.
959
+ * @param url SSE endpoint URL. Falsy disables the connection.
960
+ * @param options onMessage handler, event name filter, withCredentials.
961
+ * @example
962
+ * const { readyState, lastEvent } = useSse("/api/stream", { onMessage: console.log });
963
+ */
964
+ interface UseSseOptions {
965
+ onMessage?: (data: string, event: MessageEvent) => void;
966
+ event?: string;
967
+ withCredentials?: boolean;
968
+ }
969
+ interface UseSseState {
970
+ readyState: number;
971
+ lastEvent: string | undefined;
972
+ error: Event | undefined;
973
+ }
974
+ declare function useSse(url: string | null, options?: UseSseOptions): UseSseState;
975
+
976
+ /**
977
+ * Type-safe wrapper around TanStack Query's `useQuery`.
978
+ *
979
+ * Consumers must install `@tanstack/react-query` and wrap their app with
980
+ * `QueryClientProvider`. This hook is a thin pass-through that adds
981
+ * enterprise defaults (e.g. `staleTime: 30_000`) so teams can adopt
982
+ * query caching without boilerplate.
983
+ *
984
+ * @since 1.1.0
985
+ * @example
986
+ * const { data, isLoading } = useQuery({
987
+ * queryKey: ["users", userId],
988
+ * queryFn: () => fetchUser(userId),
989
+ * })
990
+ */
991
+ declare function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseQueryResult<TData, TError>;
992
+
993
+ /**
994
+ * Type-safe wrapper around TanStack Query's `useMutation`.
995
+ *
996
+ * @since 1.1.0
997
+ * @example
998
+ * const { mutate, isPending } = useMutation({
999
+ * mutationFn: (data: CreateUserInput) => createUser(data),
1000
+ * onSuccess: () => queryClient.invalidateQueries({ queryKey: ["users"] }),
1001
+ * })
1002
+ */
1003
+ declare function useMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
1004
+
1005
+ /**
1006
+ * @hook useSwr
1007
+ * @category Data
1008
+ * @since 1.0.0-beta.0
1009
+ * @description SWR-style data fetching with revalidation on focus and interval.
1010
+ * @param key Cache key (falsy disables fetching).
1011
+ * @param fetcher Function that returns a Promise of data.
1012
+ * @param options revalidateOnFocus, dedupingInterval, refreshInterval.
1013
+ * @example
1014
+ * const { data, error, isLoading, mutate } = useSwr("/api/users", fetcher);
1015
+ */
1016
+ interface UseSwrOptions {
1017
+ revalidateOnFocus?: boolean;
1018
+ refreshInterval?: number;
1019
+ dedupingInterval?: number;
1020
+ }
1021
+ interface UseSwrState<T> {
1022
+ data: T | undefined;
1023
+ error: Error | undefined;
1024
+ isLoading: boolean;
1025
+ mutate: (data?: T | ((prev: T | undefined) => T)) => void;
1026
+ }
1027
+ declare function useSwr<T>(key: string | null, fetcher: (key: string) => Promise<T>, options?: UseSwrOptions): UseSwrState<T>;
1028
+
1029
+ /**
1030
+ * @hook useTable
1031
+ * @category Data
1032
+ * @since 1.0.0-beta.0
1033
+ * @description Client-side table controller: sorting, filtering, pagination, and row selection over a flat data array.
1034
+ * @param data Source rows.
1035
+ * @param config initial sort, page size, filter predicate.
1036
+ * @example
1037
+ * const { rows, page, pageSize, totalPages, sort, setFilter, toggleRow, selected } = useTable(data, { pageSize: 20 });
1038
+ */
1039
+ interface UseTableConfig<T> {
1040
+ pageSize?: number;
1041
+ initialSort?: {
1042
+ key: keyof T;
1043
+ direction?: "asc" | "desc";
1044
+ };
1045
+ filter?: (row: T, term: string) => boolean;
1046
+ getRowId?: (row: T, index: number) => string;
1047
+ }
1048
+ interface SortState<T> {
1049
+ key: keyof T | null;
1050
+ direction: "asc" | "desc";
1051
+ }
1052
+ interface UseTableResult<T> {
1053
+ rows: T[];
1054
+ page: number;
1055
+ pageSize: number;
1056
+ total: number;
1057
+ totalPages: number;
1058
+ sort: SortState<T>;
1059
+ setSort: (key: keyof T) => void;
1060
+ filterTerm: string;
1061
+ setFilter: (term: string) => void;
1062
+ setPage: (page: number) => void;
1063
+ setPageSize: (size: number) => void;
1064
+ selected: Set<string>;
1065
+ toggleRow: (id: string) => void;
1066
+ toggleAll: () => void;
1067
+ clearSelected: () => void;
1068
+ }
1069
+ declare function useTable<T>(data: T[], config?: UseTableConfig<T>): UseTableResult<T>;
1070
+
1071
+ interface UseTrackOptions {
1072
+ /** Event name sent to the telemetry adapter. */
1073
+ event: string;
1074
+ /** Additional properties merged into the event payload. */
1075
+ properties?: Record<string, unknown>;
1076
+ /** If true, fires the event on mount. Default false. */
1077
+ trackOnMount?: boolean;
1078
+ /** If true, fires the event on unmount. Default false. */
1079
+ trackOnUnmount?: boolean;
1080
+ }
1081
+ /**
1082
+ * Declarative tracking hook.
1083
+ *
1084
+ * Returns a `trackNow(extra?)` function for imperative use. Optionally
1085
+ * fires events on mount/unmount via `trackOnMount` / `trackOnUnmount`.
1086
+ *
1087
+ * @since 1.1.0
1088
+ * @example
1089
+ * // Track a page view on mount
1090
+ * useTrack({ event: "page_view", properties: { page: "dashboard" }, trackOnMount: true })
1091
+ *
1092
+ * // Track a button click
1093
+ * const { trackNow } = useTrack({ event: "export_csv" })
1094
+ * <Button onClick={() => trackNow({ rows: 142 })}>Export</Button>
1095
+ */
1096
+ declare function useTrack(options: UseTrackOptions): {
1097
+ trackNow: (extra?: Record<string, unknown>) => void;
1098
+ };
1099
+
1100
+ /**
1101
+ * @hook useUndo
1102
+ * @category Data
1103
+ * @since 1.0.0-beta.0
1104
+ * @description Undo/redo history for a value. Returns value, setters, and can/clear flags.
1105
+ * @param initial Initial value.
1106
+ * @param limit Max history entries (default 100).
1107
+ * @example
1108
+ * const { value, set, undo, redo, canUndo, canRedo } = useUndo("");
1109
+ */
1110
+ interface UseUndoState<T> {
1111
+ value: T;
1112
+ setValue: (next: T | ((prev: T) => T)) => void;
1113
+ undo: () => void;
1114
+ redo: () => void;
1115
+ clear: () => void;
1116
+ canUndo: boolean;
1117
+ canRedo: boolean;
1118
+ }
1119
+ declare function useUndo<T>(initial: T, limit?: number): UseUndoState<T>;
1120
+
1121
+ /**
1122
+ * @hook useWebsocket
1123
+ * @category Data
1124
+ * @since 1.0.0-beta.0
1125
+ * @description Manage a WebSocket connection with auto-reconnect, send helper, and last-message state.
1126
+ * @param url WebSocket URL. Falsy disables.
1127
+ * @param options onOpen/onMessage/onClose/onError callbacks, protocols, retry interval.
1128
+ * @example
1129
+ * const { send, readyState, lastMessage } = useWebsocket("wss://echo.example");
1130
+ */
1131
+ interface UseWebsocketOptions {
1132
+ onOpen?: (e: Event) => void;
1133
+ onMessage?: (data: string, e: MessageEvent) => void;
1134
+ onClose?: (e: CloseEvent) => void;
1135
+ onError?: (e: Event) => void;
1136
+ protocols?: string | string[];
1137
+ retryInterval?: number;
1138
+ autoConnect?: boolean;
1139
+ }
1140
+ interface UseWebsocketState {
1141
+ readyState: number;
1142
+ lastMessage: string | undefined;
1143
+ send: (data: string | ArrayBuffer) => void;
1144
+ close: () => void;
1145
+ }
1146
+ declare function useWebsocket(url: string | null, options?: UseWebsocketOptions): UseWebsocketState;
1147
+
1148
+ export { type Breakpoint, type ConfirmOptions, ConfirmProvider, type ConfirmProviderProps, type KeyFilter, type KeyHandler, LocaleProvider, type MessageInstance, MessageOptions, type ModalInstance, type ModalOptions, ModalRenderer, type NotificationInstance, type NotificationOptions, PermissionContext, type PermissionContextValue, PermissionProvider, type PermissionProviderProps, type SupportedLocale, type UseCrudConfig, type UseCrudReturn, type UseFieldValidationOptions, type UseFormSchemaOptions, type UseKeyOptions, type UsePageTitleOptions, type UseTrackOptions, type ValidationRule, confirmAsync, getStoredLocale, supportedLocales, useApproval, useAsync, useAsyncTask, useBill, useBreakpoint, useClickOutside, useClipboard, useConfirmAsync, useConfirmContext, useCopyToClipboard, useCountdown, useCrud, useDataScope, useDebounce, useDict, useEventListener, useExport, useFetch, useFieldValidation, useForm, useFormSchema, useFormTable, useHotkeys, useIdle, useImport, useInView, useInfiniteScroll, useIntersectionObserver, useIsBreakpoint, useIsDesktop, useIsMobile, useIsTablet, useKey, useKeyCombo, useLineEditor, useLocalStorage, useLocale, useMediaQuery, useMessage, useModal, useMutation, useNetworkQuality, useNetworkStatus, useNotification, useOrientation, usePageTitle, usePagination, usePermission, usePrevious, usePrint, useQuery, useRedo, useScroll, useScrollDirection, useSse, useStep, useSwr, useTable, useThrottle, useToggle, useTrack, useUndo, useVisibilityChange, useWebsocket, useWindowSize, zodResolverAdapter };