@dnax/ui 0.0.27 → 0.0.29

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,237 @@
1
+ // v-touch-pan — directive : détecte les gestes « pan » (glisser) sur un
2
+ // élément, tactile ET souris (modifier .mouse), équivalent Quasar
3
+ // https://quasar.dev/vue-directives/touch-pan
4
+ //
5
+ // Usage : <div v-touch-pan.horizontal.mouse.prevent="onPan" />
6
+ // modifiers : horizontal | vertical | up | down | left | right (filtres de
7
+ // direction), mouse (inclut la souris), prevent (bloque le scroll natif),
8
+ // stop, capture, passive, mouseCapture
9
+ //
10
+ // Détails passés au handler (compatible Quasar) :
11
+ // { evt, position: { top, left }, direction, delta: { x, y },
12
+ // distance: { x, y }, duration, speed: { x, y },
13
+ // isFirst, isFinal, isVertical, isHorizontal }
14
+
15
+ export interface PanPosition {
16
+ top: number
17
+ left: number
18
+ }
19
+
20
+ export interface PanDelta {
21
+ x: number
22
+ y: number
23
+ }
24
+
25
+ export type PanDirection = "up" | "down" | "left" | "right"
26
+
27
+ export interface PanDetails {
28
+ evt: PointerEvent
29
+ position: PanPosition
30
+ direction: PanDirection
31
+ delta: PanDelta
32
+ distance: PanDelta
33
+ duration: number
34
+ speed: PanDelta
35
+ isFirst: boolean
36
+ isFinal: boolean
37
+ isVertical: boolean
38
+ isHorizontal: boolean
39
+ }
40
+
41
+ export type TouchPanHandler = (details: PanDetails) => void
42
+
43
+ interface PanState {
44
+ pointerId: number
45
+ startX: number
46
+ startY: number
47
+ lastX: number
48
+ lastY: number
49
+ startTime: number
50
+ lastTime: number
51
+ axis: "horizontal" | "vertical" | null
52
+ panning: boolean
53
+ }
54
+
55
+ const PAN_MIN = 4 // seuil avant de déclarer le pan (px)
56
+
57
+ interface TouchPanOptions {
58
+ handler: TouchPanHandler
59
+ allowHorizontal: boolean
60
+ allowVertical: boolean
61
+ allowUp: boolean
62
+ allowDown: boolean
63
+ allowLeft: boolean
64
+ allowRight: boolean
65
+ mouse: boolean
66
+ prevent: boolean
67
+ stop: boolean
68
+ capture: boolean
69
+ passive: boolean
70
+ mouseCapture: boolean
71
+ }
72
+
73
+ type QElement = HTMLElement & { __qTouchPanCleanup?: () => void }
74
+
75
+ function axisAllowed(options: TouchPanOptions, direction: PanDirection) {
76
+ if (options.allowHorizontal) return direction === "left" || direction === "right"
77
+ if (options.allowVertical) return direction === "up" || direction === "down"
78
+ switch (direction) {
79
+ case "up": return options.allowUp
80
+ case "down": return options.allowDown
81
+ case "left": return options.allowLeft
82
+ case "right": return options.allowRight
83
+ }
84
+ }
85
+
86
+ function parseDirection(dx: number, dy: number): PanDirection {
87
+ return Math.abs(dx) >= Math.abs(dy) ? (dx > 0 ? "right" : "left") : (dy > 0 ? "down" : "up")
88
+ }
89
+
90
+ function applyPrevent(e: Event, options: TouchPanOptions, active: boolean) {
91
+ if (options.stop) e.stopPropagation()
92
+ if (options.prevent && active) e.preventDefault()
93
+ }
94
+
95
+ export const vTouchPan = {
96
+ mounted(el: HTMLElement, binding: { value?: unknown; modifiers?: Record<string, boolean> }) {
97
+ const handler = binding.value
98
+ if (typeof handler !== "function") {
99
+ console.warn("[v-touch-pan] value doit être une fonction (handler)")
100
+ return
101
+ }
102
+ const m = binding.modifiers ?? {}
103
+ const options: TouchPanOptions = {
104
+ handler: handler as TouchPanHandler,
105
+ allowHorizontal: !!m.horizontal,
106
+ allowVertical: !!m.vertical,
107
+ allowUp: !!m.up,
108
+ allowDown: !!m.down,
109
+ allowLeft: !!m.left,
110
+ allowRight: !!m.right,
111
+ mouse: !!m.mouse || !!m.mouseCapture,
112
+ prevent: !!m.prevent,
113
+ stop: !!m.stop,
114
+ capture: !!m.capture || !!m.mouseCapture,
115
+ passive: !!m.passive,
116
+ mouseCapture: false,
117
+ }
118
+ options.mouseCapture = !!m.mouseCapture
119
+
120
+ let state: PanState | null = null
121
+
122
+ // touch-action : laisser le scroll natif quand on ne capture qu'un axe
123
+ if (options.prevent) el.style.touchAction = "none"
124
+ else if (options.allowHorizontal && !options.allowVertical) el.style.touchAction = "pan-y"
125
+ else if (options.allowVertical && !options.allowHorizontal) el.style.touchAction = "pan-x"
126
+ else el.style.touchAction = options.allowUp || options.allowDown || options.allowLeft || options.allowRight ? "pan-y pan-x" : "auto"
127
+
128
+ const onPointerDown = (e: PointerEvent) => {
129
+ if (state) return
130
+ if (e.pointerType === "mouse" && !options.mouse) return
131
+ applyPrevent(e, options, false)
132
+ state = {
133
+ pointerId: e.pointerId,
134
+ startX: e.clientX,
135
+ startY: e.clientY,
136
+ lastX: e.clientX,
137
+ lastY: e.clientY,
138
+ startTime: performance.now(),
139
+ lastTime: performance.now(),
140
+ axis: null,
141
+ panning: false,
142
+ }
143
+ try { (e.currentTarget as Element).setPointerCapture?.(e.pointerId) } catch { /* ignore */ }
144
+ }
145
+
146
+ const onPointerMove = (e: PointerEvent) => {
147
+ if (!state || state.pointerId !== e.pointerId) return
148
+ const dx = e.clientX - state.startX
149
+ const dy = e.clientY - state.startY
150
+ const deltaX = e.clientX - state.lastX
151
+ const deltaY = e.clientY - state.lastY
152
+ const now = performance.now()
153
+ const duration = now - state.startTime
154
+
155
+ if (!state.panning) {
156
+ if (Math.abs(dx) < PAN_MIN && Math.abs(dy) < PAN_MIN) return
157
+ const direction = parseDirection(dx, dy)
158
+ if (!axisAllowed(options, direction)) return
159
+ state.axis = direction === "left" || direction === "right" ? "horizontal" : "vertical"
160
+ state.panning = true
161
+ applyPrevent(e, options, true)
162
+ state.lastX = e.clientX
163
+ state.lastY = e.clientY
164
+ state.lastTime = now
165
+ emit(state, e, direction, { x: 0, y: 0 }, { x: dx, y: dy }, duration, true)
166
+ return
167
+ }
168
+
169
+ const direction = state.axis === "horizontal" ? (dx > 0 ? "right" : "left") : (dy > 0 ? "down" : "up")
170
+ applyPrevent(e, options, true)
171
+ state.lastX = e.clientX
172
+ state.lastY = e.clientY
173
+ state.lastTime = now
174
+ emit(state, e, direction, { x: deltaX, y: deltaY }, { x: dx, y: dy }, duration, false)
175
+ }
176
+
177
+ const onPointerEnd = (e: PointerEvent) => {
178
+ if (!state || state.pointerId !== e.pointerId) return
179
+ const dx = e.clientX - state.startX
180
+ const dy = e.clientY - state.startY
181
+ const duration = performance.now() - state.startTime
182
+ if (state.panning) {
183
+ const direction = state.axis === "horizontal" ? (dx > 0 ? "right" : "left") : (dy > 0 ? "down" : "up")
184
+ emit(state, e, direction, { x: 0, y: 0 }, { x: dx, y: dy }, duration, false, true)
185
+ }
186
+ state = null
187
+ }
188
+
189
+ const onPointerCancel = (e: PointerEvent) => {
190
+ if (state && state.pointerId === e.pointerId) state = null
191
+ }
192
+
193
+ const emit = (
194
+ s: PanState,
195
+ evt: PointerEvent,
196
+ direction: PanDirection,
197
+ delta: PanDelta,
198
+ distance: PanDelta,
199
+ duration: number,
200
+ isFirst: boolean,
201
+ isFinal = false,
202
+ ) => {
203
+ const elapsed = Math.max(duration, 1)
204
+ options.handler({
205
+ evt,
206
+ position: { top: evt.clientY, left: evt.clientX },
207
+ direction,
208
+ delta,
209
+ distance,
210
+ duration,
211
+ speed: { x: Math.abs(distance.x) / elapsed * 1000, y: Math.abs(distance.y) / elapsed * 1000 },
212
+ isFirst,
213
+ isFinal,
214
+ isVertical: s.axis === "vertical",
215
+ isHorizontal: s.axis === "horizontal",
216
+ })
217
+ }
218
+
219
+ const capture = options.capture
220
+ el.addEventListener("pointerdown", onPointerDown, { capture, passive: options.passive })
221
+ el.addEventListener("pointermove", onPointerMove, { capture, passive: options.passive })
222
+ el.addEventListener("pointerup", onPointerEnd, { capture })
223
+ el.addEventListener("pointercancel", onPointerCancel, { capture })
224
+
225
+ ;(el as QElement).__qTouchPanCleanup = () => {
226
+ el.removeEventListener("pointerdown", onPointerDown, { capture } as any)
227
+ el.removeEventListener("pointermove", onPointerMove, { capture } as any)
228
+ el.removeEventListener("pointerup", onPointerEnd, { capture } as any)
229
+ el.removeEventListener("pointercancel", onPointerCancel, { capture } as any)
230
+ el.style.touchAction = ""
231
+ }
232
+ },
233
+ unmounted(el: HTMLElement) {
234
+ ;(el as QElement).__qTouchPanCleanup?.()
235
+ delete (el as QElement).__qTouchPanCleanup
236
+ },
237
+ }
@@ -0,0 +1,148 @@
1
+ // v-touch-repeat — directive : déclenche un handler en boucle tant que
2
+ // l'élément est pressé (appui long répété), équivalent Quasar
3
+ // https://quasar.dev/vue-directives/touch-repeat
4
+ //
5
+ // Usage :
6
+ // <button v-touch-repeat.mouse="onRepeat">…</button>
7
+ // <button v-touch-repeat.mouse="{ delay: 500, interval: 100 }">…</button>
8
+ // <button v-touch-repeat.mouse="'500:100'">…</button>
9
+ // modifiers : mouse (inclut la souris), capture / mouseCapture, stop, prevent,
10
+ // passive
11
+ //
12
+ // Détails du handler : { evt, count, elapsed }
13
+
14
+ export interface TouchRepeatDetails {
15
+ evt: Event
16
+ /** Nombre d'appels (1 = premier, après le délai) */
17
+ count: number
18
+ /** Temps écoulé depuis le pointerdown (ms) */
19
+ elapsed: number
20
+ }
21
+
22
+ export type TouchRepeatHandler = (details: TouchRepeatDetails) => void
23
+
24
+ const DEFAULTS = { delay: 600, interval: 150 }
25
+
26
+ interface RepeatOptions {
27
+ handler: TouchRepeatHandler
28
+ delay: number
29
+ interval: number
30
+ mouse: boolean
31
+ stop: boolean
32
+ prevent: boolean
33
+ capture: boolean
34
+ passive: boolean
35
+ }
36
+
37
+ type QElement = HTMLElement & { __qTouchRepeatCleanup?: () => void }
38
+
39
+ function parseValue(value: unknown): { delay?: number; interval?: number } {
40
+ if (typeof value === "number") return { interval: value }
41
+ if (typeof value === "string") {
42
+ const [delay, interval] = value.split(":")
43
+ const out: { delay?: number; interval?: number } = {}
44
+ const d = Number(delay)
45
+ if (Number.isFinite(d)) out.delay = d
46
+ const i = Number(interval)
47
+ if (Number.isFinite(i)) out.interval = i
48
+ return out
49
+ }
50
+ if (value && typeof value === "object") {
51
+ const o = value as Record<string, unknown>
52
+ const out: { delay?: number; interval?: number } = {}
53
+ const d = Number(o.delay)
54
+ if (Number.isFinite(d)) out.delay = d
55
+ const i = Number(o.interval)
56
+ if (Number.isFinite(i)) out.interval = i
57
+ return out
58
+ }
59
+ return {}
60
+ }
61
+
62
+ export const vTouchRepeat = {
63
+ mounted(el: HTMLElement, binding: { value?: unknown; modifiers?: Record<string, boolean> }) {
64
+ const handler = binding.value
65
+ if (typeof handler !== "function") {
66
+ console.warn("[v-touch-repeat] value doit être une fonction (handler)")
67
+ return
68
+ }
69
+ const m = binding.modifiers ?? {}
70
+ const parsed = parseValue(binding.value)
71
+ const options: RepeatOptions = {
72
+ handler: handler as TouchRepeatHandler,
73
+ delay: parsed.delay ?? DEFAULTS.delay,
74
+ interval: parsed.interval ?? DEFAULTS.interval,
75
+ mouse: !!m.mouse || !!m.mouseCapture,
76
+ stop: !!m.stop,
77
+ prevent: !!m.prevent,
78
+ capture: !!m.capture || !!m.mouseCapture,
79
+ passive: !!m.passive,
80
+ }
81
+
82
+ el.style.touchAction = "none"
83
+
84
+ let active = false
85
+ let count = 0
86
+ let startTime = 0
87
+ let timer: ReturnType<typeof setTimeout> | undefined
88
+ let intervalTimer: ReturnType<typeof setInterval> | undefined
89
+
90
+ const stop = () => {
91
+ active = false
92
+ if (timer) clearTimeout(timer)
93
+ if (intervalTimer) clearInterval(intervalTimer)
94
+ timer = undefined
95
+ intervalTimer = undefined
96
+ }
97
+
98
+ const tick = () => {
99
+ count++
100
+ options.handler({
101
+ evt: lastEvt ?? new Event("touch-repeat"),
102
+ count,
103
+ elapsed: Math.round(performance.now() - startTime),
104
+ })
105
+ }
106
+
107
+ let lastEvt: Event | null = null
108
+
109
+ const onPointerDown = (e: PointerEvent) => {
110
+ if (active) return
111
+ if (e.pointerType === "mouse" && !options.mouse) return
112
+ if (options.prevent && !options.passive) e.preventDefault()
113
+ if (options.stop) e.stopPropagation()
114
+ active = true
115
+ count = 0
116
+ startTime = performance.now()
117
+ lastEvt = e
118
+ timer = setTimeout(() => {
119
+ tick()
120
+ intervalTimer = setInterval(tick, options.interval)
121
+ }, options.delay)
122
+ }
123
+
124
+ const onPointerUp = (e: PointerEvent) => {
125
+ lastEvt = e
126
+ stop()
127
+ }
128
+
129
+ const capture = options.capture
130
+ el.addEventListener("pointerdown", onPointerDown, { capture, passive: options.passive })
131
+ el.addEventListener("pointerup", onPointerUp, { capture })
132
+ el.addEventListener("pointercancel", onPointerUp, { capture })
133
+ el.addEventListener("pointerleave", onPointerUp, { capture })
134
+
135
+ ;(el as QElement).__qTouchRepeatCleanup = () => {
136
+ el.removeEventListener("pointerdown", onPointerDown, { capture } as any)
137
+ el.removeEventListener("pointerup", onPointerUp, { capture } as any)
138
+ el.removeEventListener("pointercancel", onPointerUp, { capture } as any)
139
+ el.removeEventListener("pointerleave", onPointerUp, { capture } as any)
140
+ stop()
141
+ el.style.touchAction = ""
142
+ }
143
+ },
144
+ unmounted(el: HTMLElement) {
145
+ ;(el as QElement).__qTouchRepeatCleanup?.()
146
+ delete (el as QElement).__qTouchRepeatCleanup
147
+ },
148
+ }
@@ -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
+ }
@@ -1,6 +1,7 @@
1
1
  import { computed, inject, toValue } from "vue"
