@maz-ui/mcp 5.0.0-beta.5 → 5.0.0-beta.51
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 +1 -1
- package/dist/mcp.d.mts +22 -9
- package/dist/mcp.d.ts +22 -9
- package/dist/mcp.mjs +160 -83
- package/docs/generated-docs/maz-avatar.doc.md +30 -30
- package/docs/generated-docs/maz-bottom-sheet.doc.md +16 -13
- package/docs/generated-docs/maz-btn.doc.md +21 -19
- package/docs/generated-docs/maz-checkbox.doc.md +16 -17
- package/docs/generated-docs/maz-circular-progress-bar.doc.md +1 -1
- package/docs/generated-docs/maz-code-highlight.doc.md +11 -0
- package/docs/generated-docs/maz-container.doc.md +1 -0
- package/docs/generated-docs/maz-date-picker.doc.md +41 -41
- package/docs/generated-docs/maz-drawer.doc.md +7 -8
- package/docs/generated-docs/maz-dropdown.doc.md +3 -0
- package/docs/generated-docs/maz-expand-animation.doc.md +4 -4
- package/docs/generated-docs/maz-fullscreen-loader.doc.md +5 -5
- package/docs/generated-docs/maz-gallery.doc.md +15 -15
- package/docs/generated-docs/maz-input-code.doc.md +16 -16
- package/docs/generated-docs/maz-input-phone-number.doc.md +43 -42
- package/docs/generated-docs/maz-input-price.doc.md +14 -14
- package/docs/generated-docs/maz-input-tags.doc.md +16 -16
- package/docs/generated-docs/maz-input.doc.md +33 -33
- package/docs/generated-docs/maz-lazy-img.doc.md +14 -14
- package/docs/generated-docs/maz-loading-bar.doc.md +4 -4
- package/docs/generated-docs/maz-markdown-editor.doc.md +65 -0
- package/docs/generated-docs/maz-popover.doc.md +1 -1
- package/docs/generated-docs/maz-pull-to-refresh.doc.md +39 -20
- package/docs/generated-docs/maz-radio-buttons.doc.md +17 -17
- package/docs/generated-docs/maz-radio.doc.md +16 -16
- package/docs/generated-docs/maz-reading-progress-bar.doc.md +4 -4
- package/docs/generated-docs/maz-select-country.doc.md +27 -26
- package/docs/generated-docs/maz-sidebar-content.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar-footer.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar-group.doc.md +11 -0
- package/docs/generated-docs/maz-sidebar-header.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar-menu-button.doc.md +27 -0
- package/docs/generated-docs/maz-sidebar-menu-item.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +16 -0
- package/docs/generated-docs/maz-sidebar-menu.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
- package/docs/generated-docs/maz-sidebar-trigger.doc.md +5 -0
- package/docs/generated-docs/maz-sidebar.doc.md +36 -0
- package/docs/generated-docs/maz-slider.doc.md +1 -1
- package/docs/generated-docs/maz-spinner.doc.md +4 -4
- package/docs/generated-docs/maz-switch.doc.md +14 -14
- package/docs/generated-docs/maz-table-virtualizer.doc.md +20 -0
- package/docs/generated-docs/maz-table.doc.md +43 -37
- package/docs/generated-docs/maz-tabs-bar.doc.md +20 -9
- package/docs/generated-docs/maz-tabs.doc.md +6 -3
- package/docs/generated-docs/maz-textarea.doc.md +27 -25
- package/docs/generated-docs/maz-ticker.doc.md +1 -1
- package/docs/generated-docs/maz-timeline.doc.md +4 -4
- package/docs/generated-docs/maz-window-mockup.doc.md +23 -0
- package/docs/src/blog/v4.md +1 -1
- package/docs/src/blog/v5.md +5 -7
- package/docs/src/components/maz-avatar.md +52 -4
- package/docs/src/components/maz-bottom-sheet.md +300 -169
- package/docs/src/components/maz-btn.md +1 -1
- package/docs/src/components/maz-checklist.md +10 -10
- package/docs/src/components/maz-code-highlight.md +233 -0
- package/docs/src/components/maz-date-picker.md +55 -1
- package/docs/src/components/maz-dialog.md +46 -0
- package/docs/src/components/maz-dropdown.md +32 -16
- package/docs/src/components/maz-icon.md +16 -5
- package/docs/src/components/maz-input-phone-number.md +30 -0
- package/docs/src/components/maz-lazy-img.md +64 -0
- package/docs/src/components/maz-markdown-editor.md +369 -0
- package/docs/src/components/maz-pull-to-refresh.md +176 -17
- package/docs/src/components/maz-select-country.md +138 -1
- package/docs/src/components/maz-sidebar.md +719 -0
- package/docs/src/components/maz-table.md +156 -1
- package/docs/src/components/maz-tabs.md +110 -3
- package/docs/src/components/maz-textarea.md +58 -0
- package/docs/src/components/maz-timeline.md +60 -0
- package/docs/src/components/maz-window-mockup.md +249 -0
- package/docs/src/composables/use-drag.md +239 -0
- package/docs/src/composables/use-form-validator.md +297 -16
- package/docs/src/composables/use-pull-to-refresh.md +79 -0
- package/docs/src/composables/use-swipe.md +26 -11
- package/docs/src/directives/click-outside.md +8 -15
- package/docs/src/directives/fullscreen-img.md +1 -1
- package/docs/src/directives/lazy-img.md +44 -11
- package/docs/src/directives/tooltip.md +24 -1
- package/docs/src/directives/zoom-img.md +1 -1
- package/docs/src/ecosystem/eslint-config.md +95 -1
- package/docs/src/{guide/icons.md → ecosystem/icons/index.md} +1 -1
- package/docs/src/ecosystem/node/exec-promise.md +87 -0
- package/docs/src/ecosystem/node/index.md +53 -0
- package/docs/src/ecosystem/node/logger.md +146 -0
- package/docs/src/ecosystem/node/print-banner.md +93 -0
- package/docs/src/{guide → ecosystem}/nuxt.md +102 -47
- package/docs/src/{guide → ecosystem}/themes.md +152 -71
- package/docs/src/{guide → ecosystem}/translations.md +1 -1
- package/docs/src/ecosystem/utils/camel-case.md +31 -0
- package/docs/src/{helpers → ecosystem/utils}/capitalize.md +2 -3
- package/docs/src/ecosystem/utils/check-availability.md +79 -0
- package/docs/src/ecosystem/utils/cookie.md +80 -0
- package/docs/src/ecosystem/utils/debounce-callback.md +38 -0
- package/docs/src/ecosystem/utils/debounce-id.md +69 -0
- package/docs/src/ecosystem/utils/debounce.md +65 -0
- package/docs/src/ecosystem/utils/fetch-locale-ip.md +33 -0
- package/docs/src/ecosystem/utils/format-json.md +33 -0
- package/docs/src/ecosystem/utils/format-phone-number.md +37 -0
- package/docs/src/ecosystem/utils/get-browser-locale.md +29 -0
- package/docs/src/ecosystem/utils/get-error-message.md +39 -0
- package/docs/src/ecosystem/utils/idle-timeout.md +90 -0
- package/docs/src/ecosystem/utils/index.md +60 -0
- package/docs/src/ecosystem/utils/is-client.md +32 -0
- package/docs/src/ecosystem/utils/is-equal.md +38 -0
- package/docs/src/ecosystem/utils/is-server.md +31 -0
- package/docs/src/ecosystem/utils/is-standalone-mode.md +43 -0
- package/docs/src/ecosystem/utils/kebab-case.md +36 -0
- package/docs/src/ecosystem/utils/normalize-string.md +77 -0
- package/docs/src/ecosystem/utils/pascal-case.md +35 -0
- package/docs/src/ecosystem/utils/script-loader.md +77 -0
- package/docs/src/ecosystem/utils/sleep.md +59 -0
- package/docs/src/ecosystem/utils/snake-case.md +36 -0
- package/docs/src/ecosystem/utils/swipe-handler.md +91 -0
- package/docs/src/ecosystem/utils/textarea-autogrow.md +41 -0
- package/docs/src/ecosystem/utils/throttle-id.md +48 -0
- package/docs/src/ecosystem/utils/throttle.md +57 -0
- package/docs/src/ecosystem/utils/truthy-filter.md +31 -0
- package/docs/src/ecosystem/utils/types/deep-key-of.md +48 -0
- package/docs/src/ecosystem/utils/types/deep-partial.md +42 -0
- package/docs/src/ecosystem/utils/types/deep-required.md +39 -0
- package/docs/src/ecosystem/utils/types/flatten-object-keys.md +44 -0
- package/docs/src/ecosystem/utils/types/generic-instance-type.md +42 -0
- package/docs/src/ecosystem/utils/types/infer-maybe-ref.md +35 -0
- package/docs/src/ecosystem/utils/upper-first.md +32 -0
- package/docs/src/ecosystem/utils/user-visibility.md +69 -0
- package/docs/src/guide/getting-started.md +15 -13
- package/docs/src/guide/global-defaults.md +102 -0
- package/docs/src/guide/maz-ui-provider.md +6 -3
- package/docs/src/guide/migration-v4.md +13 -9
- package/docs/src/guide/migration-v5.md +211 -15
- package/docs/src/guide/resolvers.md +8 -8
- package/docs/src/guide/tailwind.md +4 -0
- package/docs/src/guide/vue.md +4 -4
- package/docs/src/index.md +13 -13
- package/docs/src/plugins/aos.md +1 -1
- package/package.json +11 -10
- package/docs/src/helpers/camel-case.md +0 -14
- package/docs/src/helpers/check-availability.md +0 -14
- package/docs/src/helpers/debounce-callback.md +0 -14
- package/docs/src/helpers/debounce-id.md +0 -14
- package/docs/src/helpers/debounce.md +0 -14
- package/docs/src/helpers/is-client.md +0 -14
- package/docs/src/helpers/is-equal.md +0 -14
- package/docs/src/helpers/is-standalone-mode.md +0 -14
- package/docs/src/helpers/kebab-case.md +0 -14
- package/docs/src/helpers/normalize-string.md +0 -14
- package/docs/src/helpers/pascal-case.md +0 -14
- package/docs/src/helpers/script-loader.md +0 -14
- package/docs/src/helpers/sleep.md +0 -14
- package/docs/src/helpers/snake-case.md +0 -14
- package/docs/src/helpers/throttle-id.md +0 -14
- package/docs/src/helpers/throttle.md +0 -14
- /package/docs/src/{guide → ecosystem/icons}/icon-set.md +0 -0
- /package/docs/src/{guide → ecosystem}/mcp.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/country-code-to-unicode-flag.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/currency.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/date.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/get-country-flag-url.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/number.md +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: MazWindowMockup
|
|
3
|
+
description: MazWindowMockup renders a macOS-style window frame in three variants — browser, terminal, and editor — to showcase content, demos, or code examples in your documentation or UI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{ $frontmatter.title }}
|
|
7
|
+
|
|
8
|
+
{{ $frontmatter.description }}
|
|
9
|
+
|
|
10
|
+
<!--@include: ./../../.vitepress/mixins/getting-started.md-->
|
|
11
|
+
|
|
12
|
+
::: info Optional: shiki for code variants
|
|
13
|
+
When you pass the `code` prop, `MazWindowMockup` mounts `MazCodeHighlight` internally for syntax highlighting. This requires the [`shiki`](https://shiki.style) optional peer dependency to be installed. See the [MazCodeHighlight installation note](/components/maz-code-highlight#installation-requirement).
|
|
14
|
+
:::
|
|
15
|
+
|
|
16
|
+
## Browser variant
|
|
17
|
+
|
|
18
|
+
The default variant. Displays an address bar with the `url` prop and a copy-URL button on the right side of the bar.
|
|
19
|
+
|
|
20
|
+
<ComponentDemo>
|
|
21
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="100px">
|
|
22
|
+
<div style="padding: 1rem; text-align: center;">Browser content goes here</div>
|
|
23
|
+
</MazWindowMockup>
|
|
24
|
+
|
|
25
|
+
<template #code>
|
|
26
|
+
|
|
27
|
+
```vue
|
|
28
|
+
<template>
|
|
29
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="100px">
|
|
30
|
+
<div>Browser content goes here</div>
|
|
31
|
+
</MazWindowMockup>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script lang="ts" setup>
|
|
35
|
+
import MazWindowMockup from 'maz-ui/components/MazWindowMockup'
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
</template>
|
|
40
|
+
</ComponentDemo>
|
|
41
|
+
|
|
42
|
+
### Hide the URL copy button
|
|
43
|
+
|
|
44
|
+
Set `:hide-url-copy="true"` to remove the copy-URL button from the title bar.
|
|
45
|
+
|
|
46
|
+
<ComponentDemo>
|
|
47
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="80px" :hide-url-copy="true" />
|
|
48
|
+
|
|
49
|
+
<template #code>
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<template>
|
|
53
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="80px" :hide-url-copy="true" />
|
|
54
|
+
</template>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
</template>
|
|
58
|
+
</ComponentDemo>
|
|
59
|
+
|
|
60
|
+
### With screenshot
|
|
61
|
+
|
|
62
|
+
Use this variant to display a screenshot of a website.
|
|
63
|
+
|
|
64
|
+
<ComponentDemo>
|
|
65
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="100px">
|
|
66
|
+
<img :src="screenshot" alt="Maz UI Demo Dashboard" width="100%">
|
|
67
|
+
</MazWindowMockup>
|
|
68
|
+
|
|
69
|
+
<template #code>
|
|
70
|
+
|
|
71
|
+
```vue
|
|
72
|
+
<template>
|
|
73
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="100px">
|
|
74
|
+
<img src="/img/screenshots/maz-ui-home-desktop.webp" alt="Maz UI Demo Dashboard" width="100%">
|
|
75
|
+
</MazWindowMockup>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script lang="ts" setup>
|
|
79
|
+
import MazWindowMockup from 'maz-ui/components/MazWindowMockup'
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
</template>
|
|
84
|
+
</ComponentDemo>
|
|
85
|
+
|
|
86
|
+
## Terminal variant
|
|
87
|
+
|
|
88
|
+
Displays a centered title and a `$` prompt prefix in front of the code (when `code` is provided). The prompt prefix is **not** copied to the clipboard — the copy button only writes the raw `code` value.
|
|
89
|
+
|
|
90
|
+
<ComponentDemo>
|
|
91
|
+
<MazWindowMockup variant="terminal" title="zsh" code="pnpm add maz-ui" language="bash" />
|
|
92
|
+
|
|
93
|
+
<template #code>
|
|
94
|
+
|
|
95
|
+
```vue
|
|
96
|
+
<template>
|
|
97
|
+
<MazWindowMockup variant="terminal" title="zsh" code="pnpm add maz-ui" language="bash" />
|
|
98
|
+
</template>
|
|
99
|
+
|
|
100
|
+
<script lang="ts" setup>
|
|
101
|
+
import MazWindowMockup from 'maz-ui/components/MazWindowMockup'
|
|
102
|
+
</script>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
</template>
|
|
106
|
+
</ComponentDemo>
|
|
107
|
+
|
|
108
|
+
### Custom prompt
|
|
109
|
+
|
|
110
|
+
Replace the default `$` with any character via the `prompt` prop.
|
|
111
|
+
|
|
112
|
+
<ComponentDemo>
|
|
113
|
+
<MazWindowMockup variant="terminal" code="git status" language="bash" prompt="❯" />
|
|
114
|
+
|
|
115
|
+
<template #code>
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<template>
|
|
119
|
+
<MazWindowMockup variant="terminal" code="git status" language="bash" prompt="❯" />
|
|
120
|
+
</template>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
</template>
|
|
124
|
+
</ComponentDemo>
|
|
125
|
+
|
|
126
|
+
### Without prompt
|
|
127
|
+
|
|
128
|
+
Hide the default prompt by setting `hide-prompt` to `true`.
|
|
129
|
+
|
|
130
|
+
<ComponentDemo>
|
|
131
|
+
<MazWindowMockup variant="terminal" code="git status" language="bash" :hide-prompt="true" />
|
|
132
|
+
|
|
133
|
+
<template #code>
|
|
134
|
+
|
|
135
|
+
```vue
|
|
136
|
+
<template>
|
|
137
|
+
<MazWindowMockup variant="terminal" code="git status" language="bash" :hide-prompt="true" />
|
|
138
|
+
</template>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
</template>
|
|
142
|
+
</ComponentDemo>
|
|
143
|
+
|
|
144
|
+
## Editor variant
|
|
145
|
+
|
|
146
|
+
Shows a filename tab anchored to the bottom of the title bar — matching the look of real editors like VSCode.
|
|
147
|
+
|
|
148
|
+
<ComponentDemo>
|
|
149
|
+
<MazWindowMockup variant="editor" filename="App.vue" :code="vueCode" language="vue" />
|
|
150
|
+
|
|
151
|
+
<template #code>
|
|
152
|
+
|
|
153
|
+
```vue
|
|
154
|
+
<template>
|
|
155
|
+
<MazWindowMockup variant="editor" filename="App.vue" :code="vueCode" language="vue" />
|
|
156
|
+
</template>
|
|
157
|
+
|
|
158
|
+
<script lang="ts" setup>
|
|
159
|
+
import MazWindowMockup from 'maz-ui/components/MazWindowMockup'
|
|
160
|
+
|
|
161
|
+
const vueCode = `<template>
|
|
162
|
+
<MazBtn>Click me</MazBtn>
|
|
163
|
+
</template>`
|
|
164
|
+
</script>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
</template>
|
|
168
|
+
</ComponentDemo>
|
|
169
|
+
|
|
170
|
+
## With code and language props
|
|
171
|
+
|
|
172
|
+
Pass `code` and `language` to display highlighted source code via `MazCodeHighlight`. The inner highlighter automatically renders with squared corners so it sits flush against the window's border.
|
|
173
|
+
|
|
174
|
+
<ComponentDemo>
|
|
175
|
+
<MazWindowMockup code="import MazBtn from 'maz-ui/components/MazBtn'" language="ts" />
|
|
176
|
+
|
|
177
|
+
<template #code>
|
|
178
|
+
|
|
179
|
+
```vue
|
|
180
|
+
<template>
|
|
181
|
+
<MazWindowMockup code="import MazBtn from 'maz-ui/components/MazBtn'" language="ts" />
|
|
182
|
+
</template>
|
|
183
|
+
|
|
184
|
+
<script lang="ts" setup>
|
|
185
|
+
import MazWindowMockup from 'maz-ui/components/MazWindowMockup'
|
|
186
|
+
</script>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
</template>
|
|
190
|
+
</ComponentDemo>
|
|
191
|
+
|
|
192
|
+
## Empty-state placeholder
|
|
193
|
+
|
|
194
|
+
When neither `code` nor a slot content is provided, the content area renders an empty placeholder. Pass the optional `label` prop to display a centered text inside it.
|
|
195
|
+
|
|
196
|
+
<ComponentDemo>
|
|
197
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="160px" label="Preview" />
|
|
198
|
+
|
|
199
|
+
<template #code>
|
|
200
|
+
|
|
201
|
+
```vue
|
|
202
|
+
<template>
|
|
203
|
+
<MazWindowMockup url="https://maz-ui.com" min-height="160px" label="Preview" />
|
|
204
|
+
</template>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
</template>
|
|
208
|
+
</ComponentDemo>
|
|
209
|
+
|
|
210
|
+
## Custom translations
|
|
211
|
+
|
|
212
|
+
The URL copy button's aria-label and tooltip come from the `@maz-ui/translations` package (`windowMockup.copyUrlToClipboard` / `windowMockup.urlCopiedToClipboard`). Override per-instance with the `translations` prop:
|
|
213
|
+
|
|
214
|
+
<ComponentDemo>
|
|
215
|
+
<MazWindowMockup
|
|
216
|
+
url="https://maz-ui.com"
|
|
217
|
+
min-height="80px"
|
|
218
|
+
:translations="{ copyUrlToClipboard: 'Copier l\'URL', urlCopiedToClipboard: 'URL copiée !' }"
|
|
219
|
+
/>
|
|
220
|
+
|
|
221
|
+
<template #code>
|
|
222
|
+
|
|
223
|
+
```vue
|
|
224
|
+
<template>
|
|
225
|
+
<MazWindowMockup
|
|
226
|
+
url="https://maz-ui.com"
|
|
227
|
+
min-height="80px"
|
|
228
|
+
:translations="{
|
|
229
|
+
copyUrlToClipboard: 'Copier l\'URL',
|
|
230
|
+
urlCopiedToClipboard: 'URL copiée !',
|
|
231
|
+
}"
|
|
232
|
+
/>
|
|
233
|
+
</template>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
</template>
|
|
237
|
+
</ComponentDemo>
|
|
238
|
+
|
|
239
|
+
For app-wide translations, set up the [maz-ui translations plugin](/translations) and the component will pick up your locale automatically.
|
|
240
|
+
|
|
241
|
+
<script lang="ts" setup>
|
|
242
|
+
import screenshot from './../assets/interface-screenshot.png'
|
|
243
|
+
|
|
244
|
+
const vueCode = `<template>
|
|
245
|
+
<MazBtn>Click me</MazBtn>
|
|
246
|
+
</template>`
|
|
247
|
+
</script>
|
|
248
|
+
|
|
249
|
+
<!--@include: ./../../.vitepress/generated-docs/maz-window-mockup.doc.md-->
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useDrag
|
|
3
|
+
description: useDrag is a Vue composable that tracks a pointer drag gesture (touch, mouse and pen) in real time, exposing the live offset, distance and direction.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{ $frontmatter.title }}
|
|
7
|
+
|
|
8
|
+
{{ $frontmatter.description }}
|
|
9
|
+
|
|
10
|
+
## Introduction
|
|
11
|
+
|
|
12
|
+
`useDrag` follows a pointer drag on an element and gives you the **live** offset, distance and direction, plus `onStart` / `onMove` / `onEnd` callbacks. It is the low-level gesture primitive behind components like [MazBottomSheet](../components/maz-bottom-sheet.md) (drag-to-dismiss), and it's useful to build sliders, sortable handles, swipeable cards, bottom sheets, custom carousels, etc.
|
|
13
|
+
|
|
14
|
+
It is built on top of [Pointer Events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events), so it works with **touch, mouse and pen**.
|
|
15
|
+
|
|
16
|
+
::: tip
|
|
17
|
+
For discrete directional swipe detection (left / right / up / down with a threshold) rather than real-time tracking, use [useSwipe](./use-swipe.md).
|
|
18
|
+
:::
|
|
19
|
+
|
|
20
|
+
## Key Features
|
|
21
|
+
|
|
22
|
+
- Real-time pointer tracking (touch, mouse and pen)
|
|
23
|
+
- Live reactive state: `isDragging`, `offsetX`, `offsetY`, `distance`, `direction`
|
|
24
|
+
- `onStart` / `onMove` / `onEnd` callbacks with a full state snapshot
|
|
25
|
+
- Axis locking (`x`, `y` or `both`)
|
|
26
|
+
- Activation threshold, pointer-type filtering and reactive `disabled`
|
|
27
|
+
- Listeners are followed on the document, so the drag keeps working when the pointer leaves the element
|
|
28
|
+
- Automatically attaches/detaches when the target appears/disappears, and cleans up on unmount
|
|
29
|
+
|
|
30
|
+
## Basic Usage
|
|
31
|
+
|
|
32
|
+
Drag the card down: it follows your pointer and snaps back on release.
|
|
33
|
+
|
|
34
|
+
<div class="drag-demo">
|
|
35
|
+
<div
|
|
36
|
+
ref="dragHandle"
|
|
37
|
+
class="drag-card"
|
|
38
|
+
:class="{ '--dragging': dragging }"
|
|
39
|
+
:style="{ transform: dragOffset ? `translateY(${dragOffset}px)` : undefined }"
|
|
40
|
+
>
|
|
41
|
+
{{ dragging ? `Dragging — ${Math.round(dragOffset)}px ${dragDirection ?? ''}` : 'Drag me down' }}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
```vue
|
|
46
|
+
<script lang="ts" setup>
|
|
47
|
+
import { useDrag } from 'maz-ui/composables'
|
|
48
|
+
import { ref } from 'vue'
|
|
49
|
+
|
|
50
|
+
const dragHandle = ref<HTMLElement>()
|
|
51
|
+
const dragOffset = ref(0)
|
|
52
|
+
|
|
53
|
+
const { isDragging: dragging, direction: dragDirection } = useDrag(dragHandle, {
|
|
54
|
+
axis: 'y',
|
|
55
|
+
onMove: ({ offsetY }) => {
|
|
56
|
+
dragOffset.value = Math.max(0, offsetY)
|
|
57
|
+
},
|
|
58
|
+
onEnd: ({ offsetY }) => {
|
|
59
|
+
if (offsetY > 150) {
|
|
60
|
+
// trigger an action when dragged far enough
|
|
61
|
+
}
|
|
62
|
+
dragOffset.value = 0
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<div
|
|
69
|
+
ref="dragHandle"
|
|
70
|
+
class="drag-card"
|
|
71
|
+
:class="{ '--dragging': dragging }"
|
|
72
|
+
:style="{ transform: dragOffset ? `translateY(${dragOffset}px)` : undefined }"
|
|
73
|
+
>
|
|
74
|
+
{{ dragging ? `Dragging — ${Math.round(dragOffset)}px ${dragDirection ?? ''}` : 'Drag me down' }}
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<style>
|
|
79
|
+
.drag-card {
|
|
80
|
+
touch-action: none;
|
|
81
|
+
cursor: grab;
|
|
82
|
+
user-select: none;
|
|
83
|
+
}
|
|
84
|
+
.drag-card:not(.--dragging) {
|
|
85
|
+
transition: transform 0.25s ease;
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Options
|
|
91
|
+
|
|
92
|
+
`useDrag(target, options)` - the `target` is a `MaybeRefOrGetter<HTMLElement | string | null | undefined>` and `options` accepts:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
interface UseDragOptions {
|
|
96
|
+
/**
|
|
97
|
+
* Restrict the tracking to a single axis. Off-axis movement is ignored.
|
|
98
|
+
* @default 'both'
|
|
99
|
+
*/
|
|
100
|
+
axis?: 'x' | 'y' | 'both'
|
|
101
|
+
/**
|
|
102
|
+
* Minimum distance (px) the pointer must travel before the drag becomes active.
|
|
103
|
+
* @default 0
|
|
104
|
+
*/
|
|
105
|
+
threshold?: number
|
|
106
|
+
/**
|
|
107
|
+
* Pointer types allowed to initiate the drag.
|
|
108
|
+
* @default ['mouse', 'touch', 'pen']
|
|
109
|
+
*/
|
|
110
|
+
pointerTypes?: ('mouse' | 'touch' | 'pen')[]
|
|
111
|
+
/**
|
|
112
|
+
* Reactively disable the gesture.
|
|
113
|
+
* @default false
|
|
114
|
+
*/
|
|
115
|
+
disabled?: MaybeRefOrGetter<boolean>
|
|
116
|
+
/**
|
|
117
|
+
* Call `event.preventDefault()` on each pointer move while dragging.
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
preventDefault?: boolean
|
|
121
|
+
/**
|
|
122
|
+
* Call `event.stopPropagation()` on the pointer events.
|
|
123
|
+
* @default false
|
|
124
|
+
*/
|
|
125
|
+
stopPropagation?: boolean
|
|
126
|
+
/**
|
|
127
|
+
* Attach the listeners as soon as the target is available. When `false`, call `start()` manually.
|
|
128
|
+
* @default true
|
|
129
|
+
*/
|
|
130
|
+
immediate?: boolean
|
|
131
|
+
/** Called once when the drag becomes active (threshold reached). */
|
|
132
|
+
onStart?: (state: DragState) => void
|
|
133
|
+
/** Called on every pointer move while dragging. */
|
|
134
|
+
onMove?: (state: DragState) => void
|
|
135
|
+
/** Called when the drag ends (pointer up or cancel). */
|
|
136
|
+
onEnd?: (state: DragState) => void
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Each callback receives a `DragState` snapshot:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
interface DragState {
|
|
144
|
+
/** Pointer offset from the drag start on the X axis (`0` when axis is `'y'`). */
|
|
145
|
+
offsetX: number
|
|
146
|
+
/** Pointer offset from the drag start on the Y axis (`0` when axis is `'x'`). */
|
|
147
|
+
offsetY: number
|
|
148
|
+
/** Absolute distance dragged from the start. */
|
|
149
|
+
distance: number
|
|
150
|
+
/** Dominant direction of the drag. */
|
|
151
|
+
direction: 'up' | 'down' | 'left' | 'right' | undefined
|
|
152
|
+
/** Pointer position when the drag started. */
|
|
153
|
+
startX: number
|
|
154
|
+
startY: number
|
|
155
|
+
/** Current pointer position. */
|
|
156
|
+
x: number
|
|
157
|
+
y: number
|
|
158
|
+
/** The underlying pointer event. */
|
|
159
|
+
event: PointerEvent
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Composable Return
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
interface UseDragReturn {
|
|
167
|
+
/** Whether a drag is currently active (threshold reached). */
|
|
168
|
+
isDragging: Readonly<Ref<boolean>>
|
|
169
|
+
/** Reactive pointer offset from the drag start on the X axis. */
|
|
170
|
+
offsetX: Readonly<Ref<number>>
|
|
171
|
+
/** Reactive pointer offset from the drag start on the Y axis. */
|
|
172
|
+
offsetY: Readonly<Ref<number>>
|
|
173
|
+
/** Reactive absolute distance dragged from the start. */
|
|
174
|
+
distance: Readonly<Ref<number>>
|
|
175
|
+
/** Reactive dominant direction of the drag. */
|
|
176
|
+
direction: Readonly<Ref<'up' | 'down' | 'left' | 'right' | undefined>>
|
|
177
|
+
/** Manually attach the listeners. */
|
|
178
|
+
start: () => void
|
|
179
|
+
/** Manually detach the listeners (also cancels an ongoing drag). */
|
|
180
|
+
stop: () => void
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Notes
|
|
185
|
+
|
|
186
|
+
- Add `touch-action: none` on the draggable element to prevent the browser from scrolling while dragging.
|
|
187
|
+
- The composable attaches automatically on mount (`immediate: true` by default) and cleans up on unmount; use `start()` / `stop()` for manual control.
|
|
188
|
+
- `onEnd` only fires when an actual drag happened (the threshold was reached), so a simple tap will not trigger it.
|
|
189
|
+
- The target can be a ref, a getter or a CSS selector string, and the listeners re-attach automatically when it changes.
|
|
190
|
+
|
|
191
|
+
<script lang="ts" setup>
|
|
192
|
+
import { useDrag } from 'maz-ui/composables/useDrag'
|
|
193
|
+
import { ref } from 'vue'
|
|
194
|
+
|
|
195
|
+
const dragHandle = ref()
|
|
196
|
+
const dragOffset = ref(0)
|
|
197
|
+
|
|
198
|
+
const { isDragging: dragging, direction: dragDirection } = useDrag(dragHandle, {
|
|
199
|
+
axis: 'y',
|
|
200
|
+
onMove: ({ offsetY }) => {
|
|
201
|
+
dragOffset.value = Math.max(0, offsetY)
|
|
202
|
+
},
|
|
203
|
+
onEnd: () => {
|
|
204
|
+
dragOffset.value = 0
|
|
205
|
+
},
|
|
206
|
+
})
|
|
207
|
+
</script>
|
|
208
|
+
|
|
209
|
+
<style>
|
|
210
|
+
.drag-demo {
|
|
211
|
+
border: 1px solid var(--vp-c-divider);
|
|
212
|
+
border-radius: 12px;
|
|
213
|
+
padding: 1rem;
|
|
214
|
+
height: 220px;
|
|
215
|
+
display: flex;
|
|
216
|
+
justify-content: center;
|
|
217
|
+
align-items: flex-start;
|
|
218
|
+
overflow: hidden;
|
|
219
|
+
}
|
|
220
|
+
.drag-card {
|
|
221
|
+
touch-action: none;
|
|
222
|
+
cursor: grab;
|
|
223
|
+
user-select: none;
|
|
224
|
+
width: 100%;
|
|
225
|
+
max-width: 320px;
|
|
226
|
+
padding: 2.5rem 1rem;
|
|
227
|
+
border-radius: 12px;
|
|
228
|
+
text-align: center;
|
|
229
|
+
font-size: 1.1rem;
|
|
230
|
+
color: white;
|
|
231
|
+
background: var(--vp-c-brand-1, #6366f1);
|
|
232
|
+
}
|
|
233
|
+
.drag-card:not(.--dragging) {
|
|
234
|
+
transition: transform 0.25s ease;
|
|
235
|
+
}
|
|
236
|
+
.drag-card.--dragging {
|
|
237
|
+
cursor: grabbing;
|
|
238
|
+
}
|
|
239
|
+
</style>
|