directix 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -78,6 +78,11 @@ export declare interface ComposableThrottledFunction<T extends (...args: any[])
78
78
  cancel: () => void;
79
79
  }
80
80
 
81
+ /**
82
+ * Configure permission directive
83
+ */
84
+ export declare function configurePermission(config: PermissionConfig): void;
85
+
81
86
  /**
82
87
  * Countdown complete callback
83
88
  */
@@ -485,6 +490,11 @@ export declare function generateId(prefix?: string): string;
485
490
  */
486
491
  export declare function get<T = any>(obj: Record<string, any>, path: string, defaultValue?: T): T;
487
492
 
493
+ /**
494
+ * Get current configuration
495
+ */
496
+ export declare function getPermissionConfig(): PermissionConfig | null;
497
+
488
498
  /**
489
499
  * Get current Vue version
490
500
  */
@@ -599,11 +609,21 @@ export declare function isVue3(): boolean;
599
609
  */
600
610
  export declare type ItemSizeFunction = (index: number) => number;
601
611
 
612
+ /**
613
+ * Lazy loading state
614
+ */
615
+ export declare type LazyState = 'pending' | 'loading' | 'loaded' | 'error';
616
+
602
617
  /**
603
618
  * Transform text to lowercase
604
619
  */
605
620
  export declare function lowercaseText(text: string, firstOnly?: boolean): string;
606
621
 
622
+ /**
623
+ * Mutation change handler
624
+ */
625
+ export declare type MutationHandler = (mutations: MutationRecord[], observer: MutationObserver) => void;
626
+
607
627
  /**
608
628
  * Parse formatted money string to number
609
629
  */
@@ -632,6 +652,18 @@ export declare function parseTargetTime(target: Date | number | string): number;
632
652
  */
633
653
  export declare function parseTime(arg?: string): number | null;
634
654
 
655
+ /**
656
+ * Permission configuration
657
+ */
658
+ declare interface PermissionConfig {
659
+ /** Get current user's permissions */
660
+ getPermissions: () => string[];
661
+ /** Get current user's roles */
662
+ getRoles?: () => string[];
663
+ /** Role to permission mapping */
664
+ roleMap?: Record<string, string[]>;
665
+ }
666
+
635
667
  /**
636
668
  * Permission check mode
637
669
  */
@@ -800,6 +832,16 @@ export declare function throttleFn<T extends (...args: any[]) => any>(fn: T, wai
800
832
  trailing?: boolean;
801
833
  }): ComposableThrottledFunction<T>;
802
834
 
835
+ /**
836
+ * Tooltip placement
837
+ */
838
+ export declare type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
839
+
840
+ /**
841
+ * Tooltip trigger
842
+ */
843
+ export declare type TooltipTrigger = 'hover' | 'click' | 'focus' | 'manual';
844
+
803
845
  /**
804
846
  * Touch gesture type
805
847
  */
@@ -832,6 +874,11 @@ export declare type TrimPosition = 'start' | 'end' | 'both';
832
874
  */
833
875
  export declare function trimText(text: string, position?: TrimPosition, chars?: string): string;
834
876
 