2
2
  import type { ComputedRef, MaybeRefOrGetter } from "vue"
3
3
  import { qConfigKey } from "./config"
4
+ import type { QAppLang } from "./config"
4
5
 
5
6
  /** Échelle de rayon : none (carré) → lg (très arrondi) */
6
7
  export type RadiusScale = "none" | "xs" | "sm" | "md" | "lg"
@@ -19,6 +20,12 @@ export const RADIUS_VALUES: Record<RadiusScale, string> = {
19
20
  export const isRadiusScale = (v: unknown): v is RadiusScale =>
20
21
  v === "none" || v === "xs" || v === "sm" || v === "md" || v === "lg"
21
22
 
23
+ /** Langue d'application fournie par QConfigProvider ("en" par défaut). */
24
+ export function useConfigLang(): ComputedRef<QAppLang> {
25
+ const config = inject(qConfigKey, null)
26
+ return computed(() => config?.lang.value ?? "en")
27
+ }
28
+
22
29
  /**
23
30
  * Props par défaut d'un composant depuis `theme.componentProps` :
24
31
  * `default` (appliqué à tous) puis `<Nom>` (spécifique, prioritaire).
package/module.ts CHANGED
@@ -93,9 +93,19 @@ 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"
100
+ import { vIntersection } from "@dnax/ui/runtime"
96
101
 
97
102
  export default defineNuxtPlugin((nuxtApp) => {
98
103
  nuxtApp.vueApp.directive("close", vClose)
104
+ nuxtApp.vueApp.directive("touch-pan", vTouchPan)
105
+ nuxtApp.vueApp.directive("touch-hold", vTouchHold)
106
+ nuxtApp.vueApp.directive("touch-swipe", vTouchSwipe)
107
+ nuxtApp.vueApp.directive("touch-repeat", vTouchRepeat)
108
+ nuxtApp.vueApp.directive("intersection", vIntersection)
99
109
  })
100
110
  `,
101
111
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dnax/ui",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "module": "index.ts",
5
5
  "description": "UI design System",
6
6
  "type": "module",
@@ -22,15 +22,41 @@
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",
53
+ "arktype": "^2.2.3",
29
54
  "class-variance-authority": "^0.7.1",
30
55
  "clsx": "^2.1.1",
31
56
  "embla-carousel": "^8.5.0",
32
57
  "embla-carousel-vue": "^8.5.0",
33
58
  "fuse.js": "^7.1.0",
59
+ "moment": "^2.30.1",
34
60
  "shiki": "^3.0.0",
35
61
  "swiper": "^14.2.0",
36
62
  "tailwind-merge": "^3.6.0",
@@ -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,16 @@ 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"
65
+ export { vIntersection } from "./lib/intersection"
66
+ export type { IntersectionValue } from "./lib/intersection"
55
67
  `
56
68
 
57
69
  await Bun.write(indexFile, `${exports}\n${manualExports}`)