directix 1.3.0 → 1.4.0

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/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ComponentPublicInstance } from 'vue';
2
2
  import { Directive } from 'vue';
3
3
  import { Plugin as Plugin_2 } from 'vue';
4
+ import { Ref } from 'vue';
4
5
  import { VNode } from 'vue';
5
6
 
6
7
  /**
@@ -14,45 +15,940 @@ export declare function addCleanupVue2(el: Element, fn: () => void): void;
14
15
  export declare function addCleanupVue3(el: Element, fn: () => void): void;
15
16
 
16
17
  /**
17
- * Directive binding value type
18
+ * Calculate remaining time
18
19
  */
19
- export declare type CapitalcaseBinding = boolean | CapitalcaseOptions;
20
+ export declare function calculateTime(remaining: number): CountdownTime;
20
21
 
21
22
  /**
22
- * Capitalcase directive options
23
+ * Capitalize text based on options
23
24
  */
24
- export declare interface CapitalcaseOptions {
25
+ export declare function capitalizeText(text: string, options?: {
26
+ every?: boolean;
27
+ keepLower?: string[];
28
+ }): string;
29
+
30
+ /**
31
+ * Capitalize a single word
32
+ */
33
+ export declare function capitalizeWord(word: string): string;
34
+
35
+ /**
36
+ * Click delay handler
37
+ */
38
+ export declare type ClickDelayHandler = (event: MouseEvent | TouchEvent) => void;
39
+
40
+ /**
41
+ * Click outside handler
42
+ */
43
+ export declare type ClickOutsideHandler = (event: MouseEvent | TouchEvent) => void;
44
+
45
+ /**
46
+ * Debounced function type for composables
47
+ */
48
+ export declare interface ComposableDebouncedFunction<T extends (...args: any[]) => any> {
49
+ /**
50
+ * Call the debounced function
51
+ */
52
+ (...args: Parameters<T>): void;
53
+ /**
54
+ * Cancel any pending execution
55
+ */
56
+ cancel: () => void;
57
+ /**
58
+ * Immediately invoke if pending
59
+ */
60
+ flush: () => void;
61
+ /**
62
+ * Check if there is a pending execution
63
+ */
64
+ pending: () => boolean;
65
+ }
66
+
67
+ /**
68
+ * Throttled function type for composables
69
+ */
70
+ export declare interface ComposableThrottledFunction<T extends (...args: any[]) => any> {
71
+ /**
72
+ * Call the throttled function
73
+ */
74
+ (...args: Parameters<T>): void;
75
+ /**
76
+ * Cancel any pending execution
77
+ */
78
+ cancel: () => void;
79
+ }
80
+
81
+ /**
82
+ * Countdown complete callback
83
+ */
84
+ export declare type CountdownCompleteCallback = () => void;
85
+
86
+ /**
87
+ * Countdown format function
88
+ */
89
+ export declare type CountdownFormatFunction = (time: CountdownTime) => string;
90
+
91
+ /**
92
+ * Countdown tick callback
93
+ */
94
+ export declare type CountdownTickCallback = (time: CountdownTime) => void;
95
+
96
+ /**
97
+ * Countdown time object
98
+ */
99
+ export declare interface CountdownTime {
100
+ days: number;
101
+ hours: number;
102
+ minutes: number;
103
+ seconds: number;
104
+ milliseconds: number;
105
+ total: number;
106
+ }
107
+
108
+ /**
109
+ * Create a capitalizing function with preset options
110
+ *
111
+ * @param options - Capitalization options
112
+ * @returns Capitalization function
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * import { createCapitalizer } from 'directix'
117
+ *
118
+ * const titleCase = createCapitalizer({ every: true })
119
+ * const sentenceCase = createCapitalizer({ every: false })
120
+ *
121
+ * titleCase('the quick brown fox') // 'The Quick Brown Fox'
122
+ * sentenceCase('the quick brown fox') // 'The quick brown fox'
123
+ * ```
124
+ */
125
+ export declare function createCapitalizer(options?: {
126
+ every?: boolean;
127
+ keepLower?: string[];
128
+ }): (text: string) => string;
129
+
130
+ /**
131
+ * Create a debounced click handler
132
+ *
133
+ * @param handler - Click handler
134
+ * @param delay - Delay in milliseconds
135
+ * @returns Debounced click handler
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { createDelayedClick } from 'directix'
140
+ *
141
+ * const delayedSubmit = createDelayedClick(submitForm, 1000)
142
+ *
143
+ * // Use in event handler
144
+ * button.onclick = delayedSubmit
145
+ * ```
146
+ */
147
+ export declare function createDelayedClick(handler: ClickDelayHandler, delay?: number): (event: MouseEvent | TouchEvent) => void;
148
+
149
+ /**
150
+ * Create a lowercase transformation function
151
+ *
152
+ * @param first - Whether to transform only the first character
153
+ * @returns Lowercase transformation function
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * import { createLowercaser } from 'directix'
158
+ *
159
+ * const toLower = createLowercaser()
160
+ * toLower('HELLO') // 'hello'
161
+ *
162
+ * const firstToLower = createLowercaser(true)
163
+ * firstToLower('HELLO') // 'hELLO'
164
+ * ```
165
+ */
166
+ export declare function createLowercaser(first?: boolean): (text: string) => string;
167
+
168
+ /**
169
+ * Create a money formatter with preset options
170
+ *
171
+ * @param options - Format options
172
+ * @returns Money formatter function
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * import { createMoneyFormatter } from 'directix'
177
+ *
178
+ * const formatEuro = createMoneyFormatter({ symbol: '€', symbolPosition: 'after' })
179
+ * formatEuro(1234.56) // '1,234.56€'
180
+ * ```
181
+ */
182
+ export declare function createMoneyFormatter(options?: {
183
+ symbol?: string;
184
+ symbolPosition?: 'before' | 'after';
185
+ precision?: number;
186
+ separator?: string;
187
+ decimal?: string;
188
+ }): (value: number) => string;
189
+
190
+ /**
191
+ * Create a number formatter with preset options
192
+ *
193
+ * @param options - Format options
194
+ * @returns Number formatter function
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * import { createNumberFormatter } from 'directix'
199
+ *
200
+ * const formatPercent = createNumberFormatter({ suffix: '%', precision: 1 })
201
+ * formatPercent(85.5) // '85.5%'
202
+ * ```
203
+ */
204
+ export declare function createNumberFormatter(options?: {
205
+ precision?: number;
206
+ separator?: string;
207
+ decimal?: string;
208
+ prefix?: string;
209
+ suffix?: string;
210
+ }): (value: number) => string;
211
+
212
+ /**
213
+ * Create a permission checker with shared configuration
214
+ *
215
+ * @param config - Shared configuration
216
+ * @returns Permission checker function
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * import { createPermissionChecker } from 'directix'
221
+ *
222
+ * const checkPermission = createPermissionChecker({
223
+ * getPermissions: () => store.getters.permissions,
224
+ * getRoles: () => store.getters.roles,
225
+ * roleMap: { admin: ['*'], editor: ['read', 'write'] }
226
+ * })
227
+ *
228
+ * // Usage
229
+ * const isAdmin = checkPermission('admin')
230
+ * const canEdit = checkPermission(['read', 'write'], 'every')
231
+ * ```
232
+ */
233
+ export declare function createPermissionChecker(config: {
234
+ getPermissions: () => string[];
235
+ getRoles?: () => string[];
236
+ roleMap?: Record<string, string[]>;
237
+ }): (value: string | string[], mode?: PermissionMode) => boolean;
238
+
239
+ /**
240
+ * Create a trim function with preset options
241
+ *
242
+ * @param position - Trim position
243
+ * @param chars - Custom characters to trim
244
+ * @returns Trim function
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * import { createTrimmer } from 'directix'
249
+ *
250
+ * const trimStart = createTrimmer('start')
251
+ * trimStart(' hello ') // 'hello '
252
+ *
253
+ * const trimAsterisks = createTrimmer('both', '*')
254
+ * trimAsterisks('**hello**') // 'hello'
255
+ * ```
256
+ */
257
+ export declare function createTrimmer(position?: TrimPosition, chars?: string): (text: string) => string;
258
+
259
+ /**
260
+ * Create an uppercase transformation function
261
+ *
262
+ * @param first - Whether to transform only the first character
263
+ * @returns Uppercase transformation function
264
+ *
265
+ * @example
266
+ * ```ts
267
+ * import { createUppercaser } from 'directix'
268
+ *
269
+ * const toUpper = createUppercaser()
270
+ * toUpper('hello') // 'HELLO'
271
+ *
272
+ * const firstToUpper = createUppercaser(true)
273
+ * firstToUpper('hello') // 'Hello'
274
+ * ```
275
+ */
276
+ export declare function createUppercaser(first?: boolean): (text: string) => string;
277
+
278
+ /**
279
+ * Vue 2 directive adapter
280
+ * @returns Vue 2 directive object with bind/inserted/update/unbind hooks
281
+ */
282
+ export declare function createVue2Directive<T, B extends Element>(hooks: DirectiveHooks<T, B>): Record<string, any>;
283
+
284
+ /**
285
+ * Vue 3 directive adapter
286
+ * @returns Vue 3 directive object with created/mounted/updated/unmounted hooks
287
+ */
288
+ export declare function createVue3Directive<T, B extends Element>(hooks: DirectiveHooks<T, B>): Record<string, any>;
289
+
290
+ /**
291
+ * Create a simple watermark data URL
292
+ *
293
+ * @param content - Watermark text
294
+ * @param options - Additional options
295
+ * @returns Data URL string
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * import { createWatermarkUrl } from 'directix'
300
+ *
301
+ * const url = createWatermarkUrl('Confidential', { fontSize: 20 })
302
+ * // Use as background-image: url(dataUrl)
303
+ * ```
304
+ */
305
+ export declare function createWatermarkUrl(content: string | string[], options?: {
306
+ width?: number;
307
+ height?: number;
308
+ fontSize?: number;
309
+ color?: string;
310
+ rotate?: number;
311
+ }): string;
312
+
313
+ /**
314
+ * Cross-version directive type (compatible with Vue 2/3)
315
+ */
316
+ export declare type CrossVersionDirective = Directive | Vue2DirectiveHooks | Vue3DirectiveHooks;
317
+
318
+ /**
319
+ * Simple debounce function wrapper
320
+ *
321
+ * @param fn - Function to debounce
322
+ * @param wait - Delay in milliseconds
323
+ * @returns Debounced function with cancel method
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * import { debounceFn } from 'directix'
328
+ *
329
+ * const debouncedSave = debounceFn(saveData, 1000)
330
+ *
331
+ * // Call multiple times, only executes once after 1s
332
+ * debouncedSave(data)
333
+ * debouncedSave(newData)
334
+ *
335
+ * // Cancel pending execution
336
+ * debouncedSave.cancel()
337
+ * ```
338
+ */
339
+ export declare function debounceFn<T extends (...args: any[]) => any>(fn: T, wait?: number, options?: {
340
+ leading?: boolean;
341
+ trailing?: boolean;
342
+ }): ComposableDebouncedFunction<T>;
343
+
344
+ /**
345
+ * Deep clone an object
346
+ */
347
+ export declare function deepClone<T>(obj: T): T;
348
+
349
+ /**
350
+ * Deep merge objects
351
+ */
352
+ export declare function deepMerge<T extends Record<string, any>>(target: T, ...sources: Partial<T>[]): T;
353
+
354
+ /**
355
+ * Define a cross-version compatible directive
356
+ * @param definition The directive definition
357
+ * @returns Vue directive object
358
+ */
359
+ export declare function defineDirective<T = any, B extends Element = Element>(definition: DirectiveDefinition<T, B>): Directive;
360
+
361
+ /**
362
+ * Define a directive group
363
+ */
364
+ export declare function defineDirectiveGroup(name: string, directives: Record<string, any>): {
365
+ name: string;
366
+ directives: Record<string, any>;
367
+ install: (app: any) => void;
368
+ };
369
+
370
+ /**
371
+ * Unified directive binding object
372
+ */
373
+ export declare interface DirectiveBinding<T = any> {
374
+ /** The value passed to the directive */
375
+ value: T;
376
+ /** The previous value */
377
+ oldValue: T | null;
378
+ /** The directive argument (v-xxx:arg) */
379
+ arg?: string;
380
+ /** The modifiers object (v-xxx.modifier) */
381
+ modifiers: Record<string, boolean>;
382
+ /** The component instance */
383
+ instance: ComponentPublicInstance | null;
384
+ }
385
+
386
+ /**
387
+ * Directive definition interface
388
+ */
389
+ export declare interface DirectiveDefinition<T = any, B extends Element = Element> extends DirectiveHooks<T, B> {
390
+ /** The directive name */
391
+ name: string;
392
+ /** The Vue version compatibility */
393
+ version?: '2' | '3' | 'both';
394
+ /** Whether SSR compatible */
395
+ ssr?: boolean;
396
+ /** Default values */
397
+ defaults?: Partial<T>;
398
+ }
399
+
400
+ /**
401
+ * Unified directive hooks
402
+ */
403
+ export declare interface DirectiveHooks<T = any, B extends Element = Element> {
404
+ /**
405
+ * Called when the directive is bound to an element
406
+ * @param el The bound DOM element
407
+ * @param binding The binding object
408
+ * @param vnode The Vue virtual node
409
+ */
410
+ mounted?: (el: B, binding: DirectiveBinding<T>, vnode: VNode) => void;
411
+ /**
412
+ * Called when the element is updated
413
+ * @param el The bound DOM element
414
+ * @param binding The new binding object
415
+ * @param vnode The new virtual node
416
+ * @param prevBinding The previous binding object
417
+ * @param prevVnode The previous virtual node
418
+ */
419
+ updated?: (el: B, binding: DirectiveBinding<T>, vnode: VNode, prevBinding: DirectiveBinding<T>, prevVnode: VNode) => void;
420
+ /**
421
+ * Called when the directive is unbound
422
+ * @param el The bound DOM element
423
+ * @param binding The binding object
424
+ * @param vnode The virtual node
425
+ */
426
+ unmounted?: (el: B, binding: DirectiveBinding<T>, vnode: VNode) => void;
427
+ }
428
+
429
+ /**
430
+ * Directive installation options
431
+ */
432
+ export declare interface DirectiveInstallOptions {
433
+ /** List of directive names to register, registers all if not provided */
434
+ directives?: string[];
435
+ /** Whether to register all directives */
436
+ all?: boolean;
437
+ /** Global configuration */
438
+ config?: Record<string, any>;
439
+ }
440
+
441
+ /**
442
+ * Directix plugin
443
+ */
444
+ export declare const Directix: Plugin_2;
445
+
446
+ /**
447
+ * Draggable axis
448
+ */
449
+ export declare type DraggableAxis = 'x' | 'y' | 'both';
450
+
451
+ /**
452
+ * Format number to money string
453
+ */
454
+ export declare function formatMoney(value: number, options?: {
455
+ precision?: number;
456
+ separator?: string;
457
+ decimal?: string;
458
+ symbol?: string;
459
+ symbolPosition?: 'before' | 'after';
460
+ }): string;
461
+
462
+ /**
463
+ * Format number with options
464
+ */
465
+ export declare function formatNumber(value: number, options?: {
466
+ precision?: number;
467
+ separator?: string;
468
+ decimal?: string;
469
+ prefix?: string;
470
+ suffix?: string;
471
+ }): string;
472
+
473
+ /**
474
+ * Format time to string
475
+ */
476
+ export declare function formatTime(time: CountdownTime, format: string | CountdownFormatFunction): string;
477
+
478
+ /**
479
+ * Generate unique ID
480
+ */
481
+ export declare function generateId(prefix?: string): string;
482
+
483
+ /**
484
+ * Get nested property value by path
485
+ */
486
+ export declare function get<T = any>(obj: Record<string, any>, path: string, defaultValue?: T): T;
487
+
488
+ /**
489
+ * Get current Vue version
490
+ */
491
+ export declare function getVueVersion(): VueVersion;
492
+
493
+ /**
494
+ * Hotkey definition
495
+ */
496
+ export declare interface HotkeyDefinition {
497
+ /**
498
+ * Key combination (e.g., 'ctrl+s', 'alt+shift+a')
499
+ */
500
+ key: string;
501
+ /**
502
+ * Handler function
503
+ */
504
+ handler: (event: KeyboardEvent) => void;
505
+ /**
506
+ * Whether to prevent default behavior
507
+ * @default true
508
+ */
509
+ prevent?: boolean;
510
+ /**
511
+ * Whether to stop propagation
512
+ * @default false
513
+ */
514
+ stop?: boolean;
515
+ /**
516
+ * Whether to trigger on keyup instead of keydown
517
+ * @default false
518
+ */
519
+ keyup?: boolean;
520
+ /**
521
+ * Whether the hotkey is disabled
522
+ * @default false
523
+ */
524
+ disabled?: boolean | Ref<boolean>;
525
+ }
526
+
527
+ /**
528
+ * Intersect event handler
529
+ */
530
+ export declare type IntersectHandler = (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
531
+
532
+ /**
533
+ * Check if value is an array
534
+ */
535
+ export declare function isArray(value: unknown): value is any[];
536
+
537
+ /**
538
+ * Check if value is a boolean
539
+ */
540
+ export declare function isBoolean(value: unknown): value is boolean;
541
+
542
+ /**
543
+ * Check if browser environment
544
+ */
545
+ export declare const isBrowser: () => boolean;
546
+
547
+ /**
548
+ * Check if value is empty
549
+ */
550
+ export declare function isEmpty(value: unknown): boolean;
551
+
552
+ /**
553
+ * Check if value is a function
554
+ */
555
+ export declare function isFunction(value: unknown): value is (...args: any[]) => any;
556
+
557
+ /**
558
+ * Check if value is a number
559
+ */
560
+ export declare function isNumber(value: unknown): value is number;
561
+
562
+ /**
563
+ * Check if value is an object
564
+ */
565
+ export declare function isObject(value: unknown): value is Record<string, any>;
566
+
567
+ /**
568
+ * Check if value is a Promise
569
+ */
570
+ export declare function isPromise<T = any>(value: unknown): value is Promise<T>;
571
+
572
+ /**
573
+ * Check if server-side rendering
574
+ */
575
+ export declare const isSSR: () => boolean;
576
+
577
+ /**
578
+ * Check if value is a string
579
+ */
580
+ export declare function isString(value: unknown): value is string;
581
+
582
+ /**
583
+ * Check if Vue 2 (includes 2.7)
584
+ */
585
+ export declare function isVue2(): boolean;
586
+
587
+ /**
588
+ * Check if Vue 2.7 (has built-in Composition API support)
589
+ */
590
+ export declare function isVue27(): boolean;
591
+
592
+ /**
593
+ * Check if Vue 3
594
+ */
595
+ export declare function isVue3(): boolean;
596
+
597
+ /**
598
+ * Virtual list item size function
599
+ */
600
+ export declare type ItemSizeFunction = (index: number) => number;
601
+
602
+ /**
603
+ * Transform text to lowercase
604
+ */
605
+ export declare function lowercaseText(text: string, firstOnly?: boolean): string;
606
+
607
+ /**
608
+ * Parse formatted money string to number
609
+ */
610
+ export declare function parseMoney(formatted: string, options?: {
611
+ decimal?: string;
612
+ symbol?: string;
613
+ }): number;
614
+
615
+ /**
616
+ * Parse formatted number string to number
617
+ */
618
+ export declare function parseNumber(formatted: string, options?: {
619
+ decimal?: string;
620
+ prefix?: string;
621
+ suffix?: string;
622
+ }): number;
623
+
624
+ /**
625
+ * Parse target time to timestamp
626
+ */
627
+ export declare function parseTargetTime(target: Date | number | string): number;
628
+
629
+ /**
630
+ * Parse time argument
631
+ * Supports formats: "300" | "300ms" | "1s"
632
+ */
633
+ export declare function parseTime(arg?: string): number | null;
634
+
635
+ /**
636
+ * Permission check mode
637
+ */
638
+ export declare type PermissionMode = 'some' | 'every';
639
+
640
+ /**
641
+ * Position type
642
+ */
643
+ export declare interface Position {
644
+ x: number;
645
+ y: number;
646
+ }
647
+
648
+ /**
649
+ * Print before callback
650
+ */
651
+ export declare type PrintBeforeCallback = () => boolean | void;
652
+
653
+ /**
654
+ * Print complete callback
655
+ */
656
+ export declare type PrintCompleteCallback = () => void;
657
+
658
+ /**
659
+ * Pull refresh handler
660
+ */
661
+ export declare type PullRefreshHandler = () => Promise<void> | void;
662
+
663
+ /**
664
+ * Pull refresh state
665
+ */
666
+ export declare type PullRefreshState = 'idle' | 'pulling' | 'ready' | 'loading' | 'success' | 'error';
667
+
668
+ /**
669
+ * Quick print function
670
+ *
671
+ * @param target - Element or selector to print
672
+ * @param options - Print options
673
+ *
674
+ * @example
675
+ * ```ts
676
+ * import { quickPrint } from 'directix'
677
+ *
678
+ * // Print element by selector
679
+ * quickPrint('#content', { title: 'My Document' })
680
+ *
681
+ * // Print element directly
682
+ * const el = document.getElementById('content')
683
+ * quickPrint(el)
684
+ * ```
685
+ */
686
+ export declare function quickPrint(target: string | HTMLElement, options?: UsePrintOptions): Promise<void>;
687
+
688
+ /**
689
+ * Reset Vue version (useful for testing)
690
+ */
691
+ export declare function resetVueVersion(): void;
692
+
693
+ /**
694
+ * Resize information
695
+ */
696
+ export declare interface ResizeInfo {
697
+ /** New width */
698
+ width: number;
699
+ /** New height */
700
+ height: number;
701
+ /** Content rect */
702
+ contentRect: DOMRectReadOnly;
703
+ }
704
+
705
+ /**
706
+ * Scroll direction
707
+ */
708
+ export declare type ScrollDirection = -1 | 0 | 1;
709
+
710
+ /**
711
+ * Scroll information
712
+ */
713
+ export declare interface ScrollInfo {
714
+ /** Current scroll left position */
715
+ scrollLeft: number;
716
+ /** Current scroll top position */
717
+ scrollTop: number;
718
+ /** Maximum scroll left */
719
+ scrollLeftMax: number;
720
+ /** Maximum scroll top */
721
+ scrollTopMax: number;
722
+ /** Horizontal scroll progress (0-1) */
723
+ progressX: number;
724
+ /** Vertical scroll progress (0-1) */
725
+ progressY: number;
726
+ /** Direction of horizontal scroll (-1: left, 1: right, 0: none) */
727
+ directionX: ScrollDirection;
728
+ /** Direction of vertical scroll (-1: up, 1: down, 0: none) */
729
+ directionY: ScrollDirection;
730
+ }
731
+
732
+ /**
733
+ * Set nested property value by path
734
+ */
735
+ export declare function set(obj: Record<string, any>, path: string, value: any): void;
736
+
737
+ /**
738
+ * Set Vue version explicitly (for cases where auto-detection fails)
739
+ */
740
+ export declare function setVueVersion(version: VueVersion): void;
741
+
742
+ /**
743
+ * Check if Clipboard API is supported
744
+ */
745
+ export declare const supportsClipboard: () => boolean;
746
+
747
+ /**
748
+ * Check if IntersectionObserver is supported
749
+ */
750
+ export declare const supportsIntersectionObserver: () => boolean;
751
+
752
+ /**
753
+ * Check if MutationObserver is supported
754
+ */
755
+ export declare const supportsMutationObserver: () => boolean;
756
+
757
+ /**
758
+ * Check if passive event listening is supported
759
+ */
760
+ export declare const supportsPassive: () => boolean;
761
+
762
+ /**
763
+ * Check if ResizeObserver is supported
764
+ */
765
+ export declare const supportsResizeObserver: () => boolean;
766
+
767
+ /**
768
+ * Swipe direction
769
+ */
770
+ export declare type SwipeDirection = 'left' | 'right' | 'up' | 'down';
771
+
772
+ /**
773
+ * Swipe handler type
774
+ */
775
+ export declare type SwipeHandler = (direction: SwipeDirection, event: Event) => void;
776
+
777
+ /**
778
+ * Simple throttle function wrapper
779
+ *
780
+ * @param fn - Function to throttle
781
+ * @param wait - Delay in milliseconds
782
+ * @returns Throttled function with cancel method
783
+ *
784
+ * @example
785
+ * ```ts
786
+ * import { throttleFn } from 'directix'
787
+ *
788
+ * const throttledUpdate = throttleFn(updateData, 1000)
789
+ *
790
+ * // Call multiple times, only executes once per second
791
+ * throttledUpdate(data)
792
+ * throttledUpdate(newData)
793
+ *
794
+ * // Cancel pending execution
795
+ * throttledUpdate.cancel()
796
+ * ```
797
+ */
798
+ export declare function throttleFn<T extends (...args: any[]) => any>(fn: T, wait?: number, options?: {
799
+ leading?: boolean;
800
+ trailing?: boolean;
801
+ }): ComposableThrottledFunction<T>;
802
+
803
+ /**
804
+ * Touch gesture type
805
+ */
806
+ export declare type TouchGesture = 'swipe' | 'pinch' | 'rotate' | 'tap' | 'longPress';
807
+
808
+ /**
809
+ * Touch gesture event
810
+ */
811
+ export declare interface TouchGestureEvent {
812
+ type: TouchGesture;
813
+ direction?: 'left' | 'right' | 'up' | 'down';
814
+ distance?: number;
815
+ angle?: number;
816
+ scale?: number;
817
+ rotation?: number;
818
+ center?: {
819
+ x: number;
820
+ y: number;
821
+ };
822
+ event: TouchEvent;
823
+ }
824
+
825
+ /**
826
+ * Trim position
827
+ */
828
+ export declare type TrimPosition = 'start' | 'end' | 'both';
829
+
830
+ /**
831
+ * Trim text based on options
832
+ */
833
+ export declare function trimText(text: string, position?: TrimPosition, chars?: string): string;
834
+
835
+ /**
836
+ * Utility function to truncate text to a specified length
837
+ *
838
+ * @param text - Text to truncate
839
+ * @param maxLength - Maximum length
840
+ * @param ellipsis - Ellipsis string
841
+ * @returns Truncated text
842
+ *
843
+ * @example
844
+ * ```ts
845
+ * import { truncateText } from 'directix'
846
+ *
847
+ * const short = truncateText('Very long text here', 10)
848
+ * // 'Very l...'
849
+ * ```
850
+ */
851
+ export declare function truncateText(text: string, maxLength: number, ellipsis?: string): string;
852
+
853
+ /**
854
+ * Transform text to uppercase
855
+ */
856
+ export declare function uppercaseText(text: string, firstOnly?: boolean): string;
857
+
858
+ /**
859
+ * Composable for capitalizing text
860
+ *
861
+ * @param options - Configuration options
862
+ * @returns Capitalized text utilities
863
+ *
864
+ * @example
865
+ * ```vue
866
+ * <script setup>
867
+ * import { ref } from 'vue'
868
+ * import { useCapitalcase } from 'directix'
869
+ *
870
+ * const title = ref('the quick brown fox')
871
+ *
872
+ * const { capitalized } = useCapitalcase({
873
+ * text: title,
874
+ * every: true
875
+ * })
876
+ * // capitalized.value = 'The Quick Brown Fox'
877
+ * </script>
878
+ *
879
+ * <template>
880
+ * <h1>{{ capitalized }}</h1>
881
+ * </template>
882
+ * ```
883
+ */
884
+ export declare function useCapitalcase(options: UseCapitalcaseOptions): UseCapitalcaseReturn;
885
+
886
+ /**
887
+ * Options for useCapitalcase composable
888
+ */
889
+ export declare interface UseCapitalcaseOptions {
890
+ /**
891
+ * The text to capitalize
892
+ */
893
+ text: string | Ref<string>;
25
894
  /**
26
895
  * Whether to capitalize each word or just the first word
27
896
  * @default true
28
897
  */
29
- every?: boolean;
898
+ every?: boolean | Ref<boolean>;
30
899
  /**
31
900
  * Words to keep lowercase (articles, prepositions, etc.)
32
901
  * @default ['a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'on', 'at', 'to', 'from', 'by']
33
902
  */
34
- keepLower?: string[];
35
- /**
36
- * Whether to transform on input (for input elements)
37
- * @default true
38
- */
39
- onInput?: boolean;
903
+ keepLower?: string[] | Ref<string[]>;
40
904
  }
41
905
 
42
906
  /**
43
- * Directive binding value type
907
+ * Return type for useCapitalcase composable
44
908
  */
45
- export declare type ClickDelayBinding = ClickDelayHandler | ClickDelayOptions;
909
+ export declare interface UseCapitalcaseReturn {
910
+ /**
911
+ * The capitalized text
912
+ */
913
+ capitalized: Ref<string>;
914
+ /**
915
+ * Original text
916
+ */
917
+ original: Ref<string>;
918
+ }
46
919
 
47
920
  /**
48
- * Click delay handler
921
+ * Composable for preventing repeated clicks within a delay period
922
+ *
923
+ * @param options - Configuration options
924
+ * @returns Click delay utilities
925
+ *
926
+ * @example
927
+ * ```vue
928
+ * <script setup>
929
+ * import { useClickDelay } from 'directix'
930
+ *
931
+ * const { click, isPending } = useClickDelay({
932
+ * handler: async (event) => {
933
+ * await submitForm()
934
+ * },
935
+ * delay: 500
936
+ * })
937
+ * </script>
938
+ *
939
+ * <template>
940
+ * <button @click="click" :disabled="isPending">
941
+ * {{ isPending ? 'Processing...' : 'Submit' }}
942
+ * </button>
943
+ * </template>
944
+ * ```
49
945
  */
50
- export declare type ClickDelayHandler = (event: MouseEvent | TouchEvent) => void;
946
+ export declare function useClickDelay(options: UseClickDelayOptions): UseClickDelayReturn;
51
947
 
52
948
  /**
53
- * Click delay directive options
949
+ * Options for useClickDelay composable
54
950
  */
55
- export declare interface ClickDelayOptions {
951
+ export declare interface UseClickDelayOptions {
56
952
  /**
57
953
  * Click handler
58
954
  * @required
@@ -62,47 +958,74 @@ export declare interface ClickDelayOptions {
62
958
  * Delay time in milliseconds
63
959
  * @default 300
64
960
  */
65
- delay?: number;
961
+ delay?: number | Ref<number>;
66
962
  /**
67
963
  * Whether to disable
68
964
  * @default false
69
965
  */
70
- disabled?: boolean;
966
+ disabled?: boolean | Ref<boolean>;
967
+ }
968
+
969
+ /**
970
+ * Return type for useClickDelay composable
971
+ */
972
+ export declare interface UseClickDelayReturn {
71
973
  /**
72
- * CSS class to add during delay
73
- * @default 'v-click-delay--pending'
974
+ * Whether a click is pending
74
975
  */
75
- pendingClass?: string;
976
+ isPending: Ref<boolean>;
76
977
  /**
77
- * Whether to show visual feedback
78
- * @default true
978
+ * Trigger the click handler with delay protection
79
979
  */
80
- feedback?: boolean;
980
+ click: (event: MouseEvent | TouchEvent) => void;
981
+ /**
982
+ * Manually reset the pending state
983
+ */
984
+ reset: () => void;
985
+ /**
986
+ * Cancel any pending timeout
987
+ */
988
+ cancel: () => void;
81
989
  }
82
990
 
83
991
  /**
84
- * Directive binding value type
85
- */
86
- export declare type ClickOutsideBinding = ClickOutsideHandler | ClickOutsideOptions;
87
-
88
- /**
89
- * Click outside handler
992
+ * Composable for detecting clicks outside an element
993
+ *
994
+ * @param options - Configuration options
995
+ * @returns Click outside utilities
996
+ *
997
+ * @example
998
+ * ```vue
999
+ * <script setup>
1000
+ * import { ref } from 'vue'
1001
+ * import { useClickOutside } from 'directix'
1002
+ *
1003
+ * const dropdown = ref(null)
1004
+ * const show = ref(false)
1005
+ *
1006
+ * const { bind } = useClickOutside({
1007
+ * handler: () => show.value = false,
1008
+ * exclude: [() => triggerRef.value]
1009
+ * })
1010
+ *
1011
+ * onMounted(() => bind(dropdown.value))
1012
+ * </script>
1013
+ * ```
90
1014
  */
91
- export declare type ClickOutsideHandler = (event: MouseEvent | TouchEvent) => void;
1015
+ export declare function useClickOutside(options: UseClickOutsideOptions): UseClickOutsideReturn;
92
1016
 
93
1017
  /**
94
- * Click outside directive options
1018
+ * Options for useClickOutside composable
95
1019
  */
96
- export declare interface ClickOutsideOptions {
1020
+ export declare interface UseClickOutsideOptions {
97
1021
  /**
98
1022
  * Callback when clicking outside
99
- * @required
100
1023
  */
101
1024
  handler: ClickOutsideHandler;
102
1025
  /**
103
1026
  * Excluded element selectors or element references
104
1027
  */
105
- exclude?: (string | HTMLElement | (() => HTMLElement | null))[];
1028
+ exclude?: (string | HTMLElement | (() => HTMLElement | null) | Ref<HTMLElement | null>)[];
106
1029
  /**
107
1030
  * Whether to use capture mode
108
1031
  * @default true
@@ -113,11 +1036,6 @@ export declare interface ClickOutsideOptions {
113
1036
  * @default ['click']
114
1037
  */
115
1038
  events?: ('click' | 'mousedown' | 'mouseup' | 'touchstart' | 'touchend')[];
116
- /**
117
- * Whether to disable
118
- * @default false
119
- */
120
- disabled?: boolean;
121
1039
  /**
122
1040
  * Stop propagation
123
1041
  * @default false
@@ -131,77 +1049,132 @@ export declare interface ClickOutsideOptions {
131
1049
  }
132
1050
 
133
1051
  /**
134
- * Configure permission directive
135
- */
136
- export declare function configurePermission(config: PermissionConfig): void;
137
-
138
- /**
139
- * Directive binding value type
1052
+ * Return type for useClickOutside composable
140
1053
  */
141
- export declare type CopyBinding = string | CopyOptions;
1054
+ export declare interface UseClickOutsideReturn {
1055
+ /**
1056
+ * Bind click outside detection to an element
1057
+ */
1058
+ bind: (element: HTMLElement) => () => void;
1059
+ }
142
1060
 
143
1061
  /**
144
- * Copy error callback
1062
+ * Composable for copying text to clipboard
1063
+ *
1064
+ * @param options - Configuration options
1065
+ * @returns Copy utilities
1066
+ *
1067
+ * @example
1068
+ * ```vue
1069
+ * <script setup>
1070
+ * import { useCopy } from 'directix'
1071
+ *
1072
+ * const text = ref('Hello World')
1073
+ * const { copy, copied, isSupported } = useCopy({ source: text })
1074
+ *
1075
+ * // Or use with inline text
1076
+ * const { copy } = useCopy()
1077
+ *
1078
+ * async function handleCopy() {
1079
+ * await copy('Custom text')
1080
+ * }
1081
+ * </script>
1082
+ *
1083
+ * <template>
1084
+ * <button @click="copy()" :disabled="!isSupported">
1085
+ * {{ copied ? 'Copied!' : 'Copy' }}
1086
+ * </button>
1087
+ * </template>
1088
+ * ```
145
1089
  */
146
- export declare type CopyErrorCallback = (error: Error) => void;
1090
+ export declare function useCopy(options?: UseCopyOptions): UseCopyReturn;
147
1091
 
148
1092
  /**
149
- * Copy directive options
1093
+ * Options for useCopy composable
150
1094
  */
151
- export declare interface CopyOptions {
1095
+ export declare interface UseCopyOptions {
152
1096
  /**
153
- * Text to copy
154
- * @required
1097
+ * Source text to copy (can be reactive)
155
1098
  */
156
- value: string;
1099
+ source?: string | Ref<string>;
157
1100
  /**
158
1101
  * Callback on copy success
159
1102
  */
160
- onSuccess?: CopySuccessCallback;
1103
+ onSuccess?: (text: string) => void;
161
1104
  /**
162
1105
  * Callback on copy error
163
1106
  */
164
- onError?: CopyErrorCallback;
165
- /**
166
- * Tooltip text for the copy button
167
- */
168
- title?: string;
1107
+ onError?: (error: Error) => void;
169
1108
  /**
170
- * Whether to disable
171
- * @default false
1109
+ * Time in ms to reset copied state
1110
+ * @default 1500
172
1111
  */
173
- disabled?: boolean;
1112
+ copiedTimeout?: number;
174
1113
  }
175
1114
 
176
1115
  /**
177
- * Copy success callback
178
- */
179
- export declare type CopySuccessCallback = (text: string) => void;
180
-
181
- /**
182
- * Directive binding value type
1116
+ * Return type for useCopy composable
183
1117
  */
184
- export declare type CountdownBinding = CountdownOptions | Date | number | string;
185
-
186
- /**
187
- * Countdown complete callback
188
- */
189
- export declare type CountdownCompleteCallback = () => void;
1118
+ export declare interface UseCopyReturn {
1119
+ /**
1120
+ * Copy function
1121
+ * @param text - Optional text to copy (overrides source)
1122
+ */
1123
+ copy: (text?: string) => Promise<boolean>;
1124
+ /**
1125
+ * Whether the last copy was successful
1126
+ */
1127
+ copied: Readonly<Ref<boolean>>;
1128
+ /**
1129
+ * Error from the last copy attempt
1130
+ */
1131
+ error: Readonly<Ref<Error | null>>;
1132
+ /**
1133
+ * Whether clipboard API is supported
1134
+ */
1135
+ isSupported: boolean;
1136
+ }
190
1137
 
191
1138
  /**
192
- * Countdown format function
1139
+ * Composable for countdown timer functionality
1140
+ *
1141
+ * @param options - Configuration options
1142
+ * @returns Countdown utilities and state
1143
+ *
1144
+ * @example
1145
+ * ```vue
1146
+ * <script setup>
1147
+ * import { useCountdown } from 'directix'
1148
+ *
1149
+ * const targetDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour from now
1150
+ *
1151
+ * const { formatted, running, completed, pause, resume } = useCountdown({
1152
+ * target: targetDate,
1153
+ * format: 'hh:mm:ss',
1154
+ * onComplete: () => console.log('Done!')
1155
+ * })
1156
+ * </script>
1157
+ *
1158
+ * <template>
1159
+ * <div>
1160
+ * <p>{{ formatted }}</p>
1161
+ * <button @click="pause" v-if="running">Pause</button>
1162
+ * <button @click="resume" v-if="!running && !completed">Resume</button>
1163
+ * </div>
1164
+ * </template>
1165
+ * ```
193
1166
  */
194
- export declare type CountdownFormatFunction = (time: CountdownTime) => string;
1167
+ export declare function useCountdown(options: UseCountdownOptions): UseCountdownReturn;
195
1168
 
196
1169
  /**
197
- * Countdown directive options
1170
+ * Options for useCountdown composable
198
1171
  */
199
- export declare interface CountdownOptions {
1172
+ export declare interface UseCountdownOptions {
200
1173
  /**
201
1174
  * Target time (Date object, timestamp, or ISO string)
202
1175
  * @required
203
1176
  */
204
- target: Date | number | string;
1177
+ target: Date | number | string | Ref<Date | number | string>;
205
1178
  /**
206
1179
  * Format string or custom format function
207
1180
  * - 'dd:hh:mm:ss' - Days:Hours:Minutes:Seconds
@@ -210,7 +1183,7 @@ export declare interface CountdownOptions {
210
1183
  * - 'ss' - Seconds only
211
1184
  * @default 'hh:mm:ss'
212
1185
  */
213
- format?: string | CountdownFormatFunction;
1186
+ format?: string | CountdownFormatFunction | Ref<string | CountdownFormatFunction>;
214
1187
  /**
215
1188
  * Callback when countdown completes
216
1189
  */
@@ -223,17 +1196,17 @@ export declare interface CountdownOptions {
223
1196
  * Update interval in milliseconds
224
1197
  * @default 1000
225
1198
  */
226
- interval?: number;
1199
+ interval?: number | Ref<number>;
227
1200
  /**
228
1201
  * Whether to show milliseconds
229
1202
  * @default false
230
1203
  */
231
- showMilliseconds?: boolean;
1204
+ showMilliseconds?: boolean | Ref<boolean>;
232
1205
  /**
233
1206
  * Whether to auto-start
234
1207
  * @default true
235
1208
  */
236
- autoStart?: boolean;
1209
+ autoStart?: boolean | Ref<boolean>;
237
1210
  /**
238
1211
  * Custom labels for i18n
239
1212
  */
@@ -247,215 +1220,168 @@ export declare interface CountdownOptions {
247
1220
  }
248
1221
 
249
1222
  /**
250
- * Countdown tick callback
251
- */
252
- export declare type CountdownTickCallback = (time: CountdownTime) => void;
253
-
254
- /**
255
- * Countdown time object
256
- */
257
- export declare interface CountdownTime {
258
- days: number;
259
- hours: number;
260
- minutes: number;
261
- seconds: number;
262
- milliseconds: number;
263
- total: number;
264
- }
265
-
266
- /**
267
- * Vue 2 directive adapter
268
- * @returns Vue 2 directive object with bind/inserted/update/unbind hooks
269
- */
270
- export declare function createVue2Directive<T, B extends Element>(hooks: DirectiveHooks<T, B>): Record<string, any>;
271
-
272
- /**
273
- * Vue 3 directive adapter
274
- * @returns Vue 3 directive object with created/mounted/updated/unmounted hooks
275
- */
276
- export declare function createVue3Directive<T, B extends Element>(hooks: DirectiveHooks<T, B>): Record<string, any>;
277
-
278
- /**
279
- * Cross-version directive type (compatible with Vue 2/3)
280
- */
281
- export declare type CrossVersionDirective = Directive | Vue2DirectiveHooks | Vue3DirectiveHooks;
282
-
283
- /**
284
- * Directive binding value type
285
- */
286
- export declare type DebounceBinding<T extends (...args: any[]) => any = any> = T | DebounceOptions<T>;
287
-
288
- /**
289
- * Debounced function type
290
- */
291
- export declare interface DebouncedFunction<T extends (...args: any[]) => any> {
292
- (...args: Parameters<T>): void;
293
- cancel: () => void;
294
- flush: () => void;
295
- }
296
-
297
- /**
298
- * Debounce function
299
- */
300
- export declare function debounceFn<T extends (...args: any[]) => any>(func: T, wait?: number, options?: {
301
- leading?: boolean;
302
- trailing?: boolean;
303
- }): ((...args: Parameters<T>) => void) & {
304
- cancel: () => void;
305
- flush: () => void;
306
- };
307
-
308
- /**
309
- * Debounce directive options
1223
+ * Return type for useCountdown composable
310
1224
  */
311
- export declare interface DebounceOptions<T extends (...args: any[]) => any = any> {
1225
+ export declare interface UseCountdownReturn {
312
1226
  /**
313
- * Function to debounce
1227
+ * Current countdown time
314
1228
  */
315
- handler: T;
1229
+ time: Ref<CountdownTime>;
316
1230
  /**
317
- * Delay time in milliseconds
318
- * @default 300
1231
+ * Formatted time string
319
1232
  */
320
- wait?: number;
1233
+ formatted: Ref<string>;
321
1234
  /**
322
- * Whether to invoke immediately before delay starts
323
- * @default false
1235
+ * Whether countdown is running
324
1236
  */
325
- leading?: boolean;
1237
+ running: Ref<boolean>;
326
1238
  /**
327
- * Whether to invoke after delay ends
328
- * @default true
1239
+ * Whether countdown is paused
329
1240
  */
330
- trailing?: boolean;
331
- }
332
-
333
- /**
334
- * Deep clone an object
335
- */
336
- export declare function deepClone<T>(obj: T): T;
337
-
338
- /**
339
- * Deep merge objects
340
- */
341
- export declare function deepMerge<T extends Record<string, any>>(target: T, ...sources: Partial<T>[]): T;
342
-
343
- /**
344
- * Define a cross-version compatible directive
345
- * @param definition The directive definition
346
- * @returns Vue directive object
347
- */
348
- export declare function defineDirective<T = any, B extends Element = Element>(definition: DirectiveDefinition<T, B>): Directive;
349
-
350
- /**
351
- * Define a directive group
352
- */
353
- export declare function defineDirectiveGroup(name: string, directives: Record<string, any>): {
354
- name: string;
355
- directives: Record<string, any>;
356
- install: (app: any) => void;
357
- };
358
-
359
- /**
360
- * Unified directive binding object
361
- */
362
- export declare interface DirectiveBinding<T = any> {
363
- /** The value passed to the directive */
364
- value: T;
365
- /** The previous value */
366
- oldValue: T | null;
367
- /** The directive argument (v-xxx:arg) */
368
- arg?: string;
369
- /** The modifiers object (v-xxx.modifier) */
370
- modifiers: Record<string, boolean>;
371
- /** The component instance */
372
- instance: ComponentPublicInstance | null;
1241
+ paused: Ref<boolean>;
1242
+ /**
1243
+ * Whether countdown has completed
1244
+ */
1245
+ completed: Ref<boolean>;
1246
+ /**
1247
+ * Start the countdown
1248
+ */
1249
+ start: () => void;
1250
+ /**
1251
+ * Pause the countdown
1252
+ */
1253
+ pause: () => void;
1254
+ /**
1255
+ * Resume the countdown
1256
+ */
1257
+ resume: () => void;
1258
+ /**
1259
+ * Reset the countdown
1260
+ */
1261
+ reset: () => void;
373
1262
  }
374
1263
 
375
1264
  /**
376
- * Directive definition interface
377
- */
378
- export declare interface DirectiveDefinition<T = any, B extends Element = Element> extends DirectiveHooks<T, B> {
379
- /** The directive name */
380
- name: string;
381
- /** The Vue version compatibility */
382
- version?: '2' | '3' | 'both';
383
- /** Whether SSR compatible */
384
- ssr?: boolean;
385
- /** Default values */
386
- defaults?: Partial<T>;
387
- }
1265
+ * Composable for debouncing function calls
1266
+ *
1267
+ * @param options - Configuration options
1268
+ * @returns Debounced function utilities
1269
+ *
1270
+ * @example
1271
+ * ```vue
1272
+ * <script setup>
1273
+ * import { ref } from 'vue'
1274
+ * import { useDebounce } from 'directix'
1275
+ *
1276
+ * const searchQuery = ref('')
1277
+ *
1278
+ * const { run: debouncedSearch } = useDebounce({
1279
+ * handler: (query: string) => {
1280
+ * console.log('Searching:', query)
1281
+ * },
1282
+ * wait: 500
1283
+ * })
1284
+ *
1285
+ * // Watch and debounce
1286
+ * watch(searchQuery, (query) => {
1287
+ * debouncedSearch(query)
1288
+ * })
1289
+ * </script>
1290
+ * ```
1291
+ */
1292
+ export declare function useDebounce<T extends (...args: any[]) => any>(options: UseDebounceOptions<T>): UseDebounceReturn<T>;
388
1293
 
389
1294
  /**
390
- * Unified directive hooks
1295
+ * Options for useDebounce composable
391
1296
  */
392
- export declare interface DirectiveHooks<T = any, B extends Element = Element> {
1297
+ export declare interface UseDebounceOptions<T extends (...args: any[]) => any> {
393
1298
  /**
394
- * Called when the directive is bound to an element
395
- * @param el The bound DOM element
396
- * @param binding The binding object
397
- * @param vnode The Vue virtual node
1299
+ * Function to debounce
398
1300
  */
399
- mounted?: (el: B, binding: DirectiveBinding<T>, vnode: VNode) => void;
1301
+ handler: T;
400
1302
  /**
401
- * Called when the element is updated
402
- * @param el The bound DOM element
403
- * @param binding The new binding object
404
- * @param vnode The new virtual node
405
- * @param prevBinding The previous binding object
406
- * @param prevVnode The previous virtual node
1303
+ * Delay time in milliseconds
1304
+ * @default 300
407
1305
  */
408
- updated?: (el: B, binding: DirectiveBinding<T>, vnode: VNode, prevBinding: DirectiveBinding<T>, prevVnode: VNode) => void;
1306
+ wait?: number | Ref<number>;
409
1307
  /**
410
- * Called when the directive is unbound
411
- * @param el The bound DOM element
412
- * @param binding The binding object
413
- * @param vnode The virtual node
1308
+ * Whether to invoke immediately before delay starts
1309
+ * @default false
414
1310
  */
415
- unmounted?: (el: B, binding: DirectiveBinding<T>, vnode: VNode) => void;
1311
+ leading?: boolean | Ref<boolean>;
1312
+ /**
1313
+ * Whether to invoke after delay ends
1314
+ * @default true
1315
+ */
1316
+ trailing?: boolean | Ref<boolean>;
416
1317
  }
417
1318
 
418
1319
  /**
419
- * Directive installation options
1320
+ * Return type for useDebounce composable
420
1321
  */
421
- export declare interface DirectiveInstallOptions {
422
- /** List of directive names to register, registers all if not provided */
423
- directives?: string[];
424
- /** Whether to register all directives */
425
- all?: boolean;
426
- /** Global configuration */
427
- config?: Record<string, any>;
1322
+ export declare interface UseDebounceReturn<T extends (...args: any[]) => any> {
1323
+ /**
1324
+ * Debounced function
1325
+ */
1326
+ run: (...args: Parameters<T>) => void;
1327
+ /**
1328
+ * Cancel any pending execution
1329
+ */
1330
+ cancel: () => void;
1331
+ /**
1332
+ * Immediately invoke if pending
1333
+ */
1334
+ flush: () => void;
1335
+ /**
1336
+ * Check if there is a pending execution
1337
+ */
1338
+ pending: () => boolean;
428
1339
  }
429
1340
 
430
1341
  /**
431
- * Directix plugin
432
- */
433
- export declare const Directix: Plugin_2;
434
-
435
- /**
436
- * Draggable axis
437
- */
438
- export declare type DraggableAxis = 'x' | 'y' | 'both';
439
-
440
- /**
441
- * Directive binding value type
1342
+ * Composable for making elements draggable
1343
+ *
1344
+ * @param options - Configuration options
1345
+ * @returns Draggable utilities
1346
+ *
1347
+ * @example
1348
+ * ```vue
1349
+ * <script setup>
1350
+ * import { ref } from 'vue'
1351
+ * import { useDraggable } from 'directix'
1352
+ *
1353
+ * const target = ref(null)
1354
+ * const { position, isDragging, bind } = useDraggable({
1355
+ * constrain: true,
1356
+ * onEnd: (pos) => console.log('Dropped at:', pos)
1357
+ * })
1358
+ *
1359
+ * onMounted(() => bind(target.value))
1360
+ * </script>
1361
+ *
1362
+ * <template>
1363
+ * <div ref="target" :class="{ dragging: isDragging }">
1364
+ * Drag me!
1365
+ * </div>
1366
+ * </template>
1367
+ * ```
442
1368
  */
443
- export declare type DraggableBinding = boolean | DraggableOptions;
1369
+ export declare function useDraggable(options?: UseDraggableOptions): UseDraggableReturn;
444
1370
 
445
1371
  /**
446
- * Draggable directive options
1372
+ * Options for useDraggable composable
447
1373
  */
448
- export declare interface DraggableOptions {
1374
+ export declare interface UseDraggableOptions {
449
1375
  /**
450
1376
  * Drag axis
451
1377
  * @default 'both'
452
1378
  */
453
- axis?: DraggableAxis;
1379
+ axis?: DraggableAxis | Ref<DraggableAxis>;
454
1380
  /**
455
1381
  * Constrain to parent element
456
1382
  * @default false
457
1383
  */
458
- constrain?: boolean;
1384
+ constrain?: boolean | Ref<boolean>;
459
1385
  /**
460
1386
  * Boundary element selector or element
461
1387
  */
@@ -465,1392 +1391,1940 @@ export declare interface DraggableOptions {
465
1391
  */
466
1392
  handle?: string;
467
1393
  /**
468
- * Whether dragging is disabled
469
- * @default false
1394
+ * Grid snapping [x, y]
470
1395
  */
471
- disabled?: boolean;
1396
+ grid?: [number, number] | Ref<[number, number]>;
472
1397
  /**
473
- * Grid snapping [x, y]
1398
+ * Whether dragging is disabled
1399
+ * @default false
474
1400
  */
475
- grid?: [number, number];
1401
+ disabled?: boolean | Ref<boolean>;
476
1402
  /**
477
1403
  * Start drag callback
478
1404
  */
479
- onStart?: (position: {
480
- x: number;
481
- y: number;
482
- }, event: MouseEvent | TouchEvent) => void;
1405
+ onStart?: (position: Position, event: MouseEvent | TouchEvent) => void;
483
1406
  /**
484
1407
  * Drag callback
485
1408
  */
486
- onDrag?: (position: {
487
- x: number;
488
- y: number;
489
- }, event: MouseEvent | TouchEvent) => void;
1409
+ onDrag?: (position: Position, event: MouseEvent | TouchEvent) => void;
490
1410
  /**
491
1411
  * End drag callback
492
1412
  */
493
- onEnd?: (position: {
494
- x: number;
495
- y: number;
496
- }, event: MouseEvent | TouchEvent) => void;
1413
+ onEnd?: (position: Position, event: MouseEvent | TouchEvent) => void;
1414
+ }
1415
+
1416
+ /**
1417
+ * Return type for useDraggable composable
1418
+ */
1419
+ export declare interface UseDraggableReturn {
1420
+ /** Current position */
1421
+ position: Readonly<Ref<Position>>;
1422
+ /** Whether the element is being dragged */
1423
+ isDragging: Readonly<Ref<boolean>>;
1424
+ /** Reset position to origin */
1425
+ reset: () => void;
1426
+ /** Bind draggable behavior to an element */
1427
+ bind: (element: HTMLElement) => () => void;
497
1428
  }
498
1429
 
499
1430
  /**
500
- * Directive binding value type
1431
+ * Composable for text truncation with ellipsis
1432
+ *
1433
+ * @param options - Configuration options
1434
+ * @returns Truncated text utilities
1435
+ *
1436
+ * @example
1437
+ * ```vue
1438
+ * <script setup>
1439
+ * import { ref } from 'vue'
1440
+ * import { useEllipsis } from 'directix'
1441
+ *
1442
+ * const longText = ref('This is a very long text that needs to be truncated')
1443
+ *
1444
+ * const { truncated, isTruncated } = useEllipsis({
1445
+ * text: longText,
1446
+ * maxWidth: 200,
1447
+ * lines: 1
1448
+ * })
1449
+ * </script>
1450
+ *
1451
+ * <template>
1452
+ * <span :title="isTruncated ? longText : ''">
1453
+ * {{ truncated }}
1454
+ * </span>
1455
+ * </template>
1456
+ * ```
501
1457
  */
502
- export declare type EllipsisBinding = number | EllipsisOptions;
1458
+ export declare function useEllipsis(options: UseEllipsisOptions): UseEllipsisReturn;
503
1459
 
504
1460
  /**
505
- * Ellipsis directive options
1461
+ * Options for useEllipsis composable
506
1462
  */
507
- export declare interface EllipsisOptions {
1463
+ export declare interface UseEllipsisOptions {
1464
+ /**
1465
+ * The text to potentially truncate
1466
+ */
1467
+ text: string | Ref<string>;
508
1468
  /**
509
1469
  * Number of lines to show before truncating
510
1470
  * @default 1
511
1471
  */
512
- lines?: number;
1472
+ lines?: number | Ref<number>;
513
1473
  /**
514
1474
  * Custom ellipsis string
515
1475
  * @default '...'
516
1476
  */
517
- ellipsis?: string;
1477
+ ellipsis?: string | Ref<string>;
518
1478
  /**
519
- * Whether to expand on click
520
- * @default false
1479
+ * Maximum width in pixels (0 = no limit)
1480
+ * @default 0
1481
+ */
1482
+ maxWidth?: number | Ref<number>;
1483
+ }
1484
+
1485
+ /**
1486
+ * Return type for useEllipsis composable
1487
+ */
1488
+ export declare interface UseEllipsisReturn {
1489
+ /**
1490
+ * The truncated text
1491
+ */
1492
+ truncated: Ref<string>;
1493
+ /**
1494
+ * Whether the text is truncated
1495
+ */
1496
+ isTruncated: Ref<boolean>;
1497
+ /**
1498
+ * Original text
1499
+ */
1500
+ original: Ref<string>;
1501
+ /**
1502
+ * Calculate truncation for a given width
1503
+ */
1504
+ calculateForWidth: (width: number) => string;
1505
+ /**
1506
+ * Check if text would be truncated at given width
1507
+ */
1508
+ wouldTruncate: (width: number) => boolean;
1509
+ }
1510
+
1511
+ /**
1512
+ * Composable for managing element focus
1513
+ *
1514
+ * @param options - Configuration options
1515
+ * @returns Focus utilities
1516
+ *
1517
+ * @example
1518
+ * ```vue
1519
+ * <script setup>
1520
+ * import { ref } from 'vue'
1521
+ * import { useFocus } from 'directix'
1522
+ *
1523
+ * const input = ref(null)
1524
+ * const { isFocused, focus, bind } = useFocus({
1525
+ * onBlur: () => validate()
1526
+ * })
1527
+ *
1528
+ * onMounted(() => bind(input.value))
1529
+ *
1530
+ * // Programmatically focus
1531
+ * function handleButtonClick() {
1532
+ * focus()
1533
+ * }
1534
+ * </script>
1535
+ *
1536
+ * <template>
1537
+ * <input ref="input" />
1538
+ * <button @click="focus">Focus Input</button>
1539
+ * </template>
1540
+ * ```
1541
+ */
1542
+ export declare function useFocus(options?: UseFocusOptions): UseFocusReturn;
1543
+
1544
+ /**
1545
+ * Options for useFocus composable
1546
+ */
1547
+ export declare interface UseFocusOptions {
1548
+ /**
1549
+ * Callback when element is focused
521
1550
  */
522
- expandable?: boolean;
1551
+ onFocus?: (event: FocusEvent) => void;
523
1552
  /**
524
- * Title attribute behavior
525
- * - 'auto': Show full text as title only when truncated
526
- * - 'always': Always show full text as title
527
- * - 'none': Don't show title
528
- * @default 'auto'
1553
+ * Callback when element loses focus
529
1554
  */
530
- titleBehavior?: 'auto' | 'always' | 'none';
1555
+ onBlur?: (event: FocusEvent) => void;
1556
+ }
1557
+
1558
+ /**
1559
+ * Return type for useFocus composable
1560
+ */
1561
+ export declare interface UseFocusReturn {
1562
+ /** Whether the element is currently focused */
1563
+ isFocused: Readonly<Ref<boolean>>;
1564
+ /** Focus the element */
1565
+ focus: () => void;
1566
+ /** Blur the element */
1567
+ blur: () => void;
1568
+ /** Bind focus tracking to an element */
1569
+ bind: (element: HTMLElement) => () => void;
531
1570
  }
532
1571
 
533
1572
  /**
534
- * Directive binding value type
1573
+ * Composable for handling keyboard shortcuts
1574
+ *
1575
+ * @param options - Configuration options
1576
+ * @returns Hotkey utilities
1577
+ *
1578
+ * @example
1579
+ * ```vue
1580
+ * <script setup>
1581
+ * import { useHotkey } from 'directix'
1582
+ *
1583
+ * const { enable, disable, add, remove } = useHotkey({
1584
+ * hotkeys: [
1585
+ * { key: 'ctrl+s', handler: (e) => save() },
1586
+ * { key: 'ctrl+z', handler: (e) => undo() },
1587
+ * ]
1588
+ * })
1589
+ *
1590
+ * // Add dynamic hotkey
1591
+ * add({ key: 'esc', handler: (e) => closeModal() })
1592
+ * </script>
1593
+ * ```
535
1594
  */
536
- export declare type FocusBinding = boolean | FocusOptions_2;
1595
+ export declare function useHotkey(options?: UseHotkeyOptions): UseHotkeyReturn;
537
1596
 
538
1597
  /**
539
- * Focus directive options
1598
+ * Options for useHotkey composable
540
1599
  */
541
- declare interface FocusOptions_2 {
1600
+ export declare interface UseHotkeyOptions {
542
1601
  /**
543
- * Whether to auto focus
544
- * @default true
1602
+ * Single hotkey definition
545
1603
  */
546
- focus?: boolean;
1604
+ hotkey?: HotkeyDefinition;
547
1605
  /**
548
- * Whether to refocus when binding value changes
549
- * @default false
1606
+ * Multiple hotkey definitions
550
1607
  */
551
- refocus?: boolean;
1608
+ hotkeys?: HotkeyDefinition[];
552
1609
  /**
553
- * Callback when focused
1610
+ * Target element to bind events (defaults to document)
554
1611
  */
555
- onFocus?: (el: HTMLElement) => void;
1612
+ target?: HTMLElement | Ref<HTMLElement | null>;
556
1613
  /**
557
- * Callback when blurred
1614
+ * Whether to enable the hotkey(s)
1615
+ * @default true
558
1616
  */
559
- onBlur?: (el: HTMLElement) => void;
1617
+ enabled?: boolean | Ref<boolean>;
560
1618
  }
561
- export { FocusOptions_2 as FocusOptions }
562
1619
 
563
1620
  /**
564
- * Generate unique ID
1621
+ * Return type for useHotkey composable
565
1622
  */
566
- export declare function generateId(prefix?: string): string;
1623
+ export declare interface UseHotkeyReturn {
1624
+ /**
1625
+ * Whether the hotkey is currently enabled
1626
+ */
1627
+ enabled: Ref<boolean>;
1628
+ /**
1629
+ * Enable the hotkey
1630
+ */
1631
+ enable: () => void;
1632
+ /**
1633
+ * Disable the hotkey
1634
+ */
1635
+ disable: () => void;
1636
+ /**
1637
+ * Toggle the hotkey
1638
+ */
1639
+ toggle: () => void;
1640
+ /**
1641
+ * Add a hotkey
1642
+ */
1643
+ add: (hotkey: HotkeyDefinition) => void;
1644
+ /**
1645
+ * Remove a hotkey by key
1646
+ */
1647
+ remove: (key: string) => void;
1648
+ /**
1649
+ * Remove all hotkeys
1650
+ */
1651
+ clear: () => void;
1652
+ }
567
1653
 
568
1654
  /**
569
- * Get nested property value by path
1655
+ * Composable for tracking hover state
1656
+ *
1657
+ * @param options - Configuration options
1658
+ * @returns Hover utilities
1659
+ *
1660
+ * @example
1661
+ * ```vue
1662
+ * <script setup>
1663
+ * import { ref } from 'vue'
1664
+ * import { useHover } from 'directix'
1665
+ *
1666
+ * const buttonRef = ref()
1667
+ * const { isHovering, bind } = useHover({
1668
+ * onEnter: () => console.log('Mouse entered'),
1669
+ * onLeave: () => console.log('Mouse left'),
1670
+ * enterDelay: 100
1671
+ * })
1672
+ *
1673
+ * onMounted(() => {
1674
+ * const unbind = bind(buttonRef.value)
1675
+ * onUnmounted(unbind)
1676
+ * })
1677
+ * </script>
1678
+ *
1679
+ * <template>
1680
+ * <button ref="buttonRef" :class="{ 'is-hovering': isHovering }">
1681
+ * Hover Me
1682
+ * </button>
1683
+ * </template>
1684
+ * ```
570
1685
  */
571
- export declare function get<T = any>(obj: Record<string, any>, path: string, defaultValue?: T): T;
1686
+ export declare function useHover(options?: UseHoverOptions): UseHoverReturn;
572
1687
 
573
1688
  /**
574
- * Get current configuration
1689
+ * Options for useHover composable
575
1690
  */
576
- export declare function getPermissionConfig(): PermissionConfig | null;
1691
+ export declare interface UseHoverOptions {
1692
+ /**
1693
+ * Callback when mouse enters
1694
+ */
1695
+ onEnter?: (event: MouseEvent) => void;
1696
+ /**
1697
+ * Callback when mouse leaves
1698
+ */
1699
+ onLeave?: (event: MouseEvent) => void;
1700
+ /**
1701
+ * CSS class to add when hovering
1702
+ */
1703
+ class?: string;
1704
+ /**
1705
+ * Delay in milliseconds before triggering enter
1706
+ * @default 0
1707
+ */
1708
+ enterDelay?: number | Ref<number>;
1709
+ /**
1710
+ * Delay in milliseconds before triggering leave
1711
+ * @default 0
1712
+ */
1713
+ leaveDelay?: number | Ref<number>;
1714
+ }
577
1715
 
578
1716
  /**
579
- * Get current Vue version
1717
+ * Return type for useHover composable
580
1718
  */
581
- export declare function getVueVersion(): VueVersion;
1719
+ export declare interface UseHoverReturn {
1720
+ /**
1721
+ * Whether the element is currently being hovered
1722
+ */
1723
+ isHovering: Readonly<Ref<boolean>>;
1724
+ /**
1725
+ * Bind events to an element
1726
+ */
1727
+ bind: (element: HTMLElement) => () => void;
1728
+ }
582
1729
 
583
- export declare type HotkeyBinding = HotkeyHandler | HotkeyDefinition | HotkeyDefinition[] | Record<string, HotkeyHandler | HotkeyDefinition>;
1730
+ /**
1731
+ * Composable for image preview functionality
1732
+ *
1733
+ * @param options - Configuration options
1734
+ * @returns Image preview utilities
1735
+ *
1736
+ * @example
1737
+ * ```vue
1738
+ * <script setup>
1739
+ * import { ref } from 'vue'
1740
+ * import { useImagePreview } from 'directix'
1741
+ *
1742
+ * const imageRef = ref(null)
1743
+ * const { isOpen, bind, open, close } = useImagePreview()
1744
+ *
1745
+ * onMounted(() => bind(imageRef.value))
1746
+ *
1747
+ * function openCustomImage() {
1748
+ * open('https://example.com/high-res.jpg')
1749
+ * }
1750
+ * </script>
1751
+ *
1752
+ * <template>
1753
+ * <img ref="imageRef" src="thumbnail.jpg" />
1754
+ * </template>
1755
+ * ```
1756
+ */
1757
+ export declare function useImagePreview(options?: UseImagePreviewOptions): UseImagePreviewReturn;
584
1758
 
585
- export declare interface HotkeyDefinition {
586
- key: string;
587
- modifiers?: ModifierKey[];
588
- handler: HotkeyHandler;
589
- prevent?: boolean;
590
- stop?: boolean;
591
- disabled?: boolean;
592
- global?: boolean;
1759
+ /**
1760
+ * Options for useImagePreview composable
1761
+ */
1762
+ export declare interface UseImagePreviewOptions {
1763
+ /**
1764
+ * Initial image URL to preview
1765
+ */
1766
+ src?: string | Ref<string>;
1767
+ /**
1768
+ * Close on click outside
1769
+ * @default true
1770
+ */
1771
+ closeOnClickOutside?: boolean;
1772
+ /**
1773
+ * Close on escape key
1774
+ * @default true
1775
+ */
1776
+ closeOnEsc?: boolean;
1777
+ /**
1778
+ * Show close button
1779
+ * @default true
1780
+ */
1781
+ showCloseButton?: boolean;
1782
+ /**
1783
+ * Callback when preview opens
1784
+ */
1785
+ onOpen?: () => void;
1786
+ /**
1787
+ * Callback when preview closes
1788
+ */
1789
+ onClose?: () => void;
593
1790
  }
594
1791
 
595
- export declare type HotkeyHandler = (event: KeyboardEvent) => void;
596
-
597
1792
  /**
598
- * Directive binding value type
1793
+ * Return type for useImagePreview composable
599
1794
  */
600
- export declare type HoverBinding = HoverHandler | HoverOptions;
1795
+ export declare interface UseImagePreviewReturn {
1796
+ /** Whether the preview is open */
1797
+ isOpen: Readonly<Ref<boolean>>;
1798
+ /** Current image URL */
1799
+ currentSrc: Readonly<Ref<string>>;
1800
+ /** Open preview with an image */
1801
+ open: (src?: string) => void;
1802
+ /** Close preview */
1803
+ close: () => void;
1804
+ /** Bind click-to-preview to an image element */
1805
+ bind: (element: HTMLImageElement) => () => void;
1806
+ }
601
1807
 
602
1808
  /**
603
- * Hover state change handler
1809
+ * Composable for detecting element intersection with viewport
1810
+ *
1811
+ * @param options - Configuration options
1812
+ * @returns Intersection utilities
1813
+ *
1814
+ * @example
1815
+ * ```vue
1816
+ * <script setup>
1817
+ * import { ref } from 'vue'
1818
+ * import { useIntersect } from 'directix'
1819
+ *
1820
+ * const target = ref(null)
1821
+ * const { isIntersecting, bind } = useIntersect({
1822
+ * threshold: 0.5,
1823
+ * onEnter: () => console.log('Entered'),
1824
+ * onLeave: () => console.log('Left')
1825
+ * })
1826
+ *
1827
+ * onMounted(() => bind(target.value))
1828
+ * </script>
1829
+ *
1830
+ * <template>
1831
+ * <div ref="target" :class="{ visible: isIntersecting }">
1832
+ * I'm visible!
1833
+ * </div>
1834
+ * </template>
1835
+ * ```
604
1836
  */
605
- export declare type HoverHandler = (isHovering: boolean, event: MouseEvent) => void;
1837
+ export declare function useIntersect(options?: UseIntersectOptions): UseIntersectReturn;
606
1838
 
607
1839
  /**
608
- * Hover directive options
1840
+ * Options for useIntersect composable
609
1841
  */
610
- export declare interface HoverOptions {
1842
+ export declare interface UseIntersectOptions {
611
1843
  /**
612
- * Callback when hover state changes
1844
+ * Callback when element intersects
613
1845
  */
614
- handler?: HoverHandler;
1846
+ handler?: IntersectHandler;
615
1847
  /**
616
- * Callback when mouse enters
1848
+ * Callback when element enters viewport
617
1849
  */
618
- onEnter?: (event: MouseEvent) => void;
1850
+ onEnter?: (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
619
1851
  /**
620
- * Callback when mouse leaves
1852
+ * Callback when element leaves viewport
621
1853
  */
622
- onLeave?: (event: MouseEvent) => void;
1854
+ onLeave?: (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
623
1855
  /**
624
- * CSS class to add when hovering
625
- * @default 'v-hover'
1856
+ * Callback when element changes intersection
626
1857
  */
627
- class?: string;
1858
+ onChange?: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void;
628
1859
  /**
629
- * Whether to disable
630
- * @default false
1860
+ * Root element for intersection
1861
+ * @default null (viewport)
631
1862
  */
632
- disabled?: boolean;
1863
+ root?: Element | null | Ref<Element | null>;
633
1864
  /**
634
- * Delay in milliseconds before triggering enter
635
- * @default 0
1865
+ * Margin around the root
1866
+ * @default '0px'
636
1867
  */
637
- enterDelay?: number;
1868
+ rootMargin?: string;
638
1869
  /**
639
- * Delay in milliseconds before triggering leave
1870
+ * Threshold(s) at which to trigger callback
640
1871
  * @default 0
641
1872
  */
642
- leaveDelay?: number;
1873
+ threshold?: number | number[];
1874
+ /**
1875
+ * Whether to trigger only once
1876
+ * @default false
1877
+ */
1878
+ once?: boolean;
643
1879
  }
644
1880
 
645
- export declare type ImagePreviewBinding = string | ImagePreviewOptions;
646
-
647
1881
  /**
648
- * Image preview options
1882
+ * Return type for useIntersect composable
649
1883
  */
650
- export declare interface ImagePreviewOptions {
651
- /** Image source URL */
652
- src?: string;
653
- /** Preview image source URL (higher resolution) */
654
- previewSrc?: string;
655
- /** Alt text for accessibility */
656
- alt?: string;
657
- /** Whether preview is disabled @default false */
658
- disabled?: boolean;
659
- /** Close on click outside @default true */
660
- closeOnClickOutside?: boolean;
661
- /** Close on escape key @default true */
662
- closeOnEsc?: boolean;
663
- /** Show close button @default true */
664
- showCloseButton?: boolean;
665
- /** Z-index of the preview overlay @default 9999 */
666
- zIndex?: number;
667
- /** Custom class for the preview overlay */
668
- class?: string;
669
- /** Enable pinch zoom on mobile @default true */
670
- enablePinchZoom?: boolean;
671
- /** Enable double tap to zoom @default true */
672
- enableDoubleTap?: boolean;
673
- /** Enable swipe up to close @default true */
674
- enableSwipeClose?: boolean;
675
- /** Show zoom indicator @default true */
676
- showZoomIndicator?: boolean;
677
- /** Minimum zoom scale @default 0.5 */
678
- minScale?: number;
679
- /** Maximum zoom scale @default 5 */
680
- maxScale?: number;
681
- /** Callback when preview opens */
682
- onOpen?: () => void;
683
- /** Callback when preview closes */
684
- onClose?: () => void;
1884
+ export declare interface UseIntersectReturn {
1885
+ /**
1886
+ * Whether the element is currently intersecting
1887
+ */
1888
+ isIntersecting: Readonly<Ref<boolean>>;
1889
+ /**
1890
+ * Current intersection ratio
1891
+ */
1892
+ ratio: Readonly<Ref<number>>;
1893
+ /**
1894
+ * Bind intersection observer to an element
1895
+ */
1896
+ bind: (element: HTMLElement) => () => void;
1897
+ /**
1898
+ * Stop observing
1899
+ */
1900
+ stop: () => void;
685
1901
  }
686
1902
 
687
1903
  /**
688
- * Directive binding value type
689
- */
690
- export declare type InfiniteScrollBinding = InfiniteScrollHandler | InfiniteScrollOptions;
691
-
692
- /**
693
- * Infinite scroll handler
1904
+ * Composable for detecting long press gestures
1905
+ *
1906
+ * @param options - Configuration options
1907
+ * @returns Long press utilities
1908
+ *
1909
+ * @example
1910
+ * ```vue
1911
+ * <script setup>
1912
+ * import { useLongPress } from 'directix'
1913
+ *
1914
+ * const { bind, isPressing } = useLongPress({
1915
+ * onTrigger: (event) => {
1916
+ * console.log('Long press triggered!')
1917
+ * },
1918
+ * duration: 800
1919
+ * })
1920
+ *
1921
+ * // Bind to element
1922
+ * const buttonRef = ref()
1923
+ * onMounted(() => {
1924
+ * const unbind = bind(buttonRef.value)
1925
+ * onUnmounted(unbind)
1926
+ * })
1927
+ * </script>
1928
+ *
1929
+ * <template>
1930
+ * <button ref="buttonRef">Long Press Me</button>
1931
+ * </template>
1932
+ * ```
694
1933
  */
695
- export declare type InfiniteScrollHandler = () => void | Promise<void>;
1934
+ export declare function useLongPress(options?: UseLongPressOptions): UseLongPressReturn;
696
1935
 
697
1936
  /**
698
- * Infinite scroll directive options
1937
+ * Options for useLongPress composable
699
1938
  */
700
- export declare interface InfiniteScrollOptions {
1939
+ export declare interface UseLongPressOptions {
701
1940
  /**
702
- * Handler to call when scrolling to bottom
703
- * @required
1941
+ * Duration in milliseconds to trigger long press
1942
+ * @default 500
704
1943
  */
705
- handler: InfiniteScrollHandler;
1944
+ duration?: number | Ref<number>;
706
1945
  /**
707
- * Distance from bottom to trigger load (in pixels)
708
- * @default 0
1946
+ * Maximum movement distance before canceling
1947
+ * @default 10
709
1948
  */
710
- distance?: number;
1949
+ distance?: number | Ref<number>;
711
1950
  /**
712
- * Whether to disable
713
- * @default false
1951
+ * Callback when long press starts (on mousedown/touchstart)
714
1952
  */
715
- disabled?: boolean;
1953
+ onStart?: (event: MouseEvent | TouchEvent) => void;
716
1954
  /**
717
- * Whether currently loading
718
- * @default false
1955
+ * Callback when long press is triggered
719
1956
  */
720
- loading?: boolean;
1957
+ onTrigger?: (event: MouseEvent | TouchEvent) => void;
721
1958
  /**
722
- * Whether to use IntersectionObserver (more efficient)
723
- * @default true
1959
+ * Callback when long press is canceled
724
1960
  */
725
- useIntersection?: boolean;
1961
+ onCancel?: (event: MouseEvent | TouchEvent) => void;
726
1962
  /**
727
- * Throttle time in milliseconds
728
- * @default 200
1963
+ * Callback on each tick during long press
1964
+ */
1965
+ onTick?: (remaining: number) => void;
1966
+ /**
1967
+ * Interval for onTick callback in milliseconds
1968
+ * @default 100
1969
+ */
1970
+ tickInterval?: number;
1971
+ /**
1972
+ * Whether to prevent default behavior
1973
+ * @default true
729
1974
  */
730
- throttle?: number;
1975
+ prevent?: boolean;
1976
+ }
1977
+
1978
+ /**
1979
+ * Return type for useLongPress composable
1980
+ */
1981
+ export declare interface UseLongPressReturn {
731
1982
  /**
732
- * Custom scroll container
1983
+ * Whether a long press is currently in progress
733
1984
  */
734
- container?: string | Element | null;
1985
+ isPressing: Readonly<Ref<boolean>>;
735
1986
  /**
736
- * Callback when load starts
1987
+ * Start long press detection
737
1988
  */
738
- onLoadStart?: () => void;
1989
+ start: (event: MouseEvent | TouchEvent) => void;
739
1990
  /**
740
- * Callback when load completes
1991
+ * Stop long press detection
741
1992
  */
742
- onLoadEnd?: () => void;
1993
+ stop: (event: MouseEvent | TouchEvent) => void;
743
1994
  /**
744
- * Callback on error
1995
+ * Bind events to an element
745
1996
  */
746
- onError?: (error: Error) => void;
1997
+ bind: (element: HTMLElement) => () => void;
747
1998
  }
748
1999
 
749
2000
  /**
750
- * Directive binding value type
751
- */
752
- export declare type IntersectBinding = IntersectHandler | IntersectOptions;
753
-
754
- /**
755
- * Intersect event handler
2001
+ * Composable for transforming text to lowercase
2002
+ *
2003
+ * @param options - Configuration options
2004
+ * @returns Lowercase text utilities
2005
+ *
2006
+ * @example
2007
+ * ```vue
2008
+ * <script setup>
2009
+ * import { ref } from 'vue'
2010
+ * import { useLowercase } from 'directix'
2011
+ *
2012
+ * const text = ref('HELLO WORLD')
2013
+ *
2014
+ * const { transformed } = useLowercase({ text })
2015
+ * // transformed.value = 'hello world'
2016
+ * </script>
2017
+ *
2018
+ * <template>
2019
+ * <p>{{ transformed }}</p>
2020
+ * </template>
2021
+ * ```
756
2022
  */
757
- export declare type IntersectHandler = (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
2023
+ export declare function useLowercase(options: UseLowercaseOptions): UseLowercaseReturn;
758
2024
 
759
2025
  /**
760
- * Intersect directive options
2026
+ * Options for useLowercase composable
761
2027
  */
762
- export declare interface IntersectOptions {
763
- /** Callback when element intersects */
764
- handler?: IntersectHandler;
765
- /** Callback when element enters viewport */
766
- onEnter?: (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
767
- /** Callback when element leaves viewport */
768
- onLeave?: (entry: IntersectionObserverEntry, observer: IntersectionObserver) => void;
769
- /** Callback when element changes intersection */
770
- onChange?: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void;
771
- /** Root element for intersection @default null (viewport) */
772
- root?: Element | null;
773
- /** Margin around the root @default '0px' */
774
- rootMargin?: string;
775
- /** Threshold(s) at which to trigger callback @default 0 */
776
- threshold?: number | number[];
777
- /** Whether to disable @default false */
778
- disabled?: boolean;
779
- /** Whether to trigger only once @default false */
780
- once?: boolean;
2028
+ export declare interface UseLowercaseOptions {
2029
+ /**
2030
+ * The text to transform
2031
+ */
2032
+ text: string | Ref<string>;
2033
+ /**
2034
+ * Transform only the first character
2035
+ * @default false
2036
+ */
2037
+ first?: boolean | Ref<boolean>;
781
2038
  }
782
2039
 
783
2040
  /**
784
- * Check if value is an array
785
- */
786
- export declare function isArray(value: unknown): value is any[];
787
-
788
- /**
789
- * Check if value is a boolean
790
- */
791
- export declare function isBoolean(value: unknown): value is boolean;
792
-
793
- /**
794
- * Check if browser environment
795
- */
796
- export declare const isBrowser: () => boolean;
797
-
798
- /**
799
- * Check if value is empty
800
- */
801
- export declare function isEmpty(value: unknown): boolean;
802
-
803
- /**
804
- * Check if value is a function
805
- */
806
- export declare function isFunction(value: unknown): value is (...args: any[]) => any;
807
-
808
- /**
809
- * Check if value is a number
810
- */
811
- export declare function isNumber(value: unknown): value is number;
812
-
813
- /**
814
- * Check if value is an object
815
- */
816
- export declare function isObject(value: unknown): value is Record<string, any>;
817
-
818
- /**
819
- * Check if value is a Promise
2041
+ * Return type for useLowercase composable
820
2042
  */
821
- export declare function isPromise<T = any>(value: unknown): value is Promise<T>;
822
-
823
- /**
824
- * Check if server-side rendering
825
- */
826
- export declare const isSSR: () => boolean;
827
-
828
- /**
829
- * Check if value is a string
830
- */
831
- export declare function isString(value: unknown): value is string;
832
-
833
- /**
834
- * Check if Vue 2 (includes 2.7)
835
- */
836
- export declare function isVue2(): boolean;
2043
+ export declare interface UseLowercaseReturn {
2044
+ /**
2045
+ * The transformed text
2046
+ */
2047
+ transformed: Ref<string>;
2048
+ /**
2049
+ * Original text
2050
+ */
2051
+ original: Ref<string>;
2052
+ }
837
2053
 
838
2054
  /**
839
- * Check if Vue 2.7 (has built-in Composition API support)
2055
+ * Composable for formatting numbers as money
2056
+ *
2057
+ * @param options - Configuration options
2058
+ * @returns Money formatting utilities
2059
+ *
2060
+ * @example
2061
+ * ```vue
2062
+ * <script setup>
2063
+ * import { ref } from 'vue'
2064
+ * import { useMoney } from 'directix'
2065
+ *
2066
+ * const price = ref(1234.56)
2067
+ *
2068
+ * const { formatted } = useMoney({
2069
+ * value: price,
2070
+ * symbol: '€',
2071
+ * symbolPosition: 'after'
2072
+ * })
2073
+ * // formatted.value = '1,234.56€'
2074
+ * </script>
2075
+ *
2076
+ * <template>
2077
+ * <span>{{ formatted }}</span>
2078
+ * </template>
2079
+ * ```
840
2080
  */
841
- export declare function isVue27(): boolean;
2081
+ export declare function useMoney(options: UseMoneyOptions): UseMoneyReturn;
842
2082
 
843
2083
  /**
844
- * Check if Vue 3
2084
+ * Options for useMoney composable
845
2085
  */
846
- export declare function isVue3(): boolean;
2086
+ export declare interface UseMoneyOptions {
2087
+ /**
2088
+ * The numeric value
2089
+ */
2090
+ value: number | Ref<number>;
2091
+ /**
2092
+ * Currency symbol
2093
+ * @default '$'
2094
+ */
2095
+ symbol?: string | Ref<string>;
2096
+ /**
2097
+ * Symbol position
2098
+ * @default 'before'
2099
+ */
2100
+ symbolPosition?: 'before' | 'after' | Ref<'before' | 'after'>;
2101
+ /**
2102
+ * Number of decimal places
2103
+ * @default 2
2104
+ */
2105
+ precision?: number | Ref<number>;
2106
+ /**
2107
+ * Thousands separator
2108
+ * @default ','
2109
+ */
2110
+ separator?: string | Ref<string>;
2111
+ /**
2112
+ * Decimal separator
2113
+ * @default '.'
2114
+ */
2115
+ decimal?: string | Ref<string>;
2116
+ }
847
2117
 
848
2118
  /**
849
- * Virtual list item size function
2119
+ * Return type for useMoney composable
850
2120
  */
851
- export declare type ItemSizeFunction = (index: number) => number;
2121
+ export declare interface UseMoneyReturn {
2122
+ /**
2123
+ * The formatted money string
2124
+ */
2125
+ formatted: Ref<string>;
2126
+ /**
2127
+ * The numeric value
2128
+ */
2129
+ value: Ref<number>;
2130
+ /**
2131
+ * Parse a formatted string back to number
2132
+ */
2133
+ parse: (formatted: string) => number;
2134
+ }
852
2135
 
853
2136
  /**
854
- * Directive binding value type
2137
+ * Composable for formatting numbers
2138
+ *
2139
+ * @param options - Configuration options
2140
+ * @returns Number formatting utilities
2141
+ *
2142
+ * @example
2143
+ * ```vue
2144
+ * <script setup>
2145
+ * import { ref } from 'vue'
2146
+ * import { useNumber } from 'directix'
2147
+ *
2148
+ * const count = ref(1234567)
2149
+ *
2150
+ * const { formatted } = useNumber({
2151
+ * value: count,
2152
+ * precision: 2,
2153
+ * suffix: ' items'
2154
+ * })
2155
+ * // formatted.value = '1,234,567.00 items'
2156
+ * </script>
2157
+ *
2158
+ * <template>
2159
+ * <span>{{ formatted }}</span>
2160
+ * </template>
2161
+ * ```
855
2162
  */
856
- export declare type LazyBinding = string | LazyOptions;
2163
+ export declare function useNumber(options: UseNumberOptions): UseNumberReturn;
857
2164
 
858
2165
  /**
859
- * Lazy directive options
2166
+ * Options for useNumber composable
860
2167
  */
861
- export declare interface LazyOptions {
862
- /**
863
- * Image source URL
864
- */
865
- src?: string;
2168
+ export declare interface UseNumberOptions {
866
2169
  /**
867
- * Placeholder image URL
2170
+ * The numeric value
868
2171
  */
869
- placeholder?: string;
2172
+ value: number | Ref<number>;
870
2173
  /**
871
- * Error image URL (shown when loading fails)
2174
+ * Number of decimal places
2175
+ * @default 0
872
2176
  */
873
- error?: string;
2177
+ precision?: number | Ref<number>;
874
2178
  /**
875
- * Preload distance in pixels
876
- * @default 0
2179
+ * Thousands separator
2180
+ * @default ','
877
2181
  */
878
- preload?: number;
2182
+ separator?: string | Ref<string>;
879
2183
  /**
880
- * Callback when image loads successfully
2184
+ * Decimal separator
2185
+ * @default '.'
881
2186
  */
882
- onLoad?: (el: HTMLElement) => void;
2187
+ decimal?: string | Ref<string>;
883
2188
  /**
884
- * Callback when image fails to load
2189
+ * Prefix string (e.g., '$')
885
2190
  */
886
- onError?: (el: HTMLElement, error: Error) => void;
2191
+ prefix?: string | Ref<string>;
887
2192
  /**
888
- * Number of retry attempts
889
- * @default 1
2193
+ * Suffix string (e.g., '%')
890
2194
  */
891
- attempt?: number;
2195
+ suffix?: string | Ref<string>;
2196
+ }
2197
+
2198
+ /**
2199
+ * Return type for useNumber composable
2200
+ */
2201
+ export declare interface UseNumberReturn {
892
2202
  /**
893
- * Filter function, return false to skip loading
2203
+ * The formatted number string
894
2204
  */
895
- filter?: (src: string) => boolean;
2205
+ formatted: Ref<string>;
896
2206
  /**
897
- * Custom IntersectionObserver
2207
+ * The numeric value
898
2208
  */
899
- observer?: IntersectionObserver;
2209
+ value: Ref<number>;
900
2210
  /**
901
- * Whether to disable lazy loading
902
- * @default false
2211
+ * Parse a formatted string back to number
903
2212
  */
904
- disabled?: boolean;
2213
+ parse: (formatted: string) => number;
905
2214
  }
906
2215
 
907
2216
  /**
908
- * Lazy loading state
909
- */
910
- export declare type LazyState = 'pending' | 'loading' | 'loaded' | 'error';
911
-
912
- /**
913
- * Directive binding value type
2217
+ * Composable for checking user permissions
2218
+ *
2219
+ * @param options - Configuration options
2220
+ * @returns Permission utilities
2221
+ *
2222
+ * @example
2223
+ * ```vue
2224
+ * <script setup>
2225
+ * import { usePermission } from 'directix'
2226
+ *
2227
+ * const { granted } = usePermission({
2228
+ * value: 'admin',
2229
+ * getPermissions: () => store.getters.permissions,
2230
+ * getRoles: () => store.getters.roles,
2231
+ * roleMap: { admin: ['*'], editor: ['read', 'write'] }
2232
+ * })
2233
+ * </script>
2234
+ *
2235
+ * <template>
2236
+ * <button v-if="granted">Admin Only Action</button>
2237
+ * </template>
2238
+ * ```
914
2239
  */
915
- export declare type LoadingBinding = boolean | LoadingOptions;
2240
+ export declare function usePermission(options: UsePermissionOptions): UsePermissionReturn;
916
2241
 
917
2242
  /**
918
- * Loading directive options
2243
+ * Options for usePermission composable
919
2244
  */
920
- export declare interface LoadingOptions {
921
- /**
922
- * Loading state
923
- * @default true
924
- */
925
- value?: boolean;
926
- /**
927
- * Loading text to display
928
- */
929
- text?: string;
930
- /**
931
- * CSS class for loading overlay
932
- * @default 'v-loading'
933
- */
934
- loadingClass?: string;
2245
+ export declare interface UsePermissionOptions {
935
2246
  /**
936
- * CSS class for loading spinner
937
- * @default 'v-loading__spinner'
2247
+ * Permission value(s) to check
938
2248
  */
939
- spinnerClass?: string;
2249
+ value: string | string[] | Ref<string | string[]>;
940
2250
  /**
941
- * CSS class for loading text
942
- * @default 'v-loading__text'
2251
+ * Logic for multiple permissions: 'some' (OR) or 'every' (AND)
2252
+ * @default 'some'
943
2253
  */
944
- textClass?: string;
2254
+ mode?: PermissionMode | Ref<PermissionMode>;
945
2255
  /**
946
- * Custom spinner HTML
2256
+ * Custom permission check function
947
2257
  */
948
- spinner?: string;
2258
+ check?: (permission: string | string[], mode: PermissionMode) => boolean;
949
2259
  /**
950
- * Background color
951
- * @default 'rgba(255, 255, 255, 0.9)'
2260
+ * Get current user's permissions
952
2261
  */
953
- background?: string;
2262
+ getPermissions?: () => string[];
954
2263
  /**
955
- * Whether to lock scroll while loading
956
- * @default false
2264
+ * Get current user's roles
957
2265
  */
958
- lock?: boolean;
2266
+ getRoles?: () => string[];
959
2267
  /**
960
- * Whether to disable
961
- * @default false
2268
+ * Role to permission mapping
962
2269
  */
963
- disabled?: boolean;
2270
+ roleMap?: Record<string, string[]>;
964
2271
  }
965
2272
 
966
2273
  /**
967
- * Directive binding value type
2274
+ * Return type for usePermission composable
968
2275
  */
969
- export declare type LongPressBinding = LongPressHandler | LongPressOptions;
2276
+ export declare interface UsePermissionReturn {
2277
+ /** Whether the permission is granted */
2278
+ granted: Readonly<Ref<boolean>>;
2279
+ /** Re-check permission */
2280
+ recheck: () => void;
2281
+ }
970
2282
 
971
2283
  /**
972
- * Long press handler
2284
+ * Composable for printing functionality
2285
+ *
2286
+ * @param options - Configuration options
2287
+ * @returns Print utilities
2288
+ *
2289
+ * @example
2290
+ * ```vue
2291
+ * <script setup>
2292
+ * import { usePrint } from 'directix'
2293
+ *
2294
+ * const { isPrinting, print } = usePrint({
2295
+ * title: 'My Document',
2296
+ * onBeforePrint: () => {
2297
+ * console.log('About to print...')
2298
+ * return true
2299
+ * },
2300
+ * onAfterPrint: () => {
2301
+ * console.log('Print complete!')
2302
+ * }
2303
+ * })
2304
+ *
2305
+ * async function handlePrint() {
2306
+ * await print('#content')
2307
+ * }
2308
+ * </script>
2309
+ *
2310
+ * <template>
2311
+ * <div>
2312
+ * <button @click="handlePrint" :disabled="isPrinting">
2313
+ * {{ isPrinting ? 'Printing...' : 'Print' }}
2314
+ * </button>
2315
+ * <div id="content">Content to print</div>
2316
+ * </div>
2317
+ * </template>
2318
+ * ```
973
2319
  */
974
- export declare type LongPressHandler = (event: MouseEvent | TouchEvent) => void;
2320
+ export declare function usePrint(options?: UsePrintOptions): UsePrintReturn;
975
2321
 
976
2322
  /**
977
- * Long press directive options
2323
+ * Options for usePrint composable
978
2324
  */
979
- export declare interface LongPressOptions {
2325
+ export declare interface UsePrintOptions {
980
2326
  /**
981
- * Callback when long press is triggered
982
- * @required
2327
+ * Title for the printed document
983
2328
  */
984
- handler: LongPressHandler;
2329
+ title?: string | Ref<string>;
985
2330
  /**
986
- * Duration in milliseconds to trigger long press
987
- * @default 500
2331
+ * Additional CSS styles to inject
988
2332
  */
989
- duration?: number;
2333
+ styles?: string | string[] | Ref<string | string[]>;
990
2334
  /**
991
- * Whether to disable
992
- * @default false
2335
+ * Additional CSS URLs to include
993
2336
  */
994
- disabled?: boolean;
2337
+ cssUrls?: string[] | Ref<string[]>;
995
2338
  /**
996
- * Maximum movement distance before canceling
997
- * @default 10
2339
+ * Callback before printing
2340
+ * Return false to cancel printing
998
2341
  */
999
- distance?: number;
2342
+ onBeforePrint?: PrintBeforeCallback;
1000
2343
  /**
1001
- * Callback when long press starts (on mousedown/touchstart)
2344
+ * Callback after printing
1002
2345
  */
1003
- onStart?: (event: MouseEvent | TouchEvent) => void;
2346
+ onAfterPrint?: PrintCompleteCallback;
1004
2347
  /**
1005
- * Callback when long press is canceled
2348
+ * Whether to print in a new window
2349
+ * @default false
1006
2350
  */
1007
- onCancel?: (event: MouseEvent | TouchEvent) => void;
2351
+ newWindow?: boolean | Ref<boolean>;
1008
2352
  /**
1009
- * Callback on each tick during long press
2353
+ * Custom class for print container
1010
2354
  */
1011
- onTick?: (remaining: number) => void;
2355
+ printClass?: string | Ref<string>;
2356
+ }
2357
+
2358
+ /**
2359
+ * Return type for usePrint composable
2360
+ */
2361
+ export declare interface UsePrintReturn {
1012
2362
  /**
1013
- * Interval for onTick callback in milliseconds
1014
- * @default 100
2363
+ * Whether printing is in progress
1015
2364
  */
1016
- tickInterval?: number;
2365
+ isPrinting: Ref<boolean>;
1017
2366
  /**
1018
- * Whether to prevent default behavior
1019
- * @default true
2367
+ * Print the specified element or selector
1020
2368
  */
1021
- prevent?: boolean;
2369
+ print: (target?: string | HTMLElement) => Promise<void>;
1022
2370
  /**
1023
- * Whether to stop propagation
1024
- * @default false
2371
+ * Print the current page
1025
2372
  */
1026
- stop?: boolean;
2373
+ printPage: () => Promise<void>;
1027
2374
  }
1028
2375
 
1029
2376
  /**
1030
- * Directive binding value type
2377
+ * Composable for pull to refresh functionality
2378
+ *
2379
+ * @param options - Configuration options
2380
+ * @returns Pull refresh utilities and state
2381
+ *
2382
+ * @example
2383
+ * ```vue
2384
+ * <script setup>
2385
+ * import { usePullRefresh } from 'directix'
2386
+ *
2387
+ * const { state, distance, events, containerRef } = usePullRefresh({
2388
+ * handler: async () => {
2389
+ * await fetchData()
2390
+ * },
2391
+ * distance: 80
2392
+ * })
2393
+ * </script>
2394
+ *
2395
+ * <template>
2396
+ * <div
2397
+ * ref="containerRef"
2398
+ * @touchstart="events.touchstart"
2399
+ * @touchmove="events.touchmove"
2400
+ * @touchend="events.touchend"
2401
+ * >
2402
+ * <div class="indicator" :style="{ transform: `translateY(${distance}px)` }">
2403
+ * {{ state }}
2404
+ * </div>
2405
+ * <slot></slot>
2406
+ * </div>
2407
+ * </template>
2408
+ * ```
1031
2409
  */
1032
- export declare type LowercaseBinding = boolean | LowercaseOptions;
2410
+ export declare function usePullRefresh(options: UsePullRefreshOptions): UsePullRefreshReturn;
1033
2411
 
1034
2412
  /**
1035
- * Lowercase directive options
2413
+ * Options for usePullRefresh composable
1036
2414
  */
1037
- export declare interface LowercaseOptions {
2415
+ export declare interface UsePullRefreshOptions {
1038
2416
  /**
1039
- * Transform only the first character
1040
- * @default false
2417
+ * Refresh handler
2418
+ * @required
1041
2419
  */
1042
- first?: boolean;
2420
+ handler: PullRefreshHandler;
1043
2421
  /**
1044
- * Transform on input event (for input elements)
1045
- * @default true
2422
+ * Distance threshold to trigger refresh
2423
+ * @default 60
1046
2424
  */
1047
- onInput?: boolean;
1048
- }
1049
-
1050
- export declare type MaskBinding = string | MaskOptions;
1051
-
1052
- /**
1053
- * Mask directive options
1054
- */
1055
- export declare interface MaskOptions {
1056
- /** Mask pattern: # digit, A letter, N alphanumeric, X any, others as literals */
1057
- mask: string;
1058
- /** Placeholder character @default '_' */
1059
- placeholder?: string;
1060
- /** Show mask placeholder on focus @default true */
1061
- showPlaceholder?: boolean;
1062
- /** Show mask on blur @default false */
1063
- showMaskOnBlur?: boolean;
1064
- /** Clear incomplete on blur @default false */
1065
- clearIncomplete?: boolean;
1066
- /** Disable @default false */
1067
- disabled?: boolean;
1068
- /** Callback when value changes */
1069
- onChange?: (value: string, rawValue: string) => void;
1070
- /** Callback when mask is complete */
1071
- onComplete?: (value: string) => void;
1072
- }
1073
-
1074
- export declare type ModifierKey = 'ctrl' | 'alt' | 'shift' | 'meta';
1075
-
1076
- export declare type MoneyBinding = string | MoneyOptions;
1077
-
1078
- /**
1079
- * Money directive options
1080
- */
1081
- export declare interface MoneyOptions extends NumberFormatOptions {
1082
- /** Currency symbol @default '$' */
1083
- symbol?: string;
1084
- /** Symbol position @default 'before' */
1085
- symbolPosition?: 'before' | 'after';
1086
- }
1087
-
1088
- /**
1089
- * Directive binding value type
1090
- */
1091
- export declare type MutationBinding = MutationHandler | MutationOptions;
1092
-
1093
- /**
1094
- * Mutation change handler
1095
- */
1096
- export declare type MutationHandler = (mutations: MutationRecord[], observer: MutationObserver) => void;
1097
-
1098
- /**
1099
- * Mutation directive options
1100
- */
1101
- export declare interface MutationOptions {
2425
+ distance?: number | Ref<number>;
1102
2426
  /**
1103
- * Callback when mutations occur
1104
- * @required
2427
+ * Maximum pull distance
2428
+ * @default 100
1105
2429
  */
1106
- handler: MutationHandler;
2430
+ maxDistance?: number | Ref<number>;
1107
2431
  /**
1108
- * Whether to observe attribute changes
2432
+ * Whether to disable pull to refresh
1109
2433
  * @default false
1110
2434
  */
1111
- attributes?: boolean;
2435
+ disabled?: boolean | Ref<boolean>;
1112
2436
  /**
1113
- * Specific attributes to observe
2437
+ * Duration to show success indicator
2438
+ * @default 500
1114
2439
  */
1115
- attributeFilter?: string[];
2440
+ successDuration?: number | Ref<number>;
1116
2441
  /**
1117
- * Whether to observe child node additions/removals
1118
- * @default true
2442
+ * Duration to show error indicator
2443
+ * @default 1000
1119
2444
  */
1120
- childList?: boolean;
2445
+ errorDuration?: number | Ref<number>;
2446
+ }
2447
+
2448
+ /**
2449
+ * Return type for usePullRefresh composable
2450
+ */
2451
+ export declare interface UsePullRefreshReturn {
1121
2452
  /**
1122
- * Whether to observe all descendants, not just direct children
1123
- * @default false
2453
+ * Current pull refresh state
1124
2454
  */
1125
- subtree?: boolean;
2455
+ state: Ref<PullRefreshState>;
1126
2456
  /**
1127
- * Whether to observe character data changes
1128
- * @default false
2457
+ * Current pull distance
1129
2458
  */
1130
- characterData?: boolean;
2459
+ distance: Ref<number>;
1131
2460
  /**
1132
- * Whether to record old attribute values
1133
- * @default false
2461
+ * Whether pull to refresh is currently active
1134
2462
  */
1135
- attributeOldValue?: boolean;
2463
+ isPulling: Ref<boolean>;
1136
2464
  /**
1137
- * Whether to record old character data
1138
- * @default false
2465
+ * Event handlers to bind to the container element
2466
+ */
2467
+ events: {
2468
+ touchstart: (e: TouchEvent) => void;
2469
+ touchmove: (e: TouchEvent) => void;
2470
+ touchend: () => void;
2471
+ };
2472
+ /**
2473
+ * Container ref to bind to the scroll container
1139
2474
  */
1140
- characterDataOldValue?: boolean;
2475
+ containerRef: Ref<HTMLElement | null>;
1141
2476
  /**
1142
- * Whether to disable
1143
- * @default false
2477
+ * Manually trigger refresh
1144
2478
  */
1145
- disabled?: boolean;
2479
+ refresh: () => Promise<void>;
1146
2480
  }
1147
2481
 
1148
- export declare type NumberBinding = number | NumberOptions;
1149
-
1150
- /**
1151
- * Shared utilities for number and money formatting directives
1152
- */
1153
2482
  /**
1154
- * Base options shared by number and money formatting
2483
+ * Composable for tracking element resize
2484
+ *
2485
+ * @param options - Configuration options
2486
+ * @returns Resize utilities
2487
+ *
2488
+ * @example
2489
+ * ```vue
2490
+ * <script setup>
2491
+ * import { ref } from 'vue'
2492
+ * import { useResize } from 'directix'
2493
+ *
2494
+ * const target = ref(null)
2495
+ * const { width, height, bind } = useResize({
2496
+ * debounce: 100,
2497
+ * onResize: (info) => console.log('Resized:', info.width, info.height)
2498
+ * })
2499
+ *
2500
+ * onMounted(() => bind(target.value))
2501
+ * </script>
2502
+ *
2503
+ * <template>
2504
+ * <div ref="target">
2505
+ * Size: {{ width }} x {{ height }}
2506
+ * </div>
2507
+ * </template>
2508
+ * ```
1155
2509
  */
1156
- declare interface NumberFormatOptions {
1157
- /** Number of decimal places */
1158
- precision?: number;
1159
- /** Thousands separator */
1160
- separator?: string;
1161
- /** Decimal separator */
1162
- decimal?: string;
1163
- /** Whether to allow negative numbers @default true */
1164
- allowNegative?: boolean;
1165
- /** Minimum value */
1166
- min?: number;
1167
- /** Maximum value */
1168
- max?: number;
1169
- }
2510
+ export declare function useResize(options?: UseResizeOptions): UseResizeReturn;
1170
2511
 
1171
2512
  /**
1172
- * Number directive options
2513
+ * Options for useResize composable
1173
2514
  */
1174
- export declare interface NumberOptions extends NumberFormatOptions {
1175
- /** Prefix string (e.g., '$') */
1176
- prefix?: string;
1177
- /** Suffix string (e.g., '%') */
1178
- suffix?: string;
2515
+ export declare interface UseResizeOptions {
2516
+ /**
2517
+ * Debounce time in milliseconds
2518
+ * @default 0 (no debounce)
2519
+ */
2520
+ debounce?: number | Ref<number>;
2521
+ /**
2522
+ * Box model to observe
2523
+ * @default 'content-box'
2524
+ */
2525
+ box?: 'content-box' | 'border-box' | 'device-pixel-content-box';
2526
+ /**
2527
+ * Callback when resize occurs
2528
+ */
2529
+ onResize?: (info: ResizeInfo) => void;
1179
2530
  }
1180
2531
 
1181
2532
  /**
1182
- * Parse time argument
1183
- * Supports formats: "300" | "300ms" | "1s"
1184
- */
1185
- export declare function parseTime(arg?: string): number | null;
1186
-
1187
- /**
1188
- * Permission action mode
1189
- */
1190
- export declare type PermissionAction = 'remove' | 'disable' | 'hide';
1191
-
1192
- /**
1193
- * Directive binding value type
1194
- */
1195
- export declare type PermissionBinding = string | string[] | PermissionOptions;
1196
-
1197
- /**
1198
- * Permission configuration
2533
+ * Return type for useResize composable
1199
2534
  */
1200
- export declare interface PermissionConfig {
1201
- /** Get current user's permissions */
1202
- getPermissions: () => string[];
1203
- /** Get current user's roles */
1204
- getRoles?: () => string[];
1205
- /** Role to permission mapping */
1206
- roleMap?: Record<string, string[]>;
2535
+ export declare interface UseResizeReturn {
2536
+ /** Current width */
2537
+ width: Readonly<Ref<number>>;
2538
+ /** Current height */
2539
+ height: Readonly<Ref<number>>;
2540
+ /** Bind resize observer to an element */
2541
+ bind: (element: HTMLElement) => () => void;
2542
+ /** Stop observing */
2543
+ stop: () => void;
1207
2544
  }
1208
2545
 
1209
2546
  /**
1210
- * Permission check mode
2547
+ * Composable for tracking scroll position
2548
+ *
2549
+ * @param options - Configuration options
2550
+ * @returns Scroll utilities
2551
+ *
2552
+ * @example
2553
+ * ```vue
2554
+ * <script setup>
2555
+ * import { ref } from 'vue'
2556
+ * import { useScroll } from 'directix'
2557
+ *
2558
+ * const container = ref(null)
2559
+ * const { scrollTop, progressY, directionY, bind } = useScroll()
2560
+ *
2561
+ * onMounted(() => bind(container.value))
2562
+ * </script>
2563
+ *
2564
+ * <template>
2565
+ * <div ref="container" class="scroll-container">
2566
+ * <div class="progress" :style="{ width: `${progressY * 100}%` }" />
2567
+ * </div>
2568
+ * </template>
2569
+ * ```
1211
2570
  */
1212
- declare type PermissionMode = 'some' | 'every';
2571
+ export declare function useScroll(options?: UseScrollOptions): UseScrollReturn;
1213
2572
 
1214
2573
  /**
1215
- * Permission directive options
2574
+ * Options for useScroll composable
1216
2575
  */
1217
- export declare interface PermissionOptions {
1218
- /** Permission value(s) to check */
1219
- value: string | string[];
1220
- /** Logic for multiple permissions: 'some' (OR) or 'every' (AND). Default: 'some' */
1221
- mode?: PermissionMode;
1222
- /** Action when permission denied. Default: 'remove' */
1223
- action?: PermissionAction;
1224
- /** Custom permission check function */
1225
- check?: (permission: string | string[], mode: PermissionMode) => boolean;
1226
- /** Callback when permission state changes */
1227
- onChange?: (hasPermission: boolean) => void;
2576
+ export declare interface UseScrollOptions {
2577
+ /**
2578
+ * Throttle time in milliseconds
2579
+ * @default 0 (no throttle)
2580
+ */
2581
+ throttle?: number | Ref<number>;
2582
+ /**
2583
+ * Whether to use passive event listener
2584
+ * @default true
2585
+ */
2586
+ passive?: boolean;
1228
2587
  }
1229
2588
 
1230
2589
  /**
1231
- * Print before callback
1232
- */
1233
- export declare type PrintBeforeCallback = () => boolean | void;
1234
-
1235
- /**
1236
- * Directive binding value type
2590
+ * Return type for useScroll composable
1237
2591
  */
1238
- export declare type PrintBinding = PrintOptions | boolean;
2592
+ export declare interface UseScrollReturn {
2593
+ /** Current scroll left position */
2594
+ scrollLeft: Readonly<Ref<number>>;
2595
+ /** Current scroll top position */
2596
+ scrollTop: Readonly<Ref<number>>;
2597
+ /** Horizontal scroll progress (0-1) */
2598
+ progressX: Readonly<Ref<number>>;
2599
+ /** Vertical scroll progress (0-1) */
2600
+ progressY: Readonly<Ref<number>>;
2601
+ /** Direction of horizontal scroll */
2602
+ directionX: Readonly<Ref<ScrollDirection>>;
2603
+ /** Direction of vertical scroll */
2604
+ directionY: Readonly<Ref<ScrollDirection>>;
2605
+ /** Whether the user is scrolling */
2606
+ isScrolling: Readonly<Ref<boolean>>;
2607
+ /** Scroll info object (reactive) */
2608
+ info: Readonly<Ref<ScrollInfo>>;
2609
+ /** Bind scroll listener to an element */
2610
+ bind: (element?: HTMLElement | Window) => () => void;
2611
+ /** Stop listening */
2612
+ stop: () => void;
2613
+ /** Scroll to a position */
2614
+ scrollTo: (options: {
2615
+ top?: number;
2616
+ left?: number;
2617
+ behavior?: 'auto' | 'smooth';
2618
+ }) => void;
2619
+ }
1239
2620
 
1240
2621
  /**
1241
- * Print complete callback
2622
+ * Composable for detecting swipe gestures
2623
+ *
2624
+ * @param options - Configuration options
2625
+ * @returns Swipe utilities
2626
+ *
2627
+ * @example
2628
+ * ```vue
2629
+ * <script setup>
2630
+ * import { ref } from 'vue'
2631
+ * import { useSwipe } from 'directix'
2632
+ *
2633
+ * const container = ref(null)
2634
+ * const { direction, bind } = useSwipe({
2635
+ * onLeft: () => nextSlide(),
2636
+ * onRight: () => prevSlide()
2637
+ * })
2638
+ *
2639
+ * onMounted(() => bind(container.value))
2640
+ * </script>
2641
+ *
2642
+ * <template>
2643
+ * <div ref="container">
2644
+ * Swipe me!
2645
+ * </div>
2646
+ * </template>
2647
+ * ```
1242
2648
  */
1243
- export declare type PrintCompleteCallback = () => void;
2649
+ export declare function useSwipe(options?: UseSwipeOptions): UseSwipeReturn;
1244
2650
 
1245
2651
  /**
1246
- * Print directive options
2652
+ * Options for useSwipe composable
1247
2653
  */
1248
- export declare interface PrintOptions {
2654
+ export declare interface UseSwipeOptions {
1249
2655
  /**
1250
- * Title for the printed document
2656
+ * Swipe handler
2657
+ */
2658
+ handler?: SwipeHandler;
2659
+ /**
2660
+ * Minimum distance to trigger swipe
2661
+ * @default 30
1251
2662
  */
1252
- title?: string;
2663
+ threshold?: number | Ref<number>;
1253
2664
  /**
1254
- * Additional CSS styles to inject
2665
+ * Maximum time for swipe
2666
+ * @default 500
1255
2667
  */
1256
- styles?: string | string[];
2668
+ maxTime?: number | Ref<number>;
1257
2669
  /**
1258
- * Additional CSS URLs to include
2670
+ * Allowed directions
2671
+ * @default ['left', 'right', 'up', 'down']
1259
2672
  */
1260
- cssUrls?: string[];
2673
+ directions?: SwipeDirection[];
1261
2674
  /**
1262
- * Callback before printing
1263
- * Return false to cancel printing
2675
+ * Whether to prevent scroll on swipe
2676
+ * @default true
1264
2677
  */
1265
- onBeforePrint?: PrintBeforeCallback;
2678
+ preventScrollOnSwipe?: boolean;
1266
2679
  /**
1267
- * Callback after printing
2680
+ * Whether to enable mouse events
2681
+ * @default true
1268
2682
  */
1269
- onAfterPrint?: PrintCompleteCallback;
2683
+ mouse?: boolean;
1270
2684
  /**
1271
- * Whether to print immediately on mount
1272
- * @default false
2685
+ * Callback for left swipe
1273
2686
  */
1274
- immediate?: boolean;
2687
+ onLeft?: () => void;
1275
2688
  /**
1276
- * Print target selector
1277
- * If not specified, prints the element itself
2689
+ * Callback for right swipe
1278
2690
  */
1279
- target?: string;
2691
+ onRight?: () => void;
1280
2692
  /**
1281
- * Whether to print in a new window
1282
- * @default false
2693
+ * Callback for up swipe
1283
2694
  */
1284
- newWindow?: boolean;
2695
+ onUp?: () => void;
1285
2696
  /**
1286
- * Custom class for print container
2697
+ * Callback for down swipe
1287
2698
  */
1288
- printClass?: string;
1289
- }
1290
-
1291
- export declare type PullRefreshBinding = PullRefreshHandler | PullRefreshOptions;
1292
-
1293
- export declare type PullRefreshHandler = () => Promise<void> | void;
1294
-
1295
- export declare interface PullRefreshOptions {
1296
- handler: PullRefreshHandler;
1297
- distance?: number;
1298
- maxDistance?: number;
1299
- disabled?: boolean;
1300
- indicator?: {
1301
- idle?: string;
1302
- pulling?: string;
1303
- ready?: string;
1304
- loading?: string;
1305
- success?: string;
1306
- error?: string;
1307
- };
1308
- successDuration?: number;
1309
- errorDuration?: number;
1310
- onStateChange?: (state: PullRefreshState) => void;
2699
+ onDown?: () => void;
1311
2700
  }
1312
2701
 
1313
- export declare type PullRefreshState = 'idle' | 'pulling' | 'ready' | 'loading' | 'success' | 'error';
1314
-
1315
- /**
1316
- * Reset Vue version (useful for testing)
1317
- */
1318
- export declare function resetVueVersion(): void;
1319
-
1320
- /**
1321
- * Directive binding value type
1322
- */
1323
- export declare type ResizeBinding = ResizeHandler | ResizeOptions;
1324
-
1325
2702
  /**
1326
- * Resize event handler
2703
+ * Return type for useSwipe composable
1327
2704
  */
1328
- export declare type ResizeHandler = (entry: ResizeObserverEntry) => void;
2705
+ export declare interface UseSwipeReturn {
2706
+ /** Current swipe direction */
2707
+ direction: Readonly<Ref<SwipeDirection | null>>;
2708
+ /** Length of the swipe */
2709
+ lengthX: Readonly<Ref<number>>;
2710
+ /** Length of the swipe */
2711
+ lengthY: Readonly<Ref<number>>;
2712
+ /** Whether a swipe is being performed */
2713
+ isSwiping: Readonly<Ref<boolean>>;
2714
+ /** Bind swipe detection to an element */
2715
+ bind: (element: HTMLElement) => () => void;
2716
+ }
1329
2717
 
1330
2718
  /**
1331
- * Resize information
2719
+ * Composable for throttling function calls
2720
+ *
2721
+ * @param options - Configuration options
2722
+ * @returns Throttled function utilities
2723
+ *
2724
+ * @example
2725
+ * ```vue
2726
+ * <script setup>
2727
+ * import { ref } from 'vue'
2728
+ * import { useThrottle } from 'directix'
2729
+ *
2730
+ * const { run: throttledScroll } = useThrottle({
2731
+ * handler: (event) => {
2732
+ * console.log('Scroll position:', event.target.scrollTop)
2733
+ * },
2734
+ * wait: 100
2735
+ * })
2736
+ *
2737
+ * // Use in template
2738
+ * // <div @scroll="throttledScroll($event)">...</div>
2739
+ * </script>
2740
+ * ```
1332
2741
  */
1333
- export declare interface ResizeInfo {
1334
- /** New width */
1335
- width: number;
1336
- /** New height */
1337
- height: number;
1338
- /** Content rect */
1339
- contentRect: DOMRectReadOnly;
1340
- /** Border box size */
1341
- borderBoxSize: ReadonlyArray<ResizeObserverSize>;
1342
- /** Content box size */
1343
- contentBoxSize: ReadonlyArray<ResizeObserverSize>;
1344
- /** Device pixel content box size */
1345
- devicePixelContentBoxSize: ReadonlyArray<ResizeObserverSize>;
1346
- }
2742
+ export declare function useThrottle<T extends (...args: any[]) => any>(options: UseThrottleOptions<T>): UseThrottleReturn<T>;
1347
2743
 
1348
2744
  /**
1349
- * Resize directive options
2745
+ * Options for useThrottle composable
1350
2746
  */
1351
- export declare interface ResizeOptions {
2747
+ export declare interface UseThrottleOptions<T extends (...args: any[]) => any> {
1352
2748
  /**
1353
- * Resize event handler
1354
- * @required
2749
+ * Function to throttle
1355
2750
  */
1356
- handler: ResizeHandler;
2751
+ handler: T;
1357
2752
  /**
1358
- * Whether to disable
1359
- * @default false
2753
+ * Delay time in milliseconds
2754
+ * @default 300
1360
2755
  */
1361
- disabled?: boolean;
2756
+ wait?: number | Ref<number>;
1362
2757
  /**
1363
- * Whether to use box model
1364
- * - 'content-box': size of content area
1365
- * - 'border-box': size of border box
1366
- * - 'device-pixel-content-box': size in device pixels
1367
- * @default 'content-box'
2758
+ * Whether to invoke immediately before delay starts
2759
+ * @default true
1368
2760
  */
1369
- box?: 'content-box' | 'border-box' | 'device-pixel-content-box';
2761
+ leading?: boolean | Ref<boolean>;
1370
2762
  /**
1371
- * Debounce time in milliseconds
1372
- * @default 0 (no debounce)
2763
+ * Whether to invoke after delay ends
2764
+ * @default true
2765
+ */
2766
+ trailing?: boolean | Ref<boolean>;
2767
+ }
2768
+
2769
+ /**
2770
+ * Return type for useThrottle composable
2771
+ */
2772
+ export declare interface UseThrottleReturn<T extends (...args: any[]) => any> {
2773
+ /**
2774
+ * Throttled function
1373
2775
  */
1374
- debounce?: number;
2776
+ run: (...args: Parameters<T>) => void;
1375
2777
  /**
1376
- * Callback for browsers without ResizeObserver (uses object fallback)
2778
+ * Cancel any pending execution
1377
2779
  */
1378
- onFallback?: (info: ResizeInfo) => void;
2780
+ cancel: () => void;
1379
2781
  }
1380
2782
 
1381
2783
  /**
1382
- * Directive binding value type
2784
+ * Composable for touch gesture detection
2785
+ *
2786
+ * @param options - Configuration options
2787
+ * @returns Touch gesture utilities
2788
+ *
2789
+ * @example
2790
+ * ```vue
2791
+ * <script setup>
2792
+ * import { ref } from 'vue'
2793
+ * import { useTouch } from 'directix'
2794
+ *
2795
+ * const containerRef = ref(null)
2796
+ * const { gesture, bind } = useTouch({
2797
+ * onSwipeLeft: () => nextSlide(),
2798
+ * onSwipeRight: () => prevSlide()
2799
+ * })
2800
+ *
2801
+ * onMounted(() => bind(containerRef.value))
2802
+ * </script>
2803
+ *
2804
+ * <template>
2805
+ * <div ref="containerRef">
2806
+ * Swipe me!
2807
+ * </div>
2808
+ * </template>
2809
+ * ```
1383
2810
  */
1384
- export declare type RippleBinding = boolean | string | RippleOptions;
2811
+ export declare function useTouch(options?: UseTouchOptions): UseTouchReturn;
1385
2812
 
1386
2813
  /**
1387
- * Ripple directive options
2814
+ * Options for useTouch composable
1388
2815
  */
1389
- export declare interface RippleOptions {
2816
+ export declare interface UseTouchOptions {
1390
2817
  /**
1391
- * Ripple color
1392
- * @default 'currentColor'
2818
+ * Callback for swipe gesture
1393
2819
  */
1394
- color?: string;
2820
+ onSwipe?: (event: TouchGestureEvent) => void;
1395
2821
  /**
1396
- * Ripple duration in milliseconds
1397
- * @default 600
2822
+ * Callback for swipe left
1398
2823
  */
1399
- duration?: number;
2824
+ onSwipeLeft?: (event: TouchGestureEvent) => void;
1400
2825
  /**
1401
- * Whether to disable ripple
1402
- * @default false
2826
+ * Callback for swipe right
1403
2827
  */
1404
- disabled?: boolean;
2828
+ onSwipeRight?: (event: TouchGestureEvent) => void;
1405
2829
  /**
1406
- * Initial scale of ripple
1407
- * @default 0
2830
+ * Callback for swipe up
1408
2831
  */
1409
- initialScale?: number;
2832
+ onSwipeUp?: (event: TouchGestureEvent) => void;
1410
2833
  /**
1411
- * Final scale of ripple
1412
- * @default 2
2834
+ * Callback for swipe down
1413
2835
  */
1414
- finalScale?: number;
1415
- }
1416
-
1417
- /**
1418
- * Directive binding value type
1419
- */
1420
- export declare type SanitizeBinding = boolean | SanitizeOptions;
1421
-
1422
- /**
1423
- * Sanitize handler
1424
- */
1425
- export declare type SanitizeHandler = (value: string) => string;
1426
-
1427
- /**
1428
- * Sanitize directive options
1429
- */
1430
- export declare interface SanitizeOptions {
2836
+ onSwipeDown?: (event: TouchGestureEvent) => void;
1431
2837
  /**
1432
- * Tags to allow (whitelist)
1433
- * @default []
2838
+ * Callback for pinch gesture
1434
2839
  */
1435
- allowedTags?: string[];
2840
+ onPinch?: (event: TouchGestureEvent) => void;
1436
2841
  /**
1437
- * Attributes to allow (whitelist)
1438
- * @default []
2842
+ * Callback for rotate gesture
1439
2843
  */
1440
- allowedAttributes?: string[];
2844
+ onRotate?: (event: TouchGestureEvent) => void;
1441
2845
  /**
1442
- * Whether to allow data URLs
1443
- * @default false
2846
+ * Callback for tap gesture
1444
2847
  */
1445
- allowDataUrls?: boolean;
2848
+ onTap?: (event: TouchGestureEvent) => void;
1446
2849
  /**
1447
- * Whether to allow inline styles
1448
- * @default false
2850
+ * Callback for long press gesture
1449
2851
  */
1450
- allowStyles?: boolean;
2852
+ onLongPress?: (event: TouchGestureEvent) => void;
1451
2853
  /**
1452
- * Whether to allow class attribute
1453
- * @default false
2854
+ * Swipe threshold distance in pixels
2855
+ * @default 30
1454
2856
  */
1455
- allowClass?: boolean;
2857
+ swipeThreshold?: number;
1456
2858
  /**
1457
- * Whether to allow id attribute
1458
- * @default false
2859
+ * Long press duration in milliseconds
2860
+ * @default 500
1459
2861
  */
1460
- allowId?: boolean;
2862
+ longPressDuration?: number;
1461
2863
  /**
1462
- * Custom sanitize function
2864
+ * Tap max duration in milliseconds
2865
+ * @default 250
1463
2866
  */
1464
- handler?: SanitizeHandler;
2867
+ tapDuration?: number;
1465
2868
  /**
1466
2869
  * Whether to disable
1467
2870
  * @default false
1468
2871
  */
1469
- disabled?: boolean;
1470
- /**
1471
- * Whether to sanitize on update
1472
- * @default true
1473
- */
1474
- sanitizeOnUpdate?: boolean;
2872
+ disabled?: boolean | Ref<boolean>;
1475
2873
  }
1476
2874
 
1477
2875
  /**
1478
- * Directive binding value type
1479
- */
1480
- export declare type ScrollBinding = ScrollHandler | ScrollOptions_2;
1481
-
1482
- /**
1483
- * Scroll event handler
2876
+ * Return type for useTouch composable
1484
2877
  */
1485
- export declare type ScrollHandler = (event: Event, info: ScrollInfo) => void;
2878
+ export declare interface UseTouchReturn {
2879
+ /** Current gesture being performed */
2880
+ gesture: Readonly<Ref<TouchGesture | null>>;
2881
+ /** Bind touch events to an element */
2882
+ bind: (element: HTMLElement) => () => void;
2883
+ }
1486
2884
 
1487
2885
  /**
1488
- * Scroll information
2886
+ * Composable for trimming text
2887
+ *
2888
+ * @param options - Configuration options
2889
+ * @returns Trimmed text utilities
2890
+ *
2891
+ * @example
2892
+ * ```vue
2893
+ * <script setup>
2894
+ * import { ref } from 'vue'
2895
+ * import { useTrim } from 'directix'
2896
+ *
2897
+ * const text = ref(' hello world ')
2898
+ *
2899
+ * const { trimmed, wasTrimmed } = useTrim({ text })
2900
+ * // trimmed.value = 'hello world'
2901
+ * // wasTrimmed.value = true
2902
+ * </script>
2903
+ *
2904
+ * <template>
2905
+ * <p>{{ trimmed }}</p>
2906
+ * </template>
2907
+ * ```
1489
2908
  */
1490
- export declare interface ScrollInfo {
1491
- /** Current scroll left position */
1492
- scrollLeft: number;
1493
- /** Current scroll top position */
1494
- scrollTop: number;
1495
- /** Maximum scroll left */
1496
- scrollLeftMax: number;
1497
- /** Maximum scroll top */
1498
- scrollTopMax: number;
1499
- /** Horizontal scroll progress (0-1) */
1500
- progressX: number;
1501
- /** Vertical scroll progress (0-1) */
1502
- progressY: number;
1503
- /** Direction of horizontal scroll (-1: left, 1: right, 0: none) */
1504
- directionX: -1 | 0 | 1;
1505
- /** Direction of vertical scroll (-1: up, 1: down, 0: none) */
1506
- directionY: -1 | 0 | 1;
1507
- /** Scroll container element or window */
1508
- container: Element | Window;
1509
- }
2909
+ export declare function useTrim(options: UseTrimOptions): UseTrimReturn;
1510
2910
 
1511
2911
  /**
1512
- * Scroll directive options
2912
+ * Options for useTrim composable
1513
2913
  */
1514
- declare interface ScrollOptions_2 {
2914
+ export declare interface UseTrimOptions {
1515
2915
  /**
1516
- * Scroll event handler
1517
- * @required
1518
- */
1519
- handler: ScrollHandler;
1520
- /**
1521
- * Whether to disable
1522
- * @default false
1523
- */
1524
- disabled?: boolean;
1525
- /**
1526
- * Whether to use passive event listener
1527
- * @default true
2916
+ * The text to trim
1528
2917
  */
1529
- passive?: boolean;
2918
+ text: string | Ref<string>;
1530
2919
  /**
1531
- * Throttle time in milliseconds
1532
- * @default 0 (no throttle)
2920
+ * Trim position
2921
+ * @default 'both'
1533
2922
  */
1534
- throttle?: number;
2923
+ position?: TrimPosition | Ref<TrimPosition>;
1535
2924
  /**
1536
- * Custom scroll container selector or element
2925
+ * Custom characters to trim (in addition to whitespace)
1537
2926
  */
1538
- container?: string | Element | Window | null;
2927
+ chars?: string | Ref<string>;
1539
2928
  }
1540
- export { ScrollOptions_2 as ScrollOptions }
1541
-
1542
- /**
1543
- * Set nested property value by path
1544
- */
1545
- export declare function set(obj: Record<string, any>, path: string, value: any): void;
1546
-
1547
- /**
1548
- * Set Vue version explicitly (for cases where auto-detection fails)
1549
- */
1550
- export declare function setVueVersion(version: VueVersion): void;
1551
-
1552
- export declare type StickyBinding = boolean | number | StickyOptions;
1553
2929
 
1554
2930
  /**
1555
- * Sticky directive options
2931
+ * Return type for useTrim composable
1556
2932
  */
1557
- export declare interface StickyOptions {
1558
- /** Top offset when sticky @default 0 */
1559
- top?: number | string;
1560
- /** Bottom offset when sticky */
1561
- bottom?: number | string;
1562
- /** Z-index when sticky @default 100 */
1563
- zIndex?: number;
1564
- /** CSS class to add when sticky @default 'v-sticky--fixed' */
1565
- stickyClass?: string;
1566
- /** Whether to disable @default false */
1567
- disabled?: boolean;
1568
- /** Callback when sticky state changes */
1569
- onChange?: (isSticky: boolean) => void;
1570
- /** Custom scroll container */
1571
- container?: string | Element | null;
2933
+ export declare interface UseTrimReturn {
2934
+ /**
2935
+ * The trimmed text
2936
+ */
2937
+ trimmed: Ref<string>;
2938
+ /**
2939
+ * Original text
2940
+ */
2941
+ original: Ref<string>;
2942
+ /**
2943
+ * Whether the text was trimmed
2944
+ */
2945
+ wasTrimmed: Ref<boolean>;
1572
2946
  }
1573
2947
 
1574
2948
  /**
1575
- * Check if Clipboard API is supported
1576
- */
1577
- export declare const supportsClipboard: () => boolean;
1578
-
1579
- /**
1580
- * Check if IntersectionObserver is supported
1581
- */
1582
- export declare const supportsIntersectionObserver: () => boolean;
1583
-
1584
- /**
1585
- * Check if MutationObserver is supported
1586
- */
1587
- export declare const supportsMutationObserver: () => boolean;
1588
-
1589
- /**
1590
- * Check if passive event listening is supported
1591
- */
1592
- export declare const supportsPassive: () => boolean;
1593
-
1594
- /**
1595
- * Check if ResizeObserver is supported
2949
+ * Composable for transforming text to uppercase
2950
+ *
2951
+ * @param options - Configuration options
2952
+ * @returns Uppercase text utilities
2953
+ *
2954
+ * @example
2955
+ * ```vue
2956
+ * <script setup>
2957
+ * import { ref } from 'vue'
2958
+ * import { useUppercase } from 'directix'
2959
+ *
2960
+ * const text = ref('hello world')
2961
+ *
2962
+ * const { transformed } = useUppercase({ text })
2963
+ * // transformed.value = 'HELLO WORLD'
2964
+ * </script>
2965
+ *
2966
+ * <template>
2967
+ * <p>{{ transformed }}</p>
2968
+ * </template>
2969
+ * ```
1596
2970
  */
1597
- export declare const supportsResizeObserver: () => boolean;
1598
-
1599
- export declare type SwipeBinding = SwipeHandler | SwipeOptions;
1600
-
1601
- export declare type SwipeDirection = 'left' | 'right' | 'up' | 'down';
2971
+ export declare function useUppercase(options: UseUppercaseOptions): UseUppercaseReturn;
1602
2972
 
1603
2973
  /**
1604
- * Swipe direction
2974
+ * Options for useUppercase composable
1605
2975
  */
1606
- declare type SwipeDirection_2 = 'left' | 'right' | 'up' | 'down';
1607
-
1608
- export declare type SwipeHandler = (direction: SwipeDirection, event: Event) => void;
1609
-
1610
- export declare interface SwipeOptions {
1611
- handler?: SwipeHandler;
1612
- threshold?: number;
1613
- maxTime?: number;
1614
- directions?: SwipeDirection[];
1615
- preventScrollOnSwipe?: boolean;
1616
- disabled?: boolean;
1617
- mouse?: boolean;
1618
- onLeft?: () => void;
1619
- onRight?: () => void;
1620
- onUp?: () => void;
1621
- onDown?: () => void;
2976
+ export declare interface UseUppercaseOptions {
2977
+ /**
2978
+ * The text to transform
2979
+ */
2980
+ text: string | Ref<string>;
2981
+ /**
2982
+ * Transform only the first character
2983
+ * @default false
2984
+ */
2985
+ first?: boolean | Ref<boolean>;
1622
2986
  }
1623
2987
 
1624
2988
  /**
1625
- * Directive binding value type
1626
- */
1627
- export declare type ThrottleBinding<T extends (...args: any[]) => any = any> = T | ThrottleOptions<T>;
1628
-
1629
- /**
1630
- * Throttled function type
2989
+ * Return type for useUppercase composable
1631
2990
  */
1632
- export declare interface ThrottledFunction<T extends (...args: any[]) => any> {
1633
- (...args: Parameters<T>): void;
1634
- cancel: () => void;
2991
+ export declare interface UseUppercaseReturn {
2992
+ /**
2993
+ * The transformed text
2994
+ */
2995
+ transformed: Ref<string>;
2996
+ /**
2997
+ * Original text
2998
+ */
2999
+ original: Ref<string>;
1635
3000
  }
1636
3001
 
1637
3002
  /**
1638
- * Throttle function
1639
- */
1640
- export declare function throttleFn<T extends (...args: any[]) => any>(func: T, wait?: number, options?: {
1641
- leading?: boolean;
1642
- trailing?: boolean;
1643
- }): ((...args: Parameters<T>) => void) & {
1644
- cancel: () => void;
1645
- };
3003
+ * Composable for virtual list rendering
3004
+ *
3005
+ * @param options - Configuration options
3006
+ * @returns Virtual list utilities and state
3007
+ *
3008
+ * @example
3009
+ * ```vue
3010
+ * <script setup>
3011
+ * import { ref } from 'vue'
3012
+ * import { useVirtualList } from 'directix'
3013
+ *
3014
+ * const items = ref(Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })))
3015
+ *
3016
+ * const {
3017
+ * visibleItems,
3018
+ * totalHeight,
3019
+ * containerRef,
3020
+ * listStyle,
3021
+ * scrollToIndex
3022
+ * } = useVirtualList({
3023
+ * items,
3024
+ * itemSize: 50,
3025
+ * height: 600
3026
+ * })
3027
+ * </script>
3028
+ *
3029
+ * <template>
3030
+ * <div ref="containerRef" :style="listStyle">
3031
+ * <div :style="{ height: totalHeight + 'px', position: 'relative' }">
3032
+ * <div
3033
+ * v-for="{ item, index, style } in visibleItems"
3034
+ * :key="item.id"
3035
+ * :style="style"
3036
+ * >
3037
+ * {{ item.name }}
3038
+ * </div>
3039
+ * </div>
3040
+ * </div>
3041
+ * </template>
3042
+ * ```
3043
+ */
3044
+ export declare function useVirtualList<T = any>(options: UseVirtualListOptions<T>): UseVirtualListReturn<T>;
1646
3045
 
1647
3046
  /**
1648
- * Throttle directive options
3047
+ * Options for useVirtualList composable
1649
3048
  */
1650
- export declare interface ThrottleOptions<T extends (...args: any[]) => any = any> {
3049
+ export declare interface UseVirtualListOptions<T = any> {
1651
3050
  /**
1652
- * Function to throttle
3051
+ * Array of items to render
3052
+ * @required
1653
3053
  */
1654
- handler: T;
3054
+ items: Ref<T[]> | T[];
1655
3055
  /**
1656
- * Delay time in milliseconds
1657
- * @default 300
3056
+ * Height of each item (in pixels)
3057
+ * Can be a fixed number or a function
3058
+ * @default 50
1658
3059
  */
1659
- wait?: number;
3060
+ itemSize?: number | ItemSizeFunction | Ref<number | ItemSizeFunction>;
1660
3061
  /**
1661
- * Whether to invoke immediately before delay starts
1662
- * @default true
3062
+ * Height of the container (in pixels)
3063
+ * @default 400
1663
3064
  */
1664
- leading?: boolean;
3065
+ height?: number | Ref<number>;
1665
3066
  /**
1666
- * Whether to invoke after delay ends
1667
- * @default true
3067
+ * Number of extra items to render above/below visible area
3068
+ * @default 3
1668
3069
  */
1669
- trailing?: boolean;
3070
+ overscan?: number | Ref<number>;
3071
+ /**
3072
+ * Key field name for items
3073
+ * @default 'id'
3074
+ */
3075
+ keyField?: string;
1670
3076
  }
1671
3077
 
1672
- export declare type TooltipBinding = string | TooltipOptions;
1673
-
1674
3078
  /**
1675
- * Tooltip directive options
3079
+ * Return type for useVirtualList composable
1676
3080
  */
1677
- export declare interface TooltipOptions {
1678
- /** Tooltip content */
1679
- content: string;
1680
- /** Tooltip placement @default 'top' */
1681
- placement?: TooltipPlacement;
1682
- /** Trigger type @default 'hover' */
1683
- trigger?: TooltipTrigger;
1684
- /** Show delay in milliseconds @default 0 */
1685
- delay?: number;
1686
- /** Hide delay in milliseconds @default 0 */
1687
- hideDelay?: number;
1688
- /** Offset from the element in pixels @default 8 */
1689
- offset?: number;
1690
- /** Custom class for the tooltip */
1691
- class?: string;
1692
- /** Whether to show arrow @default true */
1693
- arrow?: boolean;
1694
- /** Whether the tooltip is disabled @default false */
1695
- disabled?: boolean;
1696
- /** Maximum width of the tooltip */
1697
- maxWidth?: number | string;
1698
- /** Z-index of the tooltip @default 9999 */
1699
- zIndex?: number;
1700
- /** Callback when tooltip is shown */
1701
- onShow?: () => void;
1702
- /** Callback when tooltip is hidden */
1703
- onHide?: () => void;
3081
+ export declare interface UseVirtualListReturn<T = any> {
3082
+ /**
3083
+ * Currently visible items
3084
+ */
3085
+ visibleItems: Ref<VirtualListItem<T>[]>;
3086
+ /**
3087
+ * Total height of the list
3088
+ */
3089
+ totalHeight: Ref<number>;
3090
+ /**
3091
+ * Current scroll position
3092
+ */
3093
+ scrollTop: Ref<number>;
3094
+ /**
3095
+ * Start index of visible items
3096
+ */
3097
+ startIndex: Ref<number>;
3098
+ /**
3099
+ * End index of visible items
3100
+ */
3101
+ endIndex: Ref<number>;
3102
+ /**
3103
+ * Scroll to a specific index
3104
+ */
3105
+ scrollToIndex: (index: number) => void;
3106
+ /**
3107
+ * Scroll to a specific position
3108
+ */
3109
+ scrollTo: (scrollTop: number) => void;
3110
+ /**
3111
+ * Container ref to bind to the scroll container
3112
+ */
3113
+ containerRef: Ref<HTMLElement | null>;
3114
+ /**
3115
+ * List style for the wrapper element
3116
+ */
3117
+ listStyle: Ref<{
3118
+ height: string;
3119
+ overflow: string;
3120
+ position: string;
3121
+ }>;
1704
3122
  }
1705
3123
 
1706
3124
  /**
1707
- * Tooltip placement
1708
- */
1709
- export declare type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
1710
-
1711
- /**
1712
- * Tooltip trigger
3125
+ * Composable for controlling element visibility
3126
+ *
3127
+ * @param options - Configuration options
3128
+ * @returns Visibility utilities
3129
+ *
3130
+ * @example
3131
+ * ```vue
3132
+ * <script setup>
3133
+ * import { ref } from 'vue'
3134
+ * import { useVisible } from 'directix'
3135
+ *
3136
+ * const modal = ref(null)
3137
+ * const { visible, show, hide, toggle, bind } = useVisible({
3138
+ * initial: false,
3139
+ * onChange: (v) => console.log('Visible:', v)
3140
+ * })
3141
+ *
3142
+ * onMounted(() => bind(modal.value))
3143
+ * </script>
3144
+ *
3145
+ * <template>
3146
+ * <button @click="toggle">Toggle Modal</button>
3147
+ * <div ref="modal" v-show="visible">Modal Content</div>
3148
+ * </template>
3149
+ * ```
1713
3150
  */
1714
- export declare type TooltipTrigger = 'hover' | 'click' | 'focus' | 'manual';
3151
+ export declare function useVisible(options?: UseVisibleOptions): UseVisibleReturn;
1715
3152
 
1716
3153
  /**
1717
- * Touch gesture options
3154
+ * Options for useVisible composable
1718
3155
  */
1719
- export declare interface TouchOptions {
1720
- /** Minimum swipe distance in pixels @default 30 */
1721
- swipeThreshold?: number;
1722
- /** Maximum time for a swipe in milliseconds @default 500 */
1723
- swipeTimeout?: number;
1724
- /** Minimum pinch scale change @default 0.1 */
1725
- pinchThreshold?: number;
1726
- /** Enable swipe detection @default true */
1727
- enableSwipe?: boolean;
1728
- /** Enable pinch detection @default true */
1729
- enablePinch?: boolean;
1730
- /** Enable rotate detection @default true */
1731
- enableRotate?: boolean;
1732
- /** Enable tap detection @default true */
1733
- enableTap?: boolean;
1734
- /** Maximum time for a tap in milliseconds @default 250 */
1735
- tapTimeout?: number;
1736
- /** Maximum movement for a tap in pixels @default 10 */
1737
- tapThreshold?: number;
1738
- /** Enable long press detection @default true */
1739
- enableLongPress?: boolean;
1740
- /** Long press timeout in milliseconds @default 500 */
1741
- longPressTimeout?: number;
1742
- /** Enable mouse event simulation for desktop @default true */
1743
- enableMouse?: boolean;
1744
- onSwipe?: (direction: SwipeDirection_2, event: TouchEvent | MouseEvent) => void;
1745
- onSwipeLeft?: (event: TouchEvent | MouseEvent) => void;
1746
- onSwipeRight?: (event: TouchEvent | MouseEvent) => void;
1747
- onSwipeUp?: (event: TouchEvent | MouseEvent) => void;
1748
- onSwipeDown?: (event: TouchEvent | MouseEvent) => void;
1749
- onPinch?: (scale: number, event: TouchEvent) => void;
1750
- onRotate?: (angle: number, event: TouchEvent) => void;
1751
- onTap?: (event: TouchEvent | MouseEvent) => void;
1752
- onLongPress?: (event: TouchEvent | MouseEvent) => void;
1753
- onTouchStart?: (event: TouchEvent | MouseEvent) => void;
1754
- onTouchMove?: (event: TouchEvent | MouseEvent) => void;
1755
- onTouchEnd?: (event: TouchEvent | MouseEvent) => void;
1756
- }
1757
-
1758
- /**
1759
- * Directive binding value type
1760
- */
1761
- export declare type TrimBinding = boolean | TrimPosition | TrimOptions;
1762
-
1763
- /**
1764
- * Trim directive options
1765
- */
1766
- export declare interface TrimOptions {
1767
- /**
1768
- * Trim position
1769
- * @default 'both'
1770
- */
1771
- position?: TrimPosition;
3156
+ export declare interface UseVisibleOptions {
1772
3157
  /**
1773
- * Whether to trim on input (for input elements)
3158
+ * Initial visibility
1774
3159
  * @default true
1775
3160
  */
1776
- onInput?: boolean;
3161
+ initial?: boolean | Ref<boolean>;
1777
3162
  /**
1778
- * Whether to trim on blur
1779
- * @default true
3163
+ * Whether to use visibility: hidden instead of display: none
3164
+ * @default false
1780
3165
  */
1781
- onBlur?: boolean;
3166
+ useHidden?: boolean;
1782
3167
  /**
1783
- * Custom characters to trim (in addition to whitespace)
3168
+ * Callback when visibility changes
1784
3169
  */
1785
- chars?: string;
3170
+ onChange?: (isVisible: boolean) => void;
1786
3171
  }
1787
3172
 
1788
3173
  /**
1789
- * Trim position
3174
+ * Return type for useVisible composable
1790
3175
  */
1791
- export declare type TrimPosition = 'start' | 'end' | 'both';
3176
+ export declare interface UseVisibleReturn {
3177
+ /** Current visibility state */
3178
+ visible: Ref<boolean>;
3179
+ /** Show the element */
3180
+ show: () => void;
3181
+ /** Hide the element */
3182
+ hide: () => void;
3183
+ /** Toggle visibility */
3184
+ toggle: () => void;
3185
+ /** Bind visibility control to an element */
3186
+ bind: (element: HTMLElement) => () => void;
3187
+ }
1792
3188
 
1793
3189
  /**
1794
- * Directive binding value type
3190
+ * Composable for creating watermark overlays
3191
+ *
3192
+ * @param options - Configuration options
3193
+ * @returns Watermark utilities and state
3194
+ *
3195
+ * @example
3196
+ * ```vue
3197
+ * <script setup>
3198
+ * import { useWatermark } from 'directix'
3199
+ *
3200
+ * const { dataUrl, style, disable, enable } = useWatermark({
3201
+ * content: 'Confidential',
3202
+ * fontSize: 20,
3203
+ * color: 'rgba(255, 0, 0, 0.2)'
3204
+ * })
3205
+ * </script>
3206
+ *
3207
+ * <template>
3208
+ * <div class="container">
3209
+ * <div :style="style"></div>
3210
+ * <slot></slot>
3211
+ * </div>
3212
+ * </template>
3213
+ * ```
1795
3214
  */
1796
- export declare type TruncateBinding = number | TruncateOptions;
3215
+ export declare function useWatermark(options: UseWatermarkOptions): UseWatermarkReturn;
1797
3216
 
1798
3217
  /**
1799
- * Truncate directive options
3218
+ * Options for useWatermark composable
1800
3219
  */
1801
- export declare interface TruncateOptions {
3220
+ export declare interface UseWatermarkOptions {
1802
3221
  /**
1803
- * Maximum length of text
1804
- * @default 100
3222
+ * Watermark text content
3223
+ * @required
1805
3224
  */
1806
- length?: number;
3225
+ content: string | string[] | Ref<string | string[]>;
1807
3226
  /**
1808
- * Truncation position
1809
- * @default 'end'
3227
+ * Width of watermark canvas
3228
+ * @default 300
1810
3229
  */
1811
- position?: TruncatePosition;
3230
+ width?: number | Ref<number>;
1812
3231
  /**
1813
- * Ellipsis string
1814
- * @default '...'
3232
+ * Height of watermark canvas
3233
+ * @default 200
3234
+ */
3235
+ height?: number | Ref<number>;
3236
+ /**
3237
+ * Rotation angle in degrees
3238
+ * @default -22
3239
+ */
3240
+ rotate?: number | Ref<number>;
3241
+ /**
3242
+ * Font size in pixels
3243
+ * @default 16
3244
+ */
3245
+ fontSize?: number | Ref<number>;
3246
+ /**
3247
+ * Font family
3248
+ * @default 'sans-serif'
3249
+ */
3250
+ fontFamily?: string | Ref<string>;
3251
+ /**
3252
+ * Font weight
3253
+ * @default 'normal'
3254
+ */
3255
+ fontWeight?: string | number | Ref<string | number>;
3256
+ /**
3257
+ * Font color
3258
+ * @default 'rgba(128, 128, 128, 0.15)'
3259
+ */
3260
+ color?: string | Ref<string>;
3261
+ /**
3262
+ * Gap between watermarks in pixels
3263
+ * @default [100, 100]
3264
+ */
3265
+ gap?: [number, number] | number | Ref<[number, number] | number>;
3266
+ /**
3267
+ * Z-index of watermark layer
3268
+ * @default 9999
1815
3269
  */
1816
- ellipsis?: string;
3270
+ zIndex?: number | Ref<number>;
1817
3271
  /**
1818
- * Whether to use CSS truncation (use text-overflow: ellipsis)
1819
- * When true, length and position options are ignored
3272
+ * Whether to disable watermark
1820
3273
  * @default false
1821
3274
  */
1822
- useCss?: boolean;
3275
+ disabled?: boolean | Ref<boolean>;
1823
3276
  /**
1824
- * Show full text on hover (as title attribute)
3277
+ * Whether to prevent removal attempts
1825
3278
  * @default true
1826
3279
  */
1827
- showTitle?: boolean;
3280
+ protect?: boolean | Ref<boolean>;
1828
3281
  }
1829
3282
 
1830
3283
  /**
1831
- * Truncate position
1832
- */
1833
- export declare type TruncatePosition = 'start' | 'middle' | 'end';
1834
-
1835
- /**
1836
- * Directive binding value type
1837
- */
1838
- export declare type UppercaseBinding = boolean | UppercaseOptions;
1839
-
1840
- /**
1841
- * Uppercase directive options
3284
+ * Return type for useWatermark composable
1842
3285
  */
1843
- export declare interface UppercaseOptions {
3286
+ export declare interface UseWatermarkReturn {
1844
3287
  /**
1845
- * Transform only the first character
1846
- * @default false
3288
+ * Watermark canvas element
1847
3289
  */
1848
- first?: boolean;
3290
+ canvas: Ref<HTMLCanvasElement | null>;
1849
3291
  /**
1850
- * Transform on input event (for input elements)
1851
- * @default true
3292
+ * Watermark data URL
3293
+ */
3294
+ dataUrl: Ref<string>;
3295
+ /**
3296
+ * Watermark CSS style object
3297
+ */
3298
+ style: Ref<{
3299
+ position: string;
3300
+ top: string;
3301
+ left: string;
3302
+ width: string;
3303
+ height: string;
3304
+ pointerEvents: string;
3305
+ zIndex: number;
3306
+ backgroundImage: string;
3307
+ backgroundRepeat: string;
3308
+ backgroundPosition: string;
3309
+ backgroundSize: string;
3310
+ display?: string;
3311
+ }>;
3312
+ /**
3313
+ * Whether watermark is disabled
3314
+ */
3315
+ disabled: Ref<boolean>;
3316
+ /**
3317
+ * Update watermark options
3318
+ */
3319
+ update: (options: Partial<UseWatermarkOptions>) => void;
3320
+ /**
3321
+ * Enable watermark
3322
+ */
3323
+ enable: () => void;
3324
+ /**
3325
+ * Disable watermark
1852
3326
  */
1853
- onInput?: boolean;
3327
+ disable: () => void;
1854
3328
  }
1855
3329
 
1856
3330
  /**
@@ -1870,9 +3344,7 @@ export declare interface UppercaseOptions {
1870
3344
  * </template>
1871
3345
  * ```
1872
3346
  */
1873
- declare const vCapitalcase: Directive;
1874
- export { vCapitalcase as capitalcase }
1875
- export { vCapitalcase }
3347
+ export declare const vCapitalcase: Directive;
1876
3348
 
1877
3349
  /**
1878
3350
  * v-click-delay directive
@@ -1895,9 +3367,7 @@ export { vCapitalcase }
1895
3367
  * </template>
1896
3368
  * ```
1897
3369
  */
1898
- declare const vClickDelay: Directive;
1899
- export { vClickDelay as clickDelay }
1900
- export { vClickDelay }
3370
+ export declare const vClickDelay: Directive;
1901
3371
 
1902
3372
  /**
1903
3373
  * v-click-outside directive
@@ -1911,9 +3381,7 @@ export { vClickDelay }
1911
3381
  * </template>
1912
3382
  * ```
1913
3383
  */
1914
- declare const vClickOutside: Directive;
1915
- export { vClickOutside as clickOutside }
1916
- export { vClickOutside }
3384
+ export declare const vClickOutside: Directive;
1917
3385
 
1918
3386
  /**
1919
3387
  * v-copy directive
@@ -1925,9 +3393,7 @@ export { vClickOutside }
1925
3393
  * </template>
1926
3394
  * ```
1927
3395
  */
1928
- declare const vCopy: Directive;
1929
- export { vCopy as copy }
1930
- export { vCopy }
3396
+ export declare const vCopy: Directive;
1931
3397
 
1932
3398
  /**
1933
3399
  * v-countdown directive
@@ -1958,9 +3424,7 @@ export { vCopy }
1958
3424
  * </template>
1959
3425
  * ```
1960
3426
  */
1961
- declare const vCountdown: Directive;
1962
- export { vCountdown as countdown }
1963
- export { vCountdown }
3427
+ export declare const vCountdown: Directive;
1964
3428
 
1965
3429
  /**
1966
3430
  * v-debounce directive
@@ -1976,9 +3440,7 @@ export { vCountdown }
1976
3440
  * </template>
1977
3441
  * ```
1978
3442
  */
1979
- declare const vDebounce: Directive;
1980
- export { vDebounce as debounce }
1981
- export { vDebounce }
3443
+ export declare const vDebounce: Directive;
1982
3444
 
1983
3445
  /**
1984
3446
  * v-draggable directive
@@ -2003,9 +3465,7 @@ export { vDebounce }
2003
3465
  * </template>
2004
3466
  * ```
2005
3467
  */
2006
- declare const vDraggable: Directive;
2007
- export { vDraggable as draggable }
2008
- export { vDraggable }
3468
+ export declare const vDraggable: Directive;
2009
3469
 
2010
3470
  /**
2011
3471
  * v-ellipsis directive
@@ -2028,9 +3488,7 @@ export { vDraggable }
2028
3488
  * </template>
2029
3489
  * ```
2030
3490
  */
2031
- declare const vEllipsis: Directive;
2032
- export { vEllipsis as ellipsis }
2033
- export { vEllipsis }
3491
+ export declare const vEllipsis: Directive;
2034
3492
 
2035
3493
  /**
2036
3494
  * v-focus directive
@@ -2043,13 +3501,9 @@ export { vEllipsis }
2043
3501
  * </template>
2044
3502
  * ```
2045
3503
  */
2046
- declare const vFocus: Directive;
2047
- export { vFocus as focus }
2048
- export { vFocus }
3504
+ export declare const vFocus: Directive;
2049
3505
 
2050
- declare const vHotkey: Directive;
2051
- export { vHotkey as hotkey }
2052
- export { vHotkey }
3506
+ export declare const vHotkey: Directive;
2053
3507
 
2054
3508
  /**
2055
3509
  * v-hover directive
@@ -2062,9 +3516,7 @@ export { vHotkey }
2062
3516
  * </template>
2063
3517
  * ```
2064
3518
  */
2065
- declare const vHover: Directive;
2066
- export { vHover as hover }
2067
- export { vHover }
3519
+ export declare const vHover: Directive;
2068
3520
 
2069
3521
  /**
2070
3522
  * v-image-preview directive
@@ -2083,9 +3535,7 @@ export { vHover }
2083
3535
  * </template>
2084
3536
  * ```
2085
3537
  */
2086
- declare const vImagePreview: Directive;
2087
- export { vImagePreview as imagePreview }
2088
- export { vImagePreview }
3538
+ export declare const vImagePreview: Directive;
2089
3539
 
2090
3540
  /**
2091
3541
  * v-infinite-scroll directive
@@ -2103,9 +3553,7 @@ export { vImagePreview }
2103
3553
  * </template>
2104
3554
  * ```
2105
3555
  */
2106
- declare const vInfiniteScroll: Directive;
2107
- export { vInfiniteScroll as infiniteScroll }
2108
- export { vInfiniteScroll }
3556
+ export declare const vInfiniteScroll: Directive;
2109
3557
 
2110
3558
  /**
2111
3559
  * v-intersect directive
@@ -2117,97 +3565,29 @@ export { vInfiniteScroll }
2117
3565
  * <div v-intersect="{ threshold: 0.5, once: true }">Trigger once at 50%</div>
2118
3566
  * ```
2119
3567
  */
2120
- declare const vIntersect: Directive;
2121
- export { vIntersect as intersect }
2122
- export { vIntersect }
2123
-
2124
- /**
2125
- * Directive binding value type
2126
- */
2127
- export declare type VirtualListBinding<T = any> = VirtualListOptions<T> | T[];
2128
-
2129
- /**
2130
- * Virtual list directive options
2131
- */
2132
- export declare interface VirtualListOptions<T = any> {
2133
- /**
2134
- * Array of items to render
2135
- * @required
2136
- */
2137
- items: T[];
2138
- /**
2139
- * Height of each item (in pixels)
2140
- * Can be a fixed number or a function
2141
- * @default 50
2142
- */
2143
- itemSize?: number | ItemSizeFunction;
2144
- /**
2145
- * Height of the container (in pixels)
2146
- * @default 400
2147
- */
2148
- height?: number | string;
2149
- /**
2150
- * Number of extra items to render above/below visible area
2151
- * @default 3
2152
- */
2153
- overscan?: number;
2154
- /**
2155
- * Custom render function
2156
- */
2157
- render?: VirtualListRenderFunction;
2158
- /**
2159
- * Key field name for items
2160
- * @default 'id'
2161
- */
2162
- keyField?: string;
2163
- /**
2164
- * Callback when scroll position changes
2165
- */
2166
- onScroll?: (scrollTop: number) => void;
2167
- /**
2168
- * Callback when visible range changes
2169
- */
2170
- onVisibleChange?: (startIndex: number, endIndex: number) => void;
2171
- }
2172
-
2173
- /**
2174
- * Virtual list render function
2175
- */
2176
- export declare type VirtualListRenderFunction = (item: any, index: number) => string;
2177
-
2178
- /**
2179
- * Directive binding value type
2180
- */
2181
- export declare type VisibleBinding = boolean | VisibleOptions;
2182
-
2183
- /**
2184
- * Visible change handler
2185
- */
2186
- export declare type VisibleHandler = (isVisible: boolean) => void;
3568
+ export declare const vIntersect: Directive;
2187
3569
 
2188
3570
  /**
2189
- * Visible directive options
3571
+ * Virtual list item info
2190
3572
  */
2191
- export declare interface VisibleOptions {
2192
- /**
2193
- * Callback when visibility changes
2194
- */
2195
- handler?: VisibleHandler;
3573
+ export declare interface VirtualListItem<T = any> {
2196
3574
  /**
2197
- * Whether to disable
2198
- * @default false
3575
+ * The item data
2199
3576
  */
2200
- disabled?: boolean;
3577
+ item: T;
2201
3578
  /**
2202
- * Whether to set visibility: hidden instead of display: none
2203
- * @default false
3579
+ * Index in the original list
2204
3580
  */
2205
- useHidden?: boolean;
3581
+ index: number;
2206
3582
  /**
2207
- * Initial visibility
2208
- * @default true
3583
+ * Computed style for positioning
2209
3584
  */
2210
- initial?: boolean;
3585
+ style: {
3586
+ position: string;
3587
+ top: string;
3588
+ height: string;
3589
+ width: string;
3590
+ };
2211
3591
  }
2212
3592
 
2213
3593
  /**
@@ -2222,9 +3602,7 @@ export declare interface VisibleOptions {
2222
3602
  * </template>
2223
3603
  * ```
2224
3604
  */
2225
- declare const vLazy: Directive;
2226
- export { vLazy as lazy }
2227
- export { vLazy }
3605
+ export declare const vLazy: Directive;
2228
3606
 
2229
3607
  /**
2230
3608
  * v-loading directive
@@ -2238,9 +3616,7 @@ export { vLazy }
2238
3616
  * </template>
2239
3617
  * ```
2240
3618
  */
2241
- declare const vLoading: Directive;
2242
- export { vLoading as loading }
2243
- export { vLoading }
3619
+ export declare const vLoading: Directive;
2244
3620
 
2245
3621
  /**
2246
3622
  * v-long-press directive
@@ -2253,9 +3629,7 @@ export { vLoading }
2253
3629
  * </template>
2254
3630
  * ```
2255
3631
  */
2256
- declare const vLongPress: Directive;
2257
- export { vLongPress as longPress }
2258
- export { vLongPress }
3632
+ export declare const vLongPress: Directive;
2259
3633
 
2260
3634
  /**
2261
3635
  * v-lowercase directive
@@ -2271,9 +3645,7 @@ export { vLongPress }
2271
3645
  * </template>
2272
3646
  * ```
2273
3647
  */
2274
- declare const vLowercase: Directive;
2275
- export { vLowercase as lowercase }
2276
- export { vLowercase }
3648
+ export declare const vLowercase: Directive;
2277
3649
 
2278
3650
  /**
2279
3651
  * v-mask directive
@@ -2285,13 +3657,9 @@ export { vLowercase }
2285
3657
  * <input v-mask="{ mask: '##/##/####' }" placeholder="Date" />
2286
3658
  * ```
2287
3659
  */
2288
- declare const vMask: Directive;
2289
- export { vMask as mask }
2290
- export { vMask }
3660
+ export declare const vMask: Directive;
2291
3661
 
2292
- declare const vMoney: Directive;
2293
- export { vMoney as money }
2294
- export { vMoney }
3662
+ export declare const vMoney: Directive;
2295
3663
 
2296
3664
  /**
2297
3665
  * v-mutation directive
@@ -2315,13 +3683,9 @@ export { vMoney }
2315
3683
  * </script>
2316
3684
  * ```
2317
3685
  */
2318
- declare const vMutation: Directive;
2319
- export { vMutation as mutation }
2320
- export { vMutation }
3686
+ export declare const vMutation: Directive;
2321
3687
 
2322
- declare const vNumber: Directive;
2323
- export { vNumber as number }
2324
- export { vNumber }
3688
+ export declare const vNumber: Directive;
2325
3689
 
2326
3690
  /**
2327
3691
  * v-permission directive
@@ -2349,9 +3713,7 @@ export { vNumber }
2349
3713
  * </script>
2350
3714
  * ```
2351
3715
  */
2352
- declare const vPermission: Directive;
2353
- export { vPermission as permission }
2354
- export { vPermission }
3716
+ export declare const vPermission: Directive;
2355
3717
 
2356
3718
  /**
2357
3719
  * v-print directive
@@ -2377,13 +3739,9 @@ export { vPermission }
2377
3739
  * </template>
2378
3740
  * ```
2379
3741
  */
2380
- declare const vPrint: Directive;
2381
- export { vPrint as print }
2382
- export { vPrint }
3742
+ export declare const vPrint: Directive;
2383
3743
 
2384
- declare const vPullRefresh: Directive;
2385
- export { vPullRefresh as pullRefresh }
2386
- export { vPullRefresh }
3744
+ export declare const vPullRefresh: Directive;
2387
3745
 
2388
3746
  /**
2389
3747
  * v-resize directive
@@ -2396,9 +3754,7 @@ export { vPullRefresh }
2396
3754
  * </template>
2397
3755
  * ```
2398
3756
  */
2399
- declare const vResize: Directive;
2400
- export { vResize as resize }
2401
- export { vResize }
3757
+ export declare const vResize: Directive;
2402
3758
 
2403
3759
  /**
2404
3760
  * v-ripple directive
@@ -2412,9 +3768,7 @@ export { vResize }
2412
3768
  * </template>
2413
3769
  * ```
2414
3770
  */
2415
- declare const vRipple: Directive;
2416
- export { vRipple as ripple }
2417
- export { vRipple }
3771
+ export declare const vRipple: Directive;
2418
3772
 
2419
3773
  /**
2420
3774
  * v-sanitize directive
@@ -2428,9 +3782,7 @@ export { vRipple }
2428
3782
  * </template>
2429
3783
  * ```
2430
3784
  */
2431
- declare const vSanitize: Directive;
2432
- export { vSanitize as sanitize }
2433
- export { vSanitize }
3785
+ export declare const vSanitize: Directive;
2434
3786
 
2435
3787
  /**
2436
3788
  * v-scroll directive
@@ -2443,9 +3795,7 @@ export { vSanitize }
2443
3795
  * </template>
2444
3796
  * ```
2445
3797
  */
2446
- declare const vScroll: Directive;
2447
- export { vScroll as scroll }
2448
- export { vScroll }
3798
+ export declare const vScroll: Directive;
2449
3799
 
2450
3800
  /**
2451
3801
  * v-sticky directive
@@ -2457,13 +3807,9 @@ export { vScroll }
2457
3807
  * <div v-sticky="{ top: 60, zIndex: 1000 }">Custom sticky</div>
2458
3808
  * ```
2459
3809
  */
2460
- declare const vSticky: Directive;
2461
- export { vSticky as sticky }
2462
- export { vSticky }
3810
+ export declare const vSticky: Directive;
2463
3811
 
2464
- declare const vSwipe: Directive;
2465
- export { vSwipe as swipe }
2466
- export { vSwipe }
3812
+ export declare const vSwipe: Directive;
2467
3813
 
2468
3814
  /**
2469
3815
  * v-throttle directive
@@ -2478,17 +3824,11 @@ export { vSwipe }
2478
3824
  * </template>
2479
3825
  * ```
2480
3826
  */
2481
- declare const vThrottle: Directive;
2482
- export { vThrottle as throttle }
2483
- export { vThrottle }
3827
+ export declare const vThrottle: Directive;
2484
3828
 
2485
- declare const vTooltip: Directive;
2486
- export { vTooltip as tooltip }
2487
- export { vTooltip }
3829
+ export declare const vTooltip: Directive;
2488
3830
 
2489
- declare const vTouch: Directive;
2490
- export { vTouch as touch }
2491
- export { vTouch }
3831
+ export declare const vTouch: Directive;
2492
3832
 
2493
3833
  /**
2494
3834
  * v-trim directive
@@ -2513,9 +3853,7 @@ export { vTouch }
2513
3853
  * </template>
2514
3854
  * ```
2515
3855
  */
2516
- declare const vTrim: Directive;
2517
- export { vTrim as trim }
2518
- export { vTrim }
3856
+ export declare const vTrim: Directive;
2519
3857
 
2520
3858
  /**
2521
3859
  * v-truncate directive
@@ -2534,9 +3872,7 @@ export { vTrim }
2534
3872
  * </template>
2535
3873
  * ```
2536
3874
  */
2537
- declare const vTruncate: Directive;
2538
- export { vTruncate as truncate }
2539
- export { vTruncate }
3875
+ export declare const vTruncate: Directive;
2540
3876
 
2541
3877
  /**
2542
3878
  * Vue 2 directive hooks
@@ -2584,9 +3920,7 @@ export declare type VueVersion = 2 | 2.7 | 3;
2584
3920
  * </template>
2585
3921
  * ```
2586
3922
  */
2587
- declare const vUppercase: Directive;
2588
- export { vUppercase as uppercase }
2589
- export { vUppercase }
3923
+ export declare const vUppercase: Directive;
2590
3924
 
2591
3925
  /**
2592
3926
  * v-virtual-list directive
@@ -2608,9 +3942,7 @@ export { vUppercase }
2608
3942
  * </template>
2609
3943
  * ```
2610
3944
  */
2611
- declare const vVirtualList: Directive;
2612
- export { vVirtualList }
2613
- export { vVirtualList as virtualList }
3945
+ export declare const vVirtualList: Directive;
2614
3946
 
2615
3947
  /**
2616
3948
  * v-visible directive
@@ -2624,9 +3956,7 @@ export { vVirtualList as virtualList }
2624
3956
  * </template>
2625
3957
  * ```
2626
3958
  */
2627
- declare const vVisible: Directive;
2628
- export { vVisible }
2629
- export { vVisible as visible }
3959
+ export declare const vVisible: Directive;
2630
3960
 
2631
3961
  /**
2632
3962
  * v-watermark directive
@@ -2657,79 +3987,16 @@ export { vVisible as visible }
2657
3987
  * </template>
2658
3988
  * ```
2659
3989
  */
2660
- declare const vWatermark: Directive;
2661
- export { vWatermark }
2662
- export { vWatermark as watermark }
2663
-
2664
- /**
2665
- * Directive binding value type
2666
- */
2667
- export declare type WatermarkBinding = string | WatermarkOptions;
3990
+ export declare const vWatermark: Directive;
2668
3991
 
2669
3992
  /**
2670
- * Watermark options
3993
+ * Utility function to check if text would be truncated in a container
3994
+ *
3995
+ * @param text - Text to check
3996
+ * @param containerWidth - Container width in pixels
3997
+ * @param fontSize - Font size in pixels
3998
+ * @returns Whether text would be truncated
2671
3999
  */
2672
- export declare interface WatermarkOptions {
2673
- /**
2674
- * Watermark text content
2675
- * @required
2676
- */
2677
- content: string | string[];
2678
- /**
2679
- * Width of watermark canvas
2680
- * @default 300
2681
- */
2682
- width?: number;
2683
- /**
2684
- * Height of watermark canvas
2685
- * @default 200
2686
- */
2687
- height?: number;
2688
- /**
2689
- * Rotation angle in degrees
2690
- * @default -22
2691
- */
2692
- rotate?: number;
2693
- /**
2694
- * Font size in pixels
2695
- * @default 16
2696
- */
2697
- fontSize?: number;
2698
- /**
2699
- * Font family
2700
- * @default 'sans-serif'
2701
- */
2702
- fontFamily?: string;
2703
- /**
2704
- * Font weight
2705
- * @default 'normal'
2706
- */
2707
- fontWeight?: string | number;
2708
- /**
2709
- * Font color
2710
- * @default 'rgba(128, 128, 128, 0.15)'
2711
- */
2712
- color?: string;
2713
- /**
2714
- * Gap between watermarks in pixels
2715
- * @default [100, 100]
2716
- */
2717
- gap?: [number, number] | number;
2718
- /**
2719
- * Z-index of watermark layer
2720
- * @default 9999
2721
- */
2722
- zIndex?: number;
2723
- /**
2724
- * Whether to disable watermark (for dynamic control)
2725
- * @default false
2726
- */
2727
- disabled?: boolean;
2728
- /**
2729
- * Whether to prevent removal attempts
2730
- * @default true
2731
- */
2732
- protect?: boolean;
2733
- }
4000
+ export declare function wouldTextTruncate(text: string, containerWidth: number, fontSize?: number): boolean;
2734
4001
 
2735
4002
  export { }