877
+ /**
878
+ * Truncate position
879
+ */
880
+ export declare type TruncatePosition = 'start' | 'middle' | 'end';
881
+
835
882
  /**
836
883
  * Utility function to truncate text to a specified length
837
884
  *
@@ -1805,6 +1852,91 @@ export declare interface UseImagePreviewReturn {
1805
1852
  bind: (element: HTMLImageElement) => () => void;
1806
1853
  }
1807
1854
 
1855
+ /**
1856
+ * Composable for infinite scrolling
1857
+ *
1858
+ * @param options - Configuration options
1859
+ * @returns Infinite scroll utilities
1860
+ *
1861
+ * @example
1862
+ * ```vue
1863
+ * <script setup>
1864
+ * import { ref } from 'vue'
1865
+ * import { useInfiniteScroll } from 'directix'
1866
+ *
1867
+ * const items = ref([])
1868
+ * const page = ref(1)
1869
+ *
1870
+ * const { bind, loading, finished } = useInfiniteScroll({
1871
+ * onLoad: async () => {
1872
+ * const newItems = await fetchItems(page.value++)
1873
+ * items.value.push(...newItems)
1874
+ * if (newItems.length === 0) finished.value = true
1875
+ * }
1876
+ * })
1877
+ *
1878
+ * onMounted(() => bind(containerRef.value))
1879
+ * </script>
1880
+ *
1881
+ * <template>
1882
+ * <div ref="containerRef" class="scroll-container">
1883
+ * <div v-for="item in items" :key="item.id">{{ item.name }}</div>
1884
+ * <div v-if="loading">Loading...</div>
1885
+ * </div>
1886
+ * </template>
1887
+ * ```
1888
+ */
1889
+ export declare function useInfiniteScroll(options: UseInfiniteScrollOptions): UseInfiniteScrollReturn;
1890
+
1891
+ /**
1892
+ * Options for useInfiniteScroll composable
1893
+ */
1894
+ export declare interface UseInfiniteScrollOptions {
1895
+ /**
1896
+ * Callback to load more items
1897
+ */
1898
+ onLoad: () => void | Promise<void>;
1899
+ /**
1900
+ * Whether loading is in progress
1901
+ */
1902
+ loading?: boolean | Ref<boolean>;
1903
+ /**
1904
+ * Whether all items are loaded
1905
+ */
1906
+ finished?: boolean | Ref<boolean>;
1907
+ /**
1908
+ * Distance from bottom to trigger load (in pixels)
1909
+ * @default 0
1910
+ */
1911
+ distance?: number | Ref<number>;
1912
+ /**
1913
+ * Whether to check immediately on mount
1914
+ * @default true
1915
+ */
1916
+ immediate?: boolean;
1917
+ /**
1918
+ * Whether to disable
1919
+ * @default false
1920
+ */
1921
+ disabled?: boolean | Ref<boolean>;
1922
+ }
1923
+
1924
+ /**
1925
+ * Return type for useInfiniteScroll composable
1926
+ */
1927
+ export declare interface UseInfiniteScrollReturn {
1928
+ /** Whether loading is in progress */
1929
+ loading: Readonly<Ref<boolean>>;
1930
+ /** Whether all items are loaded */
1931
+ finished: Readonly<Ref<boolean>>;
1932
+ /** Manually trigger load */
1933
+ load: () => Promise<void>;
1934
+ /** Bind infinite scroll to an element */
1935
+ bind: (element: HTMLElement) => () => void;
1936
+ /** Stop observing */
1937
+ stop: () => void;
1938
+ }
1939
+
1808
1940
  /**
1809
1941
  * Composable for detecting element intersection with viewport
1810
1942
  *
@@ -1900,6 +2032,186 @@ export declare interface UseIntersectReturn {
1900
2032
  stop: () => void;
1901
2033
  }
1902
2034
 
2035
+ /**
2036
+ * Composable for lazy loading images
2037
+ *
2038
+ * @param options - Configuration options
2039
+ * @returns Lazy loading utilities
2040
+ *
2041
+ * @example
2042
+ * ```vue
2043
+ * <script setup>
2044
+ * import { ref } from 'vue'
2045
+ * import { useLazy } from 'directix'
2046
+ *
2047
+ * const imageRef = ref(null)
2048
+ * const { state, isLoading, bind } = useLazy({
2049
+ * src: 'https://example.com/image.jpg',
2050
+ * placeholder: '/placeholder.jpg'
2051
+ * })
2052
+ *
2053
+ * onMounted(() => bind(imageRef.value))
2054
+ * </script>
2055
+ *
2056
+ * <template>
2057
+ * <img ref="imageRef" />
2058
+ * </template>
2059
+ * ```
2060
+ */
2061
+ export declare function useLazy(options?: UseLazyOptions): UseLazyReturn;
2062
+
2063
+ /**
2064
+ * Options for useLazy composable
2065
+ */
2066
+ export declare interface UseLazyOptions {
2067
+ /**
2068
+ * Image source URL
2069
+ */
2070
+ src?: string | Ref<string>;
2071
+ /**
2072
+ * Placeholder image URL
2073
+ */
2074
+ placeholder?: string;
2075
+ /**
2076
+ * Error image URL (shown when loading fails)
2077
+ */
2078
+ error?: string;
2079
+ /**
2080
+ * Preload distance in pixels
2081
+ * @default 0
2082
+ */
2083
+ preload?: number;
2084
+ /**
2085
+ * Callback when image loads successfully
2086
+ */
2087
+ onLoad?: (el: HTMLElement) => void;
2088
+ /**
2089
+ * Callback when image fails to load
2090
+ */
2091
+ onError?: (el: HTMLElement, error: Error) => void;
2092
+ /**
2093
+ * Number of retry attempts
2094
+ * @default 1
2095
+ */
2096
+ attempt?: number;
2097
+ }
2098
+
2099
+ /**
2100
+ * Return type for useLazy composable
2101
+ */
2102
+ export declare interface UseLazyReturn {
2103
+ /** Current loading state */
2104
+ state: Readonly<Ref<LazyState>>;
2105
+ /** Whether the image is currently loading */
2106
+ isLoading: Readonly<Ref<boolean>>;
2107
+ /** Whether the image has loaded successfully */
2108
+ isLoaded: Readonly<Ref<boolean>>;
2109
+ /** Whether the image failed to load */
2110
+ hasError: Readonly<Ref<boolean>>;
2111
+ /** Bind lazy loading to an element */
2112
+ bind: (element: HTMLElement) => () => void;
2113
+ /** Manually trigger load */
2114
+ load: () => void;
2115
+ /** Reset state */
2116
+ reset: () => void;
2117
+ }
2118
+
2119
+ /**
2120
+ * Composable for managing loading state
2121
+ *
2122
+ * @param options - Configuration options
2123
+ * @returns Loading utilities
2124
+ *
2125
+ * @example
2126
+ * ```vue
2127
+ * <script setup>
2128
+ * import { ref } from 'vue'
2129
+ * import { useLoading } from 'directix'
2130
+ *
2131
+ * const containerRef = ref(null)
2132
+ * const { loading, start, stop, bind } = useLoading({
2133
+ * text: 'Loading...',
2134
+ * lock: true
2135
+ * })
2136
+ *
2137
+ * onMounted(() => bind(containerRef.value))
2138
+ *
2139
+ * async function fetchData() {
2140
+ * start()
2141
+ * await api.getData()
2142
+ * stop()
2143
+ * }
2144
+ * </script>
2145
+ *
2146
+ * <template>
2147
+ * <div ref="containerRef">
2148
+ * <button @click="fetchData">Fetch Data</button>
2149
+ * </div>
2150
+ * </template>
2151
+ * ```
2152
+ */
2153
+ export declare function useLoading(options?: UseLoadingOptions): UseLoadingReturn;
2154
+
2155
+ /**
2156
+ * Options for useLoading composable
2157
+ */
2158
+ export declare interface UseLoadingOptions {
2159
+ /**
2160
+ * Initial loading state
2161
+ * @default false
2162
+ */
2163
+ initial?: boolean | Ref<boolean>;
2164
+ /**
2165
+ * Loading text to display
2166
+ */
2167
+ text?: string | Ref<string>;
2168
+ /**
2169
+ * CSS class for loading overlay
2170
+ * @default 'v-loading'
2171
+ */
2172
+ loadingClass?: string;
2173
+ /**
2174
+ * CSS class for loading spinner
2175
+ * @default 'v-loading__spinner'
2176
+ */
2177
+ spinnerClass?: string;
2178
+ /**
2179
+ * CSS class for loading text
2180
+ * @default 'v-loading__text'
2181
+ */
2182
+ textClass?: string;
2183
+ /**
2184
+ * Custom spinner HTML
2185
+ */
2186
+ spinner?: string;
2187
+ /**
2188
+ * Background color
2189
+ * @default 'rgba(255, 255, 255, 0.9)'
2190
+ */
2191
+ background?: string;
2192
+ /**
2193
+ * Whether to lock scroll while loading
2194
+ * @default false
2195
+ */
2196
+ lock?: boolean;
2197
+ }
2198
+
2199
+ /**
2200
+ * Return type for useLoading composable
2201
+ */
2202
+ export declare interface UseLoadingReturn {
2203
+ /** Current loading state */
2204
+ loading: Ref<boolean>;
2205
+ /** Start loading */
2206
+ start: () => void;
2207
+ /** Stop loading */
2208
+ stop: () => void;
2209
+ /** Toggle loading state */
2210
+ toggle: () => void;
2211
+ /** Bind loading to an element */
2212
+ bind: (element: HTMLElement) => () => void;
2213
+ }
2214
+
1903
2215
  /**
1904
2216
  * Composable for detecting long press gestures
1905
2217
  *
@@ -2051,6 +2363,91 @@ export declare interface UseLowercaseReturn {
2051
2363
  original: Ref<string>;
2052
2364
  }
2053
2365
 
2366
+ /**
2367
+ * Composable for input masking
2368
+ *
2369
+ * @param options - Configuration options
2370
+ * @returns Mask utilities
2371
+ *
2372
+ * @example
2373
+ * ```vue
2374
+ * <script setup>
2375
+ * import { ref } from 'vue'
2376
+ * import { useMask } from 'directix'
2377
+ *
2378
+ * const inputRef = ref(null)
2379
+ * const { bind, getRawValue } = useMask({
2380
+ * mask: '###-##-####',
2381
+ * placeholder: '_'
2382
+ * })
2383
+ *
2384
+ * onMounted(() => bind(inputRef.value))
2385
+ * </script>
2386
+ *
2387
+ * <template>
2388
+ * <input ref="inputRef" type="text" />
2389
+ * </template>
2390
+ * ```
2391
+ */
2392
+ export declare function useMask(options: UseMaskOptions): UseMaskReturn;
2393
+
2394
+ /**
2395
+ * Options for useMask composable
2396
+ */
2397
+ export declare interface UseMaskOptions {
2398
+ /**
2399
+ * Mask pattern: # digit, A letter, N alphanumeric, X any, others as literals
2400
+ */
2401
+ mask: string | Ref<string>;
2402
+ /**
2403
+ * Placeholder character
2404
+ * @default '_'
2405
+ */
2406
+ placeholder?: string;
2407
+ /**
2408
+ * Show mask placeholder on focus
2409
+ * @default true
2410
+ */
2411
+ showPlaceholder?: boolean;
2412
+ /**
2413
+ * Show mask on blur
2414
+ * @default false
2415
+ */
2416
+ showMaskOnBlur?: boolean;
2417
+ /**
2418
+ * Clear incomplete on blur
2419
+ * @default false
2420
+ */
2421
+ clearIncomplete?: boolean;
2422
+ /**
2423
+ * Disable
2424
+ * @default false
2425
+ */
2426
+ disabled?: boolean | Ref<boolean>;
2427
+ /**
2428
+ * Callback when value changes
2429
+ */
2430
+ onChange?: (value: string, rawValue: string) => void;
2431
+ /**
2432
+ * Callback when mask is complete
2433
+ */
2434
+ onComplete?: (value: string) => void;
2435
+ }
2436
+
2437
+ /**
2438
+ * Return type for useMask composable
2439
+ */
2440
+ export declare interface UseMaskReturn {
2441
+ /** Get formatted value */
2442
+ getFormattedValue: (value: string) => string;
2443
+ /** Get raw value (without mask literals) */
2444
+ getRawValue: (value: string) => string;
2445
+ /** Check if mask is complete */
2446
+ isComplete: (value: string) => boolean;
2447
+ /** Bind mask to an input element */
2448
+ bind: (element: HTMLInputElement | HTMLTextAreaElement) => () => void;
2449
+ }
2450
+
2054
2451
  /**
2055
2452
  * Composable for formatting numbers as money
2056
2453
  *
@@ -2133,6 +2530,104 @@ export declare interface UseMoneyReturn {
2133
2530
  parse: (formatted: string) => number;
2134
2531
  }
2135
2532
 
2533
+ /**
2534
+ * Composable for observing DOM mutations
2535
+ *
2536
+ * @param options - Configuration options
2537
+ * @returns Mutation observer utilities
2538
+ *
2539
+ * @example
2540
+ * ```vue
2541
+ * <script setup>
2542
+ * import { ref } from 'vue'
2543
+ * import { useMutation } from 'directix'
2544
+ *
2545
+ * const containerRef = ref(null)
2546
+ * const { bind } = useMutation({
2547
+ * handler: (mutations) => {
2548
+ * mutations.forEach(mutation => {
2549
+ * console.log('Type:', mutation.type)
2550
+ * console.log('Target:', mutation.target)
2551
+ * })
2552
+ * },
2553
+ * childList: true,
2554
+ * subtree: true
2555
+ * })
2556
+ *
2557
+ * onMounted(() => bind(containerRef.value))
2558
+ * </script>
2559
+ *
2560
+ * <template>
2561
+ * <div ref="containerRef">
2562
+ * Content to observe
2563
+ * </div>
2564
+ * </template>
2565
+ * ```
2566
+ */
2567
+ export declare function useMutation(options: UseMutationOptions): UseMutationReturn;
2568
+
2569
+ /**
2570
+ * Options for useMutation composable
2571
+ */
2572
+ export declare interface UseMutationOptions {
2573
+ /**
2574
+ * Callback when mutations occur
2575
+ * @required
2576
+ */
2577
+ handler: MutationHandler;
2578
+ /**
2579
+ * Whether to observe attribute changes
2580
+ * @default false
2581
+ */
2582
+ attributes?: boolean;
2583
+ /**
2584
+ * Specific attributes to observe
2585
+ */
2586
+ attributeFilter?: string[];
2587
+ /**
2588
+ * Whether to observe child node additions/removals
2589
+ * @default true
2590
+ */
2591
+ childList?: boolean;
2592
+ /**
2593
+ * Whether to observe all descendants, not just direct children
2594
+ * @default false
2595
+ */
2596
+ subtree?: boolean;
2597
+ /**
2598
+ * Whether to observe character data changes
2599
+ * @default false
2600
+ */
2601
+ characterData?: boolean;
2602
+ /**
2603
+ * Whether to record old attribute values
2604
+ * @default false
2605
+ */
2606
+ attributeOldValue?: boolean;
2607
+ /**
2608
+ * Whether to record old character data
2609
+ * @default false
2610
+ */
2611
+ characterDataOldValue?: boolean;
2612
+ /**
2613
+ * Whether to disable
2614
+ * @default false
2615
+ */
2616
+ disabled?: boolean | Ref<boolean>;
2617
+ }
2618
+
2619
+ /**
2620
+ * Return type for useMutation composable
2621
+ */
2622
+ export declare interface UseMutationReturn {
2623
+ /** Bind mutation observer to an element */
2624
+ bind: (element: HTMLElement) => () => void;
2625
+ /** Stop observing */
2626
+ stop: () => void;
2627
+ /** Start observing */
2628
+ start: () => void;
2629
+ }
2630
+
2136
2631
  /**
2137
2632
  * Composable for formatting numbers
2138
2633
  *
@@ -2543,6 +3038,151 @@ export declare interface UseResizeReturn {
2543
3038
  stop: () => void;
2544
3039
  }
2545
3040
 
3041
+ /**
3042
+ * Composable for creating ripple effects
3043
+ *
3044
+ * @param options - Configuration options
3045
+ * @returns Ripple utilities
3046
+ *
3047
+ * @example
3048
+ * ```vue
3049
+ * <script setup>
3050
+ * import { ref } from 'vue'
3051
+ * import { useRipple } from 'directix'
3052
+ *
3053
+ * const buttonRef = ref(null)
3054
+ * const { bind, trigger } = useRipple({
3055
+ * color: 'rgba(255, 255, 255, 0.3)',
3056
+ * duration: 600
3057
+ * })
3058
+ *
3059
+ * onMounted(() => bind(buttonRef.value))
3060
+ * </script>
3061
+ *
3062
+ * <template>
3063
+ * <button ref="buttonRef">Click for ripple</button>
3064
+ * </template>
3065
+ * ```
3066
+ */
3067
+ export declare function useRipple(options?: UseRippleOptions): UseRippleReturn;
3068
+
3069
+ /**
3070
+ * Options for useRipple composable
3071
+ */
3072
+ export declare interface UseRippleOptions {
3073
+ /**
3074
+ * Ripple color
3075
+ * @default 'currentColor'
3076
+ */
3077
+ color?: string | Ref<string>;
3078
+ /**
3079
+ * Ripple duration in milliseconds
3080
+ * @default 600
3081
+ */
3082
+ duration?: number | Ref<number>;
3083
+ /**
3084
+ * Whether to disable ripple
3085
+ * @default false
3086
+ */
3087
+ disabled?: boolean | Ref<boolean>;
3088
+ /**
3089
+ * Initial scale of ripple
3090
+ * @default 0
3091
+ */
3092
+ initialScale?: number;
3093
+ /**
3094
+ * Final scale of ripple
3095
+ * @default 2
3096
+ */
3097
+ finalScale?: number;
3098
+ }
3099
+
3100
+ /**
3101
+ * Return type for useRipple composable
3102
+ */
3103
+ export declare interface UseRippleReturn {
3104
+ /** Bind ripple effect to an element */
3105
+ bind: (element: HTMLElement) => () => void;
3106
+ /** Trigger ripple effect manually */
3107
+ trigger: (event?: {
3108
+ x?: number;
3109
+ y?: number;
3110
+ }) => void;
3111
+ }
3112
+
3113
+ /**
3114
+ * Composable for HTML sanitization
3115
+ *
3116
+ * @param options - Configuration options
3117
+ * @returns Sanitization utilities
3118
+ *
3119
+ * @example
3120
+ * ```vue
3121
+ * <script setup>
3122
+ * import { ref } from 'vue'
3123
+ * import { useSanitize } from 'directix'
3124
+ *
3125
+ * const { sanitize } = useSanitize({
3126
+ * allowedTags: ['b', 'i', 'p'],
3127
+ * allowedAttributes: []
3128
+ * })
3129
+ *
3130
+ * const safeHtml = sanitize(userInput)
3131
+ * </script>
3132
+ * ```
3133
+ */
3134
+ export declare function useSanitize(options?: UseSanitizeOptions): UseSanitizeReturn;
3135
+
3136
+ /**
3137
+ * Options for useSanitize composable
3138
+ */
3139
+ export declare interface UseSanitizeOptions {
3140
+ /**
3141
+ * Tags to allow (whitelist)
3142
+ * @default ['b', 'i', 'u', 'strong', 'em', 'br', 'p', 'span', 'div']
3143
+ */
3144
+ allowedTags?: string[];
3145
+ /**
3146
+ * Attributes to allow (whitelist)
3147
+ * @default ['title', 'alt', 'href', 'src']
3148
+ */
3149
+ allowedAttributes?: string[];
3150
+ /**
3151
+ * Whether to allow data URLs
3152
+ * @default false
3153
+ */
3154
+ allowDataUrls?: boolean;
3155
+ /**
3156
+ * Whether to allow inline styles
3157
+ * @default false
3158
+ */
3159
+ allowStyles?: boolean;
3160
+ /**
3161
+ * Whether to allow class attribute
3162
+ * @default false
3163
+ */
3164
+ allowClass?: boolean;
3165
+ /**
3166
+ * Whether to allow id attribute
3167
+ * @default false
3168
+ */
3169
+ allowId?: boolean;
3170
+ /**
3171
+ * Custom sanitize function
3172
+ */
3173
+ handler?: (html: string) => string;
3174
+ }
3175
+
3176
+ /**
3177
+ * Return type for useSanitize composable
3178
+ */
3179
+ export declare interface UseSanitizeReturn {
3180
+ /** Sanitize HTML string */
3181
+ sanitize: (html: string) => string;
3182
+ /** Sanitize and set to element */
3183
+ bind: (element: HTMLElement) => () => void;
3184
+ }
3185
+
2546
3186
  /**
2547
3187
  * Composable for tracking scroll position
2548
3188
  *
@@ -2618,6 +3258,68 @@ export declare interface UseScrollReturn {
2618
3258
  }) => void;
2619
3259
  }
2620
3260
 
3261
+ /**
3262
+ * Composable for sticky positioning
3263
+ *
3264
+ * @param options - Configuration options
3265
+ * @returns Sticky utilities
3266
+ *
3267
+ * @example
3268
+ * ```vue
3269
+ * <script setup>
3270
+ * import { ref } from 'vue'
3271
+ * import { useSticky } from 'directix'
3272
+ *
3273
+ * const headerRef = ref(null)
3274
+ * const { isSticky, bind } = useSticky({
3275
+ * offsetTop: 60,
3276
+ * onStick: (sticky) => console.log('Sticky:', sticky)
3277
+ * })
3278
+ *
3279
+ * onMounted(() => bind(headerRef.value))
3280
+ * </script>
3281
+ *
3282
+ * <template>
3283
+ * <header ref="headerRef" :class="{ sticky: isSticky }">
3284
+ * Navigation
3285
+ * </header>
3286
+ * </template>
3287
+ * ```
3288
+ */
3289
+ export declare function useSticky(options?: UseStickyOptions): UseStickyReturn;
3290
+
3291
+ /**
3292
+ * Options for useSticky composable
3293
+ */
3294
+ export declare interface UseStickyOptions {
3295
+ /**
3296
+ * Offset from top in pixels
3297
+ * @default 0
3298
+ */
3299
+ offsetTop?: number | Ref<number>;
3300
+ /**
3301
+ * Callback when stick state changes
3302
+ */
3303
+ onStick?: (isSticky: boolean) => void;
3304
+ /**
3305
+ * Whether to disable
3306
+ * @default false
3307
+ */
3308
+ disabled?: boolean | Ref<boolean>;
3309
+ }
3310
+
3311
+ /**
3312
+ * Return type for useSticky composable
3313
+ */
3314
+ export declare interface UseStickyReturn {
3315
+ /** Whether the element is sticky */
3316
+ isSticky: Readonly<Ref<boolean>>;
3317
+ /** Bind sticky behavior to an element */
3318
+ bind: (element: HTMLElement) => () => void;
3319
+ /** Stop observing */
3320
+ stop: () => void;
3321
+ }
3322
+
2621
3323
  /**
2622
3324
  * Composable for detecting swipe gestures
2623
3325
  *
@@ -2780,6 +3482,102 @@ export declare interface UseThrottleReturn<T extends (...args: any[]) => any> {
2780
3482
  cancel: () => void;
2781
3483
  }
2782
3484
 
3485
+ /**
3486
+ * Composable for tooltip functionality
3487
+ *
3488
+ * @param options - Configuration options
3489
+ * @returns Tooltip utilities
3490
+ *
3491
+ * @example
3492
+ * ```vue
3493
+ * <script setup>
3494
+ * import { ref } from 'vue'
3495
+ * import { useTooltip } from 'directix'
3496
+ *
3497
+ * const buttonRef = ref(null)
3498
+ * const { isVisible, bind } = useTooltip({
3499
+ * content: 'Tooltip text',
3500
+ * placement: 'top'
3501
+ * })
3502
+ *
3503
+ * onMounted(() => bind(buttonRef.value))
3504
+ * </script>
3505
+ *
3506
+ * <template>
3507
+ * <button ref="buttonRef">Hover me</button>
3508
+ * </template>
3509
+ * ```
3510
+ */
3511
+ export declare function useTooltip(options?: UseTooltipOptions): UseTooltipReturn;
3512
+
3513
+ /**
3514
+ * Options for useTooltip composable
3515
+ */
3516
+ export declare interface UseTooltipOptions {
3517
+ /**
3518
+ * Tooltip content
3519
+ */
3520
+ content?: string | Ref<string>;
3521
+ /**
3522
+ * Tooltip placement
3523
+ * @default 'top'
3524
+ */
3525
+ placement?: TooltipPlacement;
3526
+ /**
3527
+ * Trigger type
3528
+ * @default 'hover'
3529
+ */
3530
+ trigger?: TooltipTrigger;
3531
+ /**
3532
+ * Show delay in milliseconds
3533
+ * @default 0
3534
+ */
3535
+ delay?: number;
3536
+ /**
3537
+ * Hide delay in milliseconds
3538
+ * @default 0
3539
+ */
3540
+ hideDelay?: number;
3541
+ /**
3542
+ * Whether to show arrow
3543
+ * @default true
3544
+ */
3545
+ arrow?: boolean;
3546
+ /**
3547
+ * Custom class for tooltip
3548
+ */
3549
+ class?: string;
3550
+ /**
3551
+ * Callback when tooltip shows
3552
+ */
3553
+ onShow?: () => void;
3554
+ /**
3555
+ * Callback when tooltip hides
3556
+ */
3557
+ onHide?: () => void;
3558
+ /**
3559
+ * Whether to disable
3560
+ * @default false
3561
+ */
3562
+ disabled?: boolean | Ref<boolean>;
3563
+ }
3564
+
3565
+ /**
3566
+ * Return type for useTooltip composable
3567
+ */
3568
+ export declare interface UseTooltipReturn {
3569
+ /** Whether the tooltip is visible */
3570
+ isVisible: Readonly<Ref<boolean>>;
3571
+ /** Show the tooltip */
3572
+ show: () => void;
3573
+ /** Hide the tooltip */
3574
+ hide: () => void;
3575
+ /** Toggle the tooltip */
3576
+ toggle: () => void;
3577
+ /** Bind tooltip to an element */
3578
+ bind: (element: HTMLElement) => () => void;
3579
+ }
3580
+
2783
3581
  /**
2784
3582
  * Composable for touch gesture detection
2785
3583
  *
@@ -2945,6 +3743,73 @@ export declare interface UseTrimReturn {
2945
3743
  wasTrimmed: Ref<boolean>;
2946
3744
  }
2947
3745
 
3746
+ /**
3747
+ * Composable for text truncation
3748
+ *
3749
+ * @param options - Configuration options
3750
+ * @returns Truncation utilities
3751
+ *
3752
+ * @example
3753
+ * ```vue
3754
+ * <script setup>
3755
+ * import { ref } from 'vue'
3756
+ * import { useTruncate } from 'directix'
3757
+ *
3758
+ * const longText = ref('This is a very long text that needs to be truncated')
3759
+ * const { truncated, isTruncated } = useTruncate({
3760
+ * text: longText,
3761
+ * length: 20,
3762
+ * position: 'middle'
3763
+ * })
3764
+ * </script>
3765
+ *
3766
+ * <template>
3767
+ * <span>{{ truncated }}</span>
3768
+ * <span v-if="isTruncated" :title="longText">...</span>
3769
+ * </template>
3770
+ * ```
3771
+ */
3772
+ export declare function useTruncate(options: UseTruncateOptions): UseTruncateReturn;
3773
+
3774
+ /**
3775
+ * Options for useTruncate composable
3776
+ */
3777
+ export declare interface UseTruncateOptions {
3778
+ /**
3779
+ * Text to truncate
3780
+ */
3781
+ text: string | Ref<string>;
3782
+ /**
3783
+ * Maximum length
3784
+ * @default 100
3785
+ */
3786
+ length?: number | Ref<number>;
3787
+ /**
3788
+ * Truncation position
3789
+ * @default 'end'
3790
+ */
3791
+ position?: TruncatePosition | Ref<TruncatePosition>;
3792
+ /**
3793
+ * Omission string
3794
+ * @default '...'
3795
+ */
3796
+ omission?: string;
3797
+ }
3798
+
3799
+ /**
3800
+ * Return type for useTruncate composable
3801
+ */
3802
+ export declare interface UseTruncateReturn {
3803
+ /** Truncated text */
3804
+ truncated: Readonly<Ref<string>>;
3805
+ /** Whether the text was truncated */
3806
+ isTruncated: Readonly<Ref<boolean>>;
3807
+ /** Original text length */
3808
+ originalLength: Readonly<Ref<number>>;
3809
+ /** Truncate a custom string */
3810
+ truncate: (text: string, length?: number, position?: TruncatePosition) => string;
3811
+ }
3812
+
2948
3813
  /**
2949
3814
  * Composable for transforming text to uppercase
2950
3815
  *