directix 1.2.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/README.md +321 -1
- package/dist/index.cjs +4916 -365
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3000 -1142
- package/dist/index.iife.js +4917 -367
- package/dist/index.iife.js.map +1 -1
- package/dist/index.iife.min.js +2 -2
- package/dist/index.mjs +4909 -358
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,13 +10,14 @@ A comprehensive, easy-to-use, and high-performance Vue custom directives library
|
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
-
- 🎯 **Comprehensive** -
|
|
13
|
+
- 🎯 **Comprehensive** - 40 commonly used directives and 40 composables
|
|
14
14
|
- 🔄 **Vue 2/3 Compatible** - Single codebase supports both Vue 2 and Vue 3
|
|
15
15
|
- 📦 **Tree-shakable** - Import only what you need
|
|
16
16
|
- 🔒 **TypeScript** - Full TypeScript support with type definitions
|
|
17
17
|
- 🚀 **SSR Friendly** - Multiple directives support SSR out of the box
|
|
18
18
|
- 📦 **Multiple Formats** - ESM, CJS, and IIFE (CDN) formats available
|
|
19
19
|
- ⚡ **Zero Dependencies** - Lightweight with minimal bundle size
|
|
20
|
+
- 🎨 **Composables** - Every directive has a corresponding composable for Composition API
|
|
20
21
|
|
|
21
22
|
## Online Demo
|
|
22
23
|
|
|
@@ -111,6 +112,21 @@ app.directive('copy', vCopy)
|
|
|
111
112
|
Vue.directive('click-outside', vClickOutside)
|
|
112
113
|
```
|
|
113
114
|
|
|
115
|
+
### Using Composables
|
|
116
|
+
|
|
117
|
+
Every directive has a corresponding composable for use with the Composition API:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { useClickOutside, useCopy, useDebounce } from 'directix'
|
|
121
|
+
|
|
122
|
+
// In setup() or <script setup>
|
|
123
|
+
const { copy, copied } = useCopy({ source: textRef })
|
|
124
|
+
const { isHovering, bind } = useHover({ onEnter: handleEnter })
|
|
125
|
+
const { run: debouncedSearch } = useDebounce({ handler: search, wait: 500 })
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
See the [Composables](#composables) section below for all available composables.
|
|
129
|
+
|
|
114
130
|
## Available Directives
|
|
115
131
|
|
|
116
132
|
### Event Directives
|
|
@@ -118,11 +134,14 @@ Vue.directive('click-outside', vClickOutside)
|
|
|
118
134
|
| Directive | Description | SSR |
|
|
119
135
|
|-----------|-------------|-----|
|
|
120
136
|
| `v-click-outside` | Detect clicks outside an element | ❌ |
|
|
137
|
+
| `v-click-delay` | Delay click execution to prevent double clicks | ✅ |
|
|
121
138
|
| `v-debounce` | Debounce event handlers | ✅ |
|
|
122
139
|
| `v-throttle` | Throttle event handlers | ✅ |
|
|
123
140
|
| `v-long-press` | Detect long press events | ❌ |
|
|
124
141
|
| `v-hover` | Hover state detection | ❌ |
|
|
142
|
+
| `v-hotkey` | Keyboard shortcut binding | ✅ |
|
|
125
143
|
| `v-touch` | Touch gesture detection (swipe, pinch, rotate) | ❌ |
|
|
144
|
+
| `v-swipe` | Swipe gesture detection with mouse support | ❌ |
|
|
126
145
|
|
|
127
146
|
### Form Directives
|
|
128
147
|
|
|
@@ -134,6 +153,7 @@ Vue.directive('click-outside', vClickOutside)
|
|
|
134
153
|
| `v-trim` | Trim input whitespace | ✅ |
|
|
135
154
|
| `v-money` | Currency format input | ❌ |
|
|
136
155
|
| `v-number` | Number format input | ❌ |
|
|
156
|
+
| `v-ellipsis` | Text ellipsis overflow | ✅ |
|
|
137
157
|
|
|
138
158
|
### Format Directives
|
|
139
159
|
|
|
@@ -160,6 +180,8 @@ Vue.directive('click-outside', vClickOutside)
|
|
|
160
180
|
| `v-scroll` | Scroll event handling | ❌ |
|
|
161
181
|
| `v-infinite-scroll` | Infinite scrolling | ❌ |
|
|
162
182
|
| `v-sticky` | Sticky positioning | ❌ |
|
|
183
|
+
| `v-pull-refresh` | Pull to refresh functionality | ❌ |
|
|
184
|
+
| `v-virtual-list` | Virtual list for large datasets | ❌ |
|
|
163
185
|
|
|
164
186
|
### Security Directives
|
|
165
187
|
|
|
@@ -188,9 +210,122 @@ Vue.directive('click-outside', vClickOutside)
|
|
|
188
210
|
|-----------|-------------|-----|
|
|
189
211
|
| `v-tooltip` | Tooltip component | ❌ |
|
|
190
212
|
| `v-image-preview` | Image preview with zoom | ❌ |
|
|
213
|
+
| `v-countdown` | Countdown timer display | ✅ |
|
|
214
|
+
| `v-print` | Print element content | ❌ |
|
|
215
|
+
| `v-watermark` | Watermark overlay | ✅ |
|
|
191
216
|
|
|
192
217
|
> ✅ = SSR compatible | ❌ = Not SSR compatible
|
|
193
218
|
|
|
219
|
+
## Composables
|
|
220
|
+
|
|
221
|
+
Every directive has a corresponding composable function for use with the Composition API. All composables are exported from `directix`:
|
|
222
|
+
|
|
223
|
+
### Event Composables
|
|
224
|
+
|
|
225
|
+
| Composable | Description |
|
|
226
|
+
|------------|-------------|
|
|
227
|
+
| `useClickOutside` | Detect clicks outside an element |
|
|
228
|
+
| `useClickDelay` | Delay click execution |
|
|
229
|
+
| `useDebounce` | Debounce function calls |
|
|
230
|
+
| `useThrottle` | Throttle function calls |
|
|
231
|
+
| `useLongPress` | Detect long press gestures |
|
|
232
|
+
| `useHover` | Track hover state |
|
|
233
|
+
| `useHotkey` | Handle keyboard shortcuts |
|
|
234
|
+
| `useTouch` | Detect touch gestures |
|
|
235
|
+
| `useSwipe` | Detect swipe gestures |
|
|
236
|
+
|
|
237
|
+
### Form Composables
|
|
238
|
+
|
|
239
|
+
| Composable | Description |
|
|
240
|
+
|------------|-------------|
|
|
241
|
+
| `useCopy` | Copy text to clipboard |
|
|
242
|
+
| `useFocus` | Manage element focus |
|
|
243
|
+
| `useMask` | Input masking |
|
|
244
|
+
| `useTrim` | Trim input whitespace |
|
|
245
|
+
| `useMoney` | Currency formatting |
|
|
246
|
+
| `useNumber` | Number formatting |
|
|
247
|
+
| `useEllipsis` | Text ellipsis overflow |
|
|
248
|
+
|
|
249
|
+
### Format Composables
|
|
250
|
+
|
|
251
|
+
| Composable | Description |
|
|
252
|
+
|------------|-------------|
|
|
253
|
+
| `useUppercase` | Transform to uppercase |
|
|
254
|
+
| `useLowercase` | Transform to lowercase |
|
|
255
|
+
| `useCapitalcase` | Capitalize text |
|
|
256
|
+
| `useTruncate` | Truncate text |
|
|
257
|
+
|
|
258
|
+
### Visibility Composables
|
|
259
|
+
|
|
260
|
+
| Composable | Description |
|
|
261
|
+
|------------|-------------|
|
|
262
|
+
| `useLazy` | Lazy load images |
|
|
263
|
+
| `useIntersect` | Detect element intersection |
|
|
264
|
+
| `useVisible` | Control element visibility |
|
|
265
|
+
| `useLoading` | Show loading overlay |
|
|
266
|
+
|
|
267
|
+
### Scroll Composables
|
|
268
|
+
|
|
269
|
+
| Composable | Description |
|
|
270
|
+
|------------|-------------|
|
|
271
|
+
| `useScroll` | Track scroll position |
|
|
272
|
+
| `useInfiniteScroll` | Infinite scrolling |
|
|
273
|
+
| `useSticky` | Sticky positioning |
|
|
274
|
+
| `usePullRefresh` | Pull to refresh |
|
|
275
|
+
| `useVirtualList` | Virtual list for large datasets |
|
|
276
|
+
|
|
277
|
+
### Other Composables
|
|
278
|
+
|
|
279
|
+
| Composable | Description |
|
|
280
|
+
|------------|-------------|
|
|
281
|
+
| `usePermission` | Permission checking |
|
|
282
|
+
| `useSanitize` | Sanitize HTML content |
|
|
283
|
+
| `useRipple` | Material design ripple effect |
|
|
284
|
+
| `useDraggable` | Make elements draggable |
|
|
285
|
+
| `useResize` | Element resize observer |
|
|
286
|
+
| `useMutation` | DOM mutation observer |
|
|
287
|
+
| `useTooltip` | Tooltip control |
|
|
288
|
+
| `useImagePreview` | Image preview with zoom |
|
|
289
|
+
| `useCountdown` | Countdown timer |
|
|
290
|
+
| `usePrint` | Print content |
|
|
291
|
+
| `useWatermark` | Watermark overlay |
|
|
292
|
+
|
|
293
|
+
### Composable Usage Example
|
|
294
|
+
|
|
295
|
+
```vue
|
|
296
|
+
<script setup>
|
|
297
|
+
import { ref } from 'vue'
|
|
298
|
+
import { useCopy, useHover, useDebounce } from 'directix'
|
|
299
|
+
|
|
300
|
+
// useCopy
|
|
301
|
+
const text = ref('Hello World')
|
|
302
|
+
const { copy, copied } = useCopy({ source: text })
|
|
303
|
+
|
|
304
|
+
// useHover
|
|
305
|
+
const buttonRef = ref()
|
|
306
|
+
const { isHovering, bind } = useHover({
|
|
307
|
+
onEnter: () => console.log('Entered'),
|
|
308
|
+
onLeave: () => console.log('Left')
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
// useDebounce
|
|
312
|
+
const { run: debouncedSearch } = useDebounce({
|
|
313
|
+
handler: (query) => fetchResults(query),
|
|
314
|
+
wait: 500
|
|
315
|
+
})
|
|
316
|
+
</script>
|
|
317
|
+
|
|
318
|
+
<template>
|
|
319
|
+
<button @click="copy()">
|
|
320
|
+
{{ copied ? 'Copied!' : 'Copy' }}
|
|
321
|
+
</button>
|
|
322
|
+
|
|
323
|
+
<button ref="buttonRef" :class="{ active: isHovering }">
|
|
324
|
+
Hover me
|
|
325
|
+
</button>
|
|
326
|
+
</template>
|
|
327
|
+
```
|
|
328
|
+
|
|
194
329
|
## Usage Examples
|
|
195
330
|
|
|
196
331
|
### v-click-outside
|
|
@@ -530,6 +665,191 @@ Number format input.
|
|
|
530
665
|
</template>
|
|
531
666
|
```
|
|
532
667
|
|
|
668
|
+
### v-click-delay
|
|
669
|
+
|
|
670
|
+
Delay click execution to prevent double clicks.
|
|
671
|
+
|
|
672
|
+
```vue
|
|
673
|
+
<template>
|
|
674
|
+
<!-- Default: 300ms delay -->
|
|
675
|
+
<button v-click-delay="handleClick">Click me</button>
|
|
676
|
+
|
|
677
|
+
<!-- Custom delay time -->
|
|
678
|
+
<button v-click-delay="{ handler: handleClick, delay: 500 }">500ms delay</button>
|
|
679
|
+
</template>
|
|
680
|
+
|
|
681
|
+
<script setup>
|
|
682
|
+
function handleClick() {
|
|
683
|
+
console.log('Clicked (delayed)')
|
|
684
|
+
}
|
|
685
|
+
</script>
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
### v-countdown
|
|
689
|
+
|
|
690
|
+
Countdown timer display.
|
|
691
|
+
|
|
692
|
+
```vue
|
|
693
|
+
<template>
|
|
694
|
+
<!-- Simple usage -->
|
|
695
|
+
<span v-countdown="{ time: 60 }"></span>
|
|
696
|
+
|
|
697
|
+
<!-- With callbacks -->
|
|
698
|
+
<span v-countdown="{ time: 60, onTick: handleTick, onComplete: handleComplete }"></span>
|
|
699
|
+
|
|
700
|
+
<!-- Custom format -->
|
|
701
|
+
<span v-countdown="{ time: 3600, format: 'mm:ss' }"></span>
|
|
702
|
+
</template>
|
|
703
|
+
|
|
704
|
+
<script setup>
|
|
705
|
+
function handleTick(remaining) {
|
|
706
|
+
console.log('Remaining:', remaining)
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
function handleComplete() {
|
|
710
|
+
console.log('Countdown complete!')
|
|
711
|
+
}
|
|
712
|
+
</script>
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### v-ellipsis
|
|
716
|
+
|
|
717
|
+
Text ellipsis overflow with tooltip.
|
|
718
|
+
|
|
719
|
+
```vue
|
|
720
|
+
<template>
|
|
721
|
+
<!-- Simple usage -->
|
|
722
|
+
<div v-ellipsis style="width: 200px;">Long text that will be truncated</div>
|
|
723
|
+
|
|
724
|
+
<!-- With custom lines -->
|
|
725
|
+
<div v-ellipsis="{ lines: 2 }">Multi-line text with ellipsis</div>
|
|
726
|
+
</template>
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### v-hotkey
|
|
730
|
+
|
|
731
|
+
Keyboard shortcut binding.
|
|
732
|
+
|
|
733
|
+
```vue
|
|
734
|
+
<template>
|
|
735
|
+
<!-- Simple usage -->
|
|
736
|
+
<div v-hotkey="{ 'ctrl+s': handleSave, 'ctrl+c': handleCopy }">
|
|
737
|
+
Press Ctrl+S to save
|
|
738
|
+
</div>
|
|
739
|
+
|
|
740
|
+
<!-- With modifiers -->
|
|
741
|
+
<input v-hotkey="{ 'enter': submit, 'escape': cancel }" />
|
|
742
|
+
</template>
|
|
743
|
+
|
|
744
|
+
<script setup>
|
|
745
|
+
function handleSave() {
|
|
746
|
+
console.log('Saving...')
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
function handleCopy() {
|
|
750
|
+
console.log('Copying...')
|
|
751
|
+
}
|
|
752
|
+
</script>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### v-print
|
|
756
|
+
|
|
757
|
+
Print element content.
|
|
758
|
+
|
|
759
|
+
```vue
|
|
760
|
+
<template>
|
|
761
|
+
<!-- Simple usage -->
|
|
762
|
+
<button v-print="printRef">Print</button>
|
|
763
|
+
<div ref="printRef">Content to print</div>
|
|
764
|
+
|
|
765
|
+
<!-- Print self -->
|
|
766
|
+
<div v-print="{ self: true }">Click to print this content</div>
|
|
767
|
+
</template>
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### v-pull-refresh
|
|
771
|
+
|
|
772
|
+
Pull to refresh functionality.
|
|
773
|
+
|
|
774
|
+
```vue
|
|
775
|
+
<template>
|
|
776
|
+
<div v-pull-refresh="handleRefresh" style="height: 400px; overflow: auto;">
|
|
777
|
+
Pull down to refresh
|
|
778
|
+
</div>
|
|
779
|
+
|
|
780
|
+
<!-- With options -->
|
|
781
|
+
<div v-pull-refresh="{ handler: handleRefresh, threshold: 80, disabled: false }">
|
|
782
|
+
Content
|
|
783
|
+
</div>
|
|
784
|
+
</template>
|
|
785
|
+
|
|
786
|
+
<script setup>
|
|
787
|
+
async function handleRefresh() {
|
|
788
|
+
// Fetch new data
|
|
789
|
+
await fetchData()
|
|
790
|
+
}
|
|
791
|
+
</script>
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### v-swipe
|
|
795
|
+
|
|
796
|
+
Swipe gesture detection with mouse support.
|
|
797
|
+
|
|
798
|
+
```vue
|
|
799
|
+
<template>
|
|
800
|
+
<div v-swipe="handleSwipe" style="height: 200px;">
|
|
801
|
+
Swipe in any direction
|
|
802
|
+
</div>
|
|
803
|
+
|
|
804
|
+
<!-- With options -->
|
|
805
|
+
<div v-swipe="{ onSwipe: handleSwipe, threshold: 50, enableMouse: true }">
|
|
806
|
+
Swipe or drag with mouse
|
|
807
|
+
</div>
|
|
808
|
+
</template>
|
|
809
|
+
|
|
810
|
+
<script setup>
|
|
811
|
+
function handleSwipe(direction) {
|
|
812
|
+
console.log('Swiped:', direction) // 'left', 'right', 'up', 'down'
|
|
813
|
+
}
|
|
814
|
+
</script>
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### v-virtual-list
|
|
818
|
+
|
|
819
|
+
Virtual list for rendering large datasets efficiently.
|
|
820
|
+
|
|
821
|
+
```vue
|
|
822
|
+
<template>
|
|
823
|
+
<div v-virtual-list="{ items: list, itemSize: 50 }" style="height: 500px;">
|
|
824
|
+
<template #default="{ item, index }">
|
|
825
|
+
<div :key="index">{{ item.name }}</div>
|
|
826
|
+
</template>
|
|
827
|
+
</div>
|
|
828
|
+
</template>
|
|
829
|
+
|
|
830
|
+
<script setup>
|
|
831
|
+
const list = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` }))
|
|
832
|
+
</script>
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
### v-watermark
|
|
836
|
+
|
|
837
|
+
Watermark overlay.
|
|
838
|
+
|
|
839
|
+
```vue
|
|
840
|
+
<template>
|
|
841
|
+
<!-- Simple usage -->
|
|
842
|
+
<div v-watermark="'Confidential'" style="width: 100%; height: 400px;">
|
|
843
|
+
Protected content
|
|
844
|
+
</div>
|
|
845
|
+
|
|
846
|
+
<!-- With options -->
|
|
847
|
+
<div v-watermark="{ content: 'Draft', fontSize: 16, color: '#ccc', rotate: -20 }">
|
|
848
|
+
Content with watermark
|
|
849
|
+
</div>
|
|
850
|
+
</template>
|
|
851
|
+
```
|
|
852
|
+
|
|
533
853
|
## API Reference
|
|
534
854
|
|
|
535
855
|
### DirectiveInstallOptions
|