@dnax/ui 0.0.27 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,182 @@
1
+ // v-touch-swipe — directive : détecte le « swipe » (glissement rapide puis
2
+ // relâchement), équivalent Quasar
3
+ // https://quasar.dev/vue-directives/touch-swipe
4
+ //
5
+ // Usage :
6
+ // <div v-touch-swipe.horizontal.mouse="onSwipe">…</div>
7
+ // <div v-touch-swipe="{ distance: 40, duration: 300 }">…</div>
8
+ // modifiers : horizontal | vertical | up | down | left | right (filtres de
9
+ // direction), mouse (inclut la souris), capture / mouseCapture, stop, prevent,
10
+ // passive
11
+ //
12
+ // Détails du handler : { evt, direction, distance: { x, y }, duration,
13
+ // speed: { x, y } }
14
+
15
+ export type SwipeDirection = "up" | "down" | "left" | "right"
16
+
17
+ export interface TouchSwipeDetails {
18
+ evt: PointerEvent
19
+ direction: SwipeDirection
20
+ /** Distance totale (px), par axe (signée) */
21
+ distance: { x: number; y: number }
22
+ duration: number
23
+ /** Vitesse finale (px/s), par axe */
24
+ speed: { x: number; y: number }
25
+ }
26
+
27
+ export type TouchSwipeHandler = (details: TouchSwipeDetails) => void
28
+
29
+ const DEFAULTS = { distance: 50, duration: 300 }
30
+
31
+ interface SwipeOptions {
32
+ handler: TouchSwipeHandler
33
+ distance: number
34
+ duration: number
35
+ allowHorizontal: boolean
36
+ allowVertical: boolean
37
+ allowUp: boolean
38
+ allowDown: boolean
39
+ allowLeft: boolean
40
+ allowRight: boolean
41
+ mouse: boolean
42
+ stop: boolean
43
+ prevent: boolean
44
+ capture: boolean
45
+ passive: boolean
46
+ }
47
+
48
+ type QElement = HTMLElement & { __qTouchSwipeCleanup?: () => void }
49
+
50
+ function parseValue(value: unknown): { distance?: number; duration?: number } {
51
+ if (value && typeof value === "object") {
52
+ const o = value as Record<string, unknown>
53
+ const out: { distance?: number; duration?: number } = {}
54
+ const d = Number(o.distance)
55
+ if (Number.isFinite(d)) out.distance = d
56
+ const t = Number(o.duration)
57
+ if (Number.isFinite(t)) out.duration = t
58
+ return out
59
+ }
60
+ return {}
61
+ }
62
+
63
+ function axisAllowed(o: SwipeOptions, direction: SwipeDirection) {
64
+ if (o.allowHorizontal) return direction === "left" || direction === "right"
65
+ if (o.allowVertical) return direction === "up" || direction === "down"
66
+ switch (direction) {
67
+ case "up": return o.allowUp
68
+ case "down": return o.allowDown
69
+ case "left": return o.allowLeft
70
+ case "right": return o.allowRight
71
+ }
72
+ }
73
+
74
+ export const vTouchSwipe = {
75
+ mounted(el: HTMLElement, binding: { value?: unknown; modifiers?: Record<string, boolean> }) {
76
+ const handler = binding.value
77
+ if (typeof handler !== "function") {
78
+ console.warn("[v-touch-swipe] value doit être une fonction (handler)")
79
+ return
80
+ }
81
+ const m = binding.modifiers ?? {}
82
+ const parsed = parseValue(binding.value)
83
+ const options: SwipeOptions = {
84
+ handler: handler as TouchSwipeHandler,
85
+ distance: parsed.distance ?? DEFAULTS.distance,
86
+ duration: parsed.duration ?? DEFAULTS.duration,
87
+ allowHorizontal: !!m.horizontal,
88
+ allowVertical: !!m.vertical,
89
+ allowUp: !!m.up,
90
+ allowDown: !!m.down,
91
+ allowLeft: !!m.left,
92
+ allowRight: !!m.right,
93
+ mouse: !!m.mouse || !!m.mouseCapture,
94
+ stop: !!m.stop,
95
+ prevent: !!m.prevent,
96
+ capture: !!m.capture || !!m.mouseCapture,
97
+ passive: !!m.passive,
98
+ }
99
+
100
+ if (options.prevent) el.style.touchAction = "none"
101
+ else if (options.allowHorizontal && !options.allowVertical) el.style.touchAction = "pan-y"
102
+ else if (options.allowVertical && !options.allowHorizontal) el.style.touchAction = "pan-x"
103
+ else el.style.touchAction = "auto"
104
+
105
+ let startX = 0
106
+ let startY = 0
107
+ let startTime = 0
108
+ let lastX = 0
109
+ let lastY = 0
110
+ let lastTime = 0
111
+ let tracking = false
112
+
113
+ const guard = (e: Event) => {
114
+ if (options.stop) e.stopPropagation()
115
+ if (options.prevent) e.preventDefault()
116
+ }
117
+
118
+ const onPointerDown = (e: PointerEvent) => {
119
+ if (tracking) return
120
+ if (e.pointerType === "mouse" && !options.mouse) return
121
+ guard(e)
122
+ tracking = true
123
+ startX = lastX = e.clientX
124
+ startY = lastY = e.clientY
125
+ startTime = lastTime = performance.now()
126
+ }
127
+
128
+ const onPointerMove = (e: PointerEvent) => {
129
+ if (!tracking) return
130
+ lastX = e.clientX
131
+ lastY = e.clientY
132
+ lastTime = performance.now()
133
+ guard(e)
134
+ }
135
+
136
+ const onPointerUp = (e: PointerEvent) => {
137
+ if (!tracking) return
138
+ tracking = false
139
+ const now = performance.now()
140
+ const duration = now - startTime
141
+ const dx = e.clientX - startX
142
+ const dy = e.clientY - startY
143
+ const direction: SwipeDirection =
144
+ Math.abs(dx) >= Math.abs(dy) ? (dx > 0 ? "right" : "left") : (dy > 0 ? "down" : "up")
145
+ if (!axisAllowed(options, direction)) return
146
+ const along = direction === "left" || direction === "right" ? Math.abs(dx) : Math.abs(dy)
147
+ if (along < options.distance) return
148
+ if (duration > options.duration) return
149
+ const elapsed = Math.max(now - lastTime, 1)
150
+ const instSpeed = {
151
+ x: (lastX - startX) / elapsed * 1000,
152
+ y: (lastY - startY) / elapsed * 1000,
153
+ }
154
+ options.handler({
155
+ evt: e,
156
+ direction,
157
+ distance: { x: dx, y: dy },
158
+ duration,
159
+ speed: { x: Math.round(instSpeed.x), y: Math.round(instSpeed.y) },
160
+ })
161
+ }
162
+
163
+ const onCancel = () => { tracking = false }
164
+ const capture = options.capture
165
+ el.addEventListener("pointerdown", onPointerDown, { capture, passive: options.passive })
166
+ el.addEventListener("pointermove", onPointerMove, { capture, passive: options.passive })
167
+ el.addEventListener("pointerup", onPointerUp, { capture })
168
+ el.addEventListener("pointercancel", onCancel, { capture })
169
+
170
+ ;(el as QElement).__qTouchSwipeCleanup = () => {
171
+ el.removeEventListener("pointerdown", onPointerDown, { capture } as any)
172
+ el.removeEventListener("pointermove", onPointerMove, { capture } as any)
173
+ el.removeEventListener("pointerup", onPointerUp, { capture } as any)
174
+ el.removeEventListener("pointercancel", onCancel, { capture } as any)
175
+ el.style.touchAction = ""
176
+ }
177
+ },
178
+ unmounted(el: HTMLElement) {
179
+ ;(el as QElement).__qTouchSwipeCleanup?.()
180
+ delete (el as QElement).__qTouchSwipeCleanup
181
+ },
182
+ }
package/module.ts CHANGED
@@ -93,9 +93,17 @@ export default defineNuxtPlugin((nuxtApp) => {
93
93
  getContents: () => `
94
94
  import { defineNuxtPlugin } from "#imports"
95
95
  import { vClose } from "@dnax/ui/runtime"
96
+ import { vTouchPan } from "@dnax/ui/runtime"
97
+ import { vTouchHold } from "@dnax/ui/runtime"
98
+ import { vTouchSwipe } from "@dnax/ui/runtime"
99
+ import { vTouchRepeat } from "@dnax/ui/runtime"
96
100
 
97
101
  export default defineNuxtPlugin((nuxtApp) => {
98
102
  nuxtApp.vueApp.directive("close", vClose)
103
+ nuxtApp.vueApp.directive("touch-pan", vTouchPan)
104
+ nuxtApp.vueApp.directive("touch-hold", vTouchHold)
105
+ nuxtApp.vueApp.directive("touch-swipe", vTouchSwipe)
106
+ nuxtApp.vueApp.directive("touch-repeat", vTouchRepeat)
99
107
  })
100
108
  `,
101
109
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dnax/ui",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "module": "index.ts",
5
5
  "description": "UI design System",
6
6
  "type": "module",
@@ -22,8 +22,32 @@
22
22
  "vue": "^3.5.41"
23
23
  },
24
24
  "dependencies": {
25
+ "@editorjs/checklist": "^1.6.0",
26
+ "@editorjs/code": "^2.9.4",
27
+ "@editorjs/delimiter": "^1.4.2",
28
+ "@editorjs/editorjs": "^2.31.6",
29
+ "@editorjs/header": "^2.8.9",
30
+ "@editorjs/list": "^2.0.9",
31
+ "@editorjs/paragraph": "^2.11.7",
32
+ "@editorjs/quote": "^2.7.6",
25
33
  "@iconify/vue": "^5.0.1",
26
34
  "@nuxt/kit": "^4.5.2",
35
+ "@tiptap/extension-bubble-menu": "^3.31.3",
36
+ "@tiptap/extension-drag-handle": "^3.31.3",
37
+ "@tiptap/extension-drag-handle-vue-3": "^3.31.3",
38
+ "@tiptap/extension-floating-menu": "^3.31.3",
39
+ "@tiptap/extension-image": "^3.31.3",
40
+ "@tiptap/extension-mention": "^3.31.3",
41
+ "@tiptap/extension-table": "^3.31.3",
42
+ "@tiptap/extension-table-of-contents": "^3.31.3",
43
+ "@tiptap/extension-task-item": "^3.31.3",
44
+ "@tiptap/extension-task-list": "^3.31.3",
45
+ "@tiptap/extension-text-align": "^3.31.3",
46
+ "@tiptap/extension-text-style": "^3.31.3",
47
+ "@tiptap/pm": "^3.31.3",
48
+ "@tiptap/starter-kit": "^3.31.3",
49
+ "@tiptap/suggestion": "^3.31.3",
50
+ "@tiptap/vue-3": "^3.31.3",
27
51
  "@videojs/html": "^10.0.0-beta.32",
28
52
  "@vueuse/core": "^14.4.0",
29
53
  "class-variance-authority": "^0.7.1",
@@ -42,6 +42,8 @@ export { screen } from "./lib/screen"
42
42
  export type { QScreen } from "./lib/screen"
43
43
  export { loading } from "./lib/loading"
44
44
  export type { LoadingOptions, QLoadingPlugin } from "./lib/loading"
45
+ export { localStorage, sessionStorage } from "./lib/storage"
46
+ export type { QWebStorage } from "./lib/storage"
45
47
  export {
46
48
  registerOverlay,
47
49
  unregisterOverlay,
@@ -52,6 +54,14 @@ export {
52
54
  } from "./lib/overlayBack"
53
55
  export type { OverlayHandle } from "./lib/overlayBack"
54
56
  export { markOverlayClose, closeParentOverlay, vClose } from "./lib/closeOverlay"
57
+ export { vTouchPan } from "./lib/touchPan"
58
+ export type { PanDetails, TouchPanHandler, PanDirection } from "./lib/touchPan"
59
+ export { vTouchHold } from "./lib/touchHold"
60
+ export type { TouchHoldDetails, TouchHoldHandler } from "./lib/touchHold"
61
+ export { vTouchSwipe } from "./lib/touchSwipe"
62
+ export type { TouchSwipeDetails, TouchSwipeHandler, SwipeDirection } from "./lib/touchSwipe"
63
+ export { vTouchRepeat } from "./lib/touchRepeat"
64
+ export type { TouchRepeatDetails, TouchRepeatHandler } from "./lib/touchRepeat"
55
65
  `
56
66
 
57
67
  await Bun.write(indexFile, `${exports}\n${manualExports}`)