@baklavue/mcp 1.0.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 +72 -0
- package/dist/data/component-categories.d.ts +7 -0
- package/dist/data/component-categories.js +48 -0
- package/dist/data/loaders.d.ts +22 -0
- package/dist/data/loaders.js +346 -0
- package/dist/docs/components/accordion.md +601 -0
- package/dist/docs/components/alert.md +233 -0
- package/dist/docs/components/badge.md +100 -0
- package/dist/docs/components/banner.md +231 -0
- package/dist/docs/components/button.md +324 -0
- package/dist/docs/components/checkbox.md +343 -0
- package/dist/docs/components/chip.md +199 -0
- package/dist/docs/components/datepicker.md +243 -0
- package/dist/docs/components/dialog.md +224 -0
- package/dist/docs/components/drawer.md +188 -0
- package/dist/docs/components/dropdown.md +291 -0
- package/dist/docs/components/file-upload.md +248 -0
- package/dist/docs/components/icon.md +142 -0
- package/dist/docs/components/image.md +161 -0
- package/dist/docs/components/index.md +151 -0
- package/dist/docs/components/input.md +407 -0
- package/dist/docs/components/link.md +249 -0
- package/dist/docs/components/notification.md +179 -0
- package/dist/docs/components/pagination.md +168 -0
- package/dist/docs/components/radio.md +221 -0
- package/dist/docs/components/scroll-to-top.md +90 -0
- package/dist/docs/components/select.md +239 -0
- package/dist/docs/components/skeleton.md +79 -0
- package/dist/docs/components/spinner.md +93 -0
- package/dist/docs/components/split-button.md +165 -0
- package/dist/docs/components/stepper.md +337 -0
- package/dist/docs/components/switch.md +144 -0
- package/dist/docs/components/tab.md +140 -0
- package/dist/docs/components/table.md +362 -0
- package/dist/docs/components/tag.md +243 -0
- package/dist/docs/components/textarea.md +190 -0
- package/dist/docs/components/tooltip.md +155 -0
- package/dist/docs/composables/alert.md +87 -0
- package/dist/docs/composables/asyncState.md +74 -0
- package/dist/docs/composables/base64.md +72 -0
- package/dist/docs/composables/breakpoints.md +129 -0
- package/dist/docs/composables/clipboard.md +108 -0
- package/dist/docs/composables/colorScheme.md +110 -0
- package/dist/docs/composables/confirmDialog.md +105 -0
- package/dist/docs/composables/containerScroll.md +89 -0
- package/dist/docs/composables/cookie.md +137 -0
- package/dist/docs/composables/debounce.md +69 -0
- package/dist/docs/composables/disclosure.md +69 -0
- package/dist/docs/composables/elementSize.md +84 -0
- package/dist/docs/composables/fetch.md +257 -0
- package/dist/docs/composables/fieldArray.md +104 -0
- package/dist/docs/composables/file.md +343 -0
- package/dist/docs/composables/focusTrap.md +87 -0
- package/dist/docs/composables/formPersistence.md +69 -0
- package/dist/docs/composables/formState.md +71 -0
- package/dist/docs/composables/formValidation.md +355 -0
- package/dist/docs/composables/format.md +107 -0
- package/dist/docs/composables/id.md +54 -0
- package/dist/docs/composables/index.md +112 -0
- package/dist/docs/composables/infiniteQuery.md +104 -0
- package/dist/docs/composables/intersectionObserver.md +64 -0
- package/dist/docs/composables/lazyQuery.md +68 -0
- package/dist/docs/composables/loading.md +91 -0
- package/dist/docs/composables/mutation.md +83 -0
- package/dist/docs/composables/notification.md +169 -0
- package/dist/docs/composables/pagination.md +109 -0
- package/dist/docs/composables/polling.md +76 -0
- package/dist/docs/composables/previous.md +58 -0
- package/dist/docs/composables/query.md +248 -0
- package/dist/docs/composables/raf.md +78 -0
- package/dist/docs/composables/scrollLock.md +46 -0
- package/dist/docs/composables/scrollToError.md +291 -0
- package/dist/docs/composables/scrollVisibility.md +60 -0
- package/dist/docs/composables/share.md +78 -0
- package/dist/docs/composables/slug.md +58 -0
- package/dist/docs/composables/stepper.md +117 -0
- package/dist/docs/composables/stepperForm.md +74 -0
- package/dist/docs/composables/sticky.md +91 -0
- package/dist/docs/composables/storage.md +193 -0
- package/dist/docs/composables/theme.md +252 -0
- package/dist/docs/composables/themePreset.md +62 -0
- package/dist/docs/composables/throttle.md +76 -0
- package/dist/docs/composables/timer.md +78 -0
- package/dist/docs/composables/toggle.md +55 -0
- package/dist/docs/guide/contributing.md +364 -0
- package/dist/docs/guide/design-tokens.md +29 -0
- package/dist/docs/guide/getting-started.md +181 -0
- package/dist/docs/guide/installation.md +287 -0
- package/dist/docs/guide/localization.md +132 -0
- package/dist/docs/guide/mcp.md +141 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +177 -0
- package/package.json +48 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# useScrollToError
|
|
2
|
+
|
|
3
|
+
A composable for scrolling to an element with validation error. Scrolls into view, optionally applies a highlight effect, focuses the first focusable control, and announces to screen readers.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<form @submit.prevent="handleSubmit">
|
|
10
|
+
<div data-field="tags">
|
|
11
|
+
<input v-model="tags" />
|
|
12
|
+
</div>
|
|
13
|
+
<button type="submit">Submit</button>
|
|
14
|
+
</form>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
19
|
+
|
|
20
|
+
const { scrollToError } = useScrollToError();
|
|
21
|
+
|
|
22
|
+
const handleSubmit = () => {
|
|
23
|
+
const err = validationError.value;
|
|
24
|
+
if (err) {
|
|
25
|
+
scrollToError(err);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
</script>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Direct Selector
|
|
32
|
+
|
|
33
|
+
```vue
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
36
|
+
|
|
37
|
+
const { scrollToError } = useScrollToError();
|
|
38
|
+
|
|
39
|
+
// Scroll to element by selector
|
|
40
|
+
scrollToError('[data-field="tags"]');
|
|
41
|
+
</script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### With Validation Error Object
|
|
45
|
+
|
|
46
|
+
```vue
|
|
47
|
+
<script setup lang="ts">
|
|
48
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
49
|
+
|
|
50
|
+
const { scrollToError } = useScrollToError();
|
|
51
|
+
|
|
52
|
+
// Validation error with scrollTarget
|
|
53
|
+
const validationError = {
|
|
54
|
+
field: "tags",
|
|
55
|
+
message: "Please select at least one option",
|
|
56
|
+
scrollTarget: '[data-field="tags"]',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
scrollToError(validationError);
|
|
60
|
+
</script>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Methods
|
|
64
|
+
|
|
65
|
+
### scrollToError
|
|
66
|
+
|
|
67
|
+
Scrolls to the target element and optionally applies highlight and focus.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
scrollToError(target: ScrollToErrorTarget, options?: ScrollToErrorOptions): ScrollToErrorResult
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Returns `{ success: boolean }` indicating whether the target was found and scrolled to.
|
|
74
|
+
|
|
75
|
+
## Target Types
|
|
76
|
+
|
|
77
|
+
Accepted by `scrollToError`:
|
|
78
|
+
|
|
79
|
+
- **CSS selector string** – e.g. `'[data-field="tags"]'`
|
|
80
|
+
- **HTMLElement** – direct element reference
|
|
81
|
+
- **Object with scrollTarget** – e.g. `{ scrollTarget: '[data-field="tags"]' }` for validation errors
|
|
82
|
+
|
|
83
|
+
## Options
|
|
84
|
+
|
|
85
|
+
### ScrollToErrorOptions
|
|
86
|
+
|
|
87
|
+
| Option | Type | Default | Description |
|
|
88
|
+
| --- | --- | --- | --- |
|
|
89
|
+
| `scrollBehavior` | `'smooth' \| 'auto' \| 'instant'` | `'smooth'` | Scroll behavior |
|
|
90
|
+
| `block` | `'start' \| 'center' \| 'end' \| 'nearest'` | `'center'` | Vertical scroll position |
|
|
91
|
+
| `shineClass` | `string` | `'error-shine'` | CSS class for highlight effect |
|
|
92
|
+
| `shineDuration` | `number` | `2500` | Duration in ms to keep the shine class. Use `0` to disable |
|
|
93
|
+
| `focus` | `boolean` | `true` | Whether to attempt focusing the first focusable element |
|
|
94
|
+
| `focusDelay` | `number` | `300` | Delay in ms before focus attempt |
|
|
95
|
+
| `scrollContainer` | `string \| HTMLElement \| null` | — | Scroll container for forms inside modals/drawers. When provided, scrolls this container instead of the viewport |
|
|
96
|
+
| `announce` | `boolean \| string` | `true` | Screen reader announcement. `true` = default message, `string` = custom message, `false` = no announcement |
|
|
97
|
+
| `scrollOffset` | `{ top?: number; left?: number }` | — | Offset in pixels for fixed headers (e.g. `{ top: 80 }`) |
|
|
98
|
+
|
|
99
|
+
### UseScrollToErrorOptions (composable-level)
|
|
100
|
+
|
|
101
|
+
When creating the composable, you can pass default options applied to every call:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
useScrollToError({
|
|
105
|
+
defaultOptions: {
|
|
106
|
+
scrollContainer: "[data-dialog-body]",
|
|
107
|
+
shineClass: "my-app-error",
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Call-time options override these defaults.
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### With Custom Options
|
|
117
|
+
|
|
118
|
+
```vue
|
|
119
|
+
<script setup lang="ts">
|
|
120
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
121
|
+
|
|
122
|
+
const { scrollToError } = useScrollToError();
|
|
123
|
+
|
|
124
|
+
scrollToError('[data-field="tags"]', {
|
|
125
|
+
shineClass: "my-shine",
|
|
126
|
+
shineDuration: 1500,
|
|
127
|
+
focusDelay: 500,
|
|
128
|
+
});
|
|
129
|
+
</script>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### With Default Options (for modals)
|
|
133
|
+
|
|
134
|
+
```vue
|
|
135
|
+
<script setup lang="ts">
|
|
136
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
137
|
+
|
|
138
|
+
const { scrollToError } = useScrollToError({
|
|
139
|
+
defaultOptions: {
|
|
140
|
+
scrollContainer: "[data-dialog-body]",
|
|
141
|
+
announce: "Form has errors. Please fix the highlighted field.",
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
scrollToError('[data-field="tags"]');
|
|
146
|
+
</script>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Form in Modal with Scroll Container
|
|
150
|
+
|
|
151
|
+
```vue
|
|
152
|
+
<template>
|
|
153
|
+
<BvDialog v-model:open="isOpen">
|
|
154
|
+
<div data-dialog-body class="dialog-body">
|
|
155
|
+
<form @submit.prevent="handleSubmit">
|
|
156
|
+
<div data-field="email">
|
|
157
|
+
<input v-model="email" />
|
|
158
|
+
</div>
|
|
159
|
+
</form>
|
|
160
|
+
</div>
|
|
161
|
+
</BvDialog>
|
|
162
|
+
</template>
|
|
163
|
+
|
|
164
|
+
<script setup lang="ts">
|
|
165
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
166
|
+
|
|
167
|
+
const { scrollToError } = useScrollToError({
|
|
168
|
+
defaultOptions: { scrollContainer: "[data-dialog-body]" },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const handleSubmit = () => {
|
|
172
|
+
if (hasError) {
|
|
173
|
+
scrollToError('[data-field="email"]');
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
</script>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### With Fixed Header Offset
|
|
180
|
+
|
|
181
|
+
```vue
|
|
182
|
+
<script setup lang="ts">
|
|
183
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
184
|
+
|
|
185
|
+
const { scrollToError } = useScrollToError();
|
|
186
|
+
|
|
187
|
+
scrollToError('[data-field="tags"]', {
|
|
188
|
+
scrollOffset: { top: 80 },
|
|
189
|
+
});
|
|
190
|
+
</script>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Without Shine Effect
|
|
194
|
+
|
|
195
|
+
```vue
|
|
196
|
+
<script setup lang="ts">
|
|
197
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
198
|
+
|
|
199
|
+
const { scrollToError } = useScrollToError();
|
|
200
|
+
|
|
201
|
+
scrollToError('[data-field="tags"]', {
|
|
202
|
+
shineDuration: 0,
|
|
203
|
+
});
|
|
204
|
+
</script>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Without Focus
|
|
208
|
+
|
|
209
|
+
```vue
|
|
210
|
+
<script setup lang="ts">
|
|
211
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
212
|
+
|
|
213
|
+
const { scrollToError } = useScrollToError();
|
|
214
|
+
|
|
215
|
+
scrollToError('[data-field="tags"]', {
|
|
216
|
+
focus: false,
|
|
217
|
+
});
|
|
218
|
+
</script>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Without Screen Reader Announcement
|
|
222
|
+
|
|
223
|
+
```vue
|
|
224
|
+
<script setup lang="ts">
|
|
225
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
226
|
+
|
|
227
|
+
const { scrollToError } = useScrollToError();
|
|
228
|
+
|
|
229
|
+
scrollToError('[data-field="tags"]', {
|
|
230
|
+
announce: false,
|
|
231
|
+
});
|
|
232
|
+
</script>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Using Return Value
|
|
236
|
+
|
|
237
|
+
```vue
|
|
238
|
+
<script setup lang="ts">
|
|
239
|
+
import { useScrollToError } from "@baklavue/composables";
|
|
240
|
+
|
|
241
|
+
const { scrollToError } = useScrollToError();
|
|
242
|
+
|
|
243
|
+
const handleSubmit = () => {
|
|
244
|
+
const result = scrollToError('[data-field="tags"]');
|
|
245
|
+
if (!result.success) {
|
|
246
|
+
console.warn("Could not scroll to error field");
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
</script>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## CSS for Shine Effect
|
|
253
|
+
|
|
254
|
+
The composable uses `error-shine` by default. Define this class in your styles for the highlight effect:
|
|
255
|
+
|
|
256
|
+
```css
|
|
257
|
+
.error-shine {
|
|
258
|
+
animation: error-shine 2.5s ease-in-out;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
@keyframes error-shine {
|
|
262
|
+
0%,
|
|
263
|
+
100% {
|
|
264
|
+
box-shadow: none;
|
|
265
|
+
}
|
|
266
|
+
50% {
|
|
267
|
+
box-shadow: 0 0 0 2px var(--bl-color-danger);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## TypeScript Support
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import {
|
|
276
|
+
useScrollToError,
|
|
277
|
+
type ScrollToErrorOptions,
|
|
278
|
+
type ScrollToErrorResult,
|
|
279
|
+
type ScrollToErrorTarget,
|
|
280
|
+
type UseScrollToErrorOptions,
|
|
281
|
+
} from "@baklavue/composables";
|
|
282
|
+
|
|
283
|
+
const { scrollToError } = useScrollToError();
|
|
284
|
+
|
|
285
|
+
// scrollToError accepts string, HTMLElement, or { scrollTarget: string }
|
|
286
|
+
const result = scrollToError('[data-field="tags"]');
|
|
287
|
+
// result.success: boolean
|
|
288
|
+
|
|
289
|
+
scrollToError(document.getElementById("field"));
|
|
290
|
+
scrollToError({ scrollTarget: '[data-field="tags"]' });
|
|
291
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# useScrollVisibility
|
|
2
|
+
|
|
3
|
+
A composable for scroll-based visibility. Detects when scroll position exceeds a threshold. RAF-throttled for performance. Use with BvScrollToTop or custom scroll-to-top and sticky UI.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<div>
|
|
10
|
+
<BvButton v-if="isVisible" @click="scrollToTop">Scroll to top</BvButton>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup>
|
|
15
|
+
import { BvButton } from "@baklavue/ui";
|
|
16
|
+
import { useScrollVisibility } from "@baklavue/composables";
|
|
17
|
+
|
|
18
|
+
const { isVisible, scrollY, scrollToTop } = useScrollVisibility({ threshold: 300 });
|
|
19
|
+
</script>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Custom Threshold
|
|
23
|
+
|
|
24
|
+
```vue
|
|
25
|
+
<script setup>
|
|
26
|
+
import { useScrollVisibility } from "@baklavue/composables";
|
|
27
|
+
|
|
28
|
+
const { isVisible } = useScrollVisibility({ threshold: 500 });
|
|
29
|
+
// isVisible is true when user scrolls past 500px
|
|
30
|
+
</script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
### Return Value
|
|
36
|
+
|
|
37
|
+
| Property | Type | Description |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `isVisible` | `Ref<boolean>` | True when scroll exceeds threshold |
|
|
40
|
+
| `scrollY` | `Ref<number>` | Current scroll position |
|
|
41
|
+
| `scrollToTop` | `() => void` | Smooth scroll to top |
|
|
42
|
+
|
|
43
|
+
### Options
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface UseScrollVisibilityOptions {
|
|
47
|
+
threshold?: number; // pixels (default: 300)
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## TypeScript Support
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import {
|
|
55
|
+
useScrollVisibility,
|
|
56
|
+
type UseScrollVisibilityOptions,
|
|
57
|
+
} from "@baklavue/composables";
|
|
58
|
+
|
|
59
|
+
const { isVisible, scrollToTop } = useScrollVisibility({ threshold: 400 });
|
|
60
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# useShare
|
|
2
|
+
|
|
3
|
+
A composable for the Web Share API. Share text, URLs, or files via native share sheet (mobile) or fallback. Pairs with `useClipboard` when share is unavailable.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<BvButton v-if="isSupported" @click="handleShare">Share</BvButton>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
import { BvButton } from "@baklavue/ui";
|
|
14
|
+
import { useShare, useNotification } from "@baklavue/composables";
|
|
15
|
+
|
|
16
|
+
const { share, isSupported } = useShare();
|
|
17
|
+
const { success } = useNotification();
|
|
18
|
+
|
|
19
|
+
const handleShare = async () => {
|
|
20
|
+
const ok = await share({ title: "Report", url: "https://example.com/report" });
|
|
21
|
+
if (ok) success({ description: "Shared!" });
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## With Default Data
|
|
27
|
+
|
|
28
|
+
```vue
|
|
29
|
+
<script setup>
|
|
30
|
+
import { useShare, useNotification } from "@baklavue/composables";
|
|
31
|
+
|
|
32
|
+
const { success } = useNotification();
|
|
33
|
+
const { share, isSupported } = useShare({
|
|
34
|
+
data: { title: "Check this out", url: window.location.href },
|
|
35
|
+
onSuccess: () => success({ description: "Shared!" }),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await share(); // uses default data
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API
|
|
43
|
+
|
|
44
|
+
### Options
|
|
45
|
+
|
|
46
|
+
| Option | Type | Description |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| `data` | `ShareData` | Default data to share when `share()` is called without arguments |
|
|
49
|
+
| `onSuccess` | `() => void` | Callback when share succeeds |
|
|
50
|
+
| `onError` | `(error?: Error) => void` | Callback when share fails or is aborted |
|
|
51
|
+
|
|
52
|
+
### ShareData
|
|
53
|
+
|
|
54
|
+
| Property | Type | Description |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| `title` | `string` | Title of the shared content |
|
|
57
|
+
| `text` | `string` | Text to share |
|
|
58
|
+
| `url` | `string` | URL to share |
|
|
59
|
+
| `files` | `File[]` | Files to share (when supported) |
|
|
60
|
+
|
|
61
|
+
### Return Value
|
|
62
|
+
|
|
63
|
+
| Property | Type | Description |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `share` | `(data?: ShareData) => Promise<boolean>` | Share data. Uses default when called without args. |
|
|
66
|
+
| `isSupported` | `ComputedRef<boolean>` | Whether Web Share API is available |
|
|
67
|
+
| `canShare` | `ComputedRef<boolean>` | Whether the current data can be shared |
|
|
68
|
+
| `shared` | `Ref<boolean>` | True after successful share |
|
|
69
|
+
| `error` | `Ref<Error \| null>` | Last error if share failed |
|
|
70
|
+
|
|
71
|
+
## TypeScript Support
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { useShare, type ShareData, type UseShareOptions } from "@baklavue/composables";
|
|
75
|
+
|
|
76
|
+
const { share, isSupported } = useShare();
|
|
77
|
+
await share({ title: "Report", url: "https://example.com" });
|
|
78
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# useSlug
|
|
2
|
+
|
|
3
|
+
A composable for converting a string to a URL-friendly slug. Useful for SEO-friendly URLs, filenames, and unique keys.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<script setup>
|
|
9
|
+
import { ref } from "vue";
|
|
10
|
+
import { useSlug } from "@baklavue/composables";
|
|
11
|
+
|
|
12
|
+
const title = ref("Hello World!");
|
|
13
|
+
const slug = useSlug(title);
|
|
14
|
+
// slug: "hello-world"
|
|
15
|
+
</script>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## With Options
|
|
19
|
+
|
|
20
|
+
```vue
|
|
21
|
+
<script setup>
|
|
22
|
+
import { useSlug } from "@baklavue/composables";
|
|
23
|
+
|
|
24
|
+
const slug = useSlug("My Project Name", { separator: "_" });
|
|
25
|
+
// slug: "my_project_name"
|
|
26
|
+
</script>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### Options
|
|
32
|
+
|
|
33
|
+
| Option | Type | Default | Description |
|
|
34
|
+
| --- | --- | --- | --- |
|
|
35
|
+
| `separator` | `string` | `"-"` | Character to replace spaces/special chars |
|
|
36
|
+
| `lowercase` | `boolean` | `true` | Lowercase the result |
|
|
37
|
+
|
|
38
|
+
### Return Value
|
|
39
|
+
|
|
40
|
+
| Property | Type | Description |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| (return) | `ComputedRef<string>` | URL-friendly slug |
|
|
43
|
+
|
|
44
|
+
### Behavior
|
|
45
|
+
|
|
46
|
+
- Trims whitespace
|
|
47
|
+
- Normalizes Unicode (NFD) and removes diacritics
|
|
48
|
+
- Replaces non-word chars with separator
|
|
49
|
+
- Collapses multiple separators
|
|
50
|
+
- Trims leading/trailing separators
|
|
51
|
+
|
|
52
|
+
## TypeScript Support
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { useSlug, type UseSlugOptions } from "@baklavue/composables";
|
|
56
|
+
|
|
57
|
+
const slug = useSlug(titleRef, { separator: "_", lowercase: false });
|
|
58
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# useStepper
|
|
2
|
+
|
|
3
|
+
A composable for multi-step flow state. Use with BvStepper for wizards and form flows.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<div>
|
|
10
|
+
<BvStepper v-model:current-step="currentStep" :steps="steps" />
|
|
11
|
+
<div>
|
|
12
|
+
<BvButton v-if="!isFirst" @click="prev">Previous</BvButton>
|
|
13
|
+
<BvButton v-if="!isLast" @click="next">Next</BvButton>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup>
|
|
19
|
+
import { BvButton, BvStepper } from "@baklavue/ui";
|
|
20
|
+
import { useStepper } from "@baklavue/composables";
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
currentStep,
|
|
24
|
+
steps,
|
|
25
|
+
next,
|
|
26
|
+
prev,
|
|
27
|
+
isFirst,
|
|
28
|
+
isLast,
|
|
29
|
+
} = useStepper({
|
|
30
|
+
steps: [
|
|
31
|
+
{ label: "Details" },
|
|
32
|
+
{ label: "Review" },
|
|
33
|
+
{ label: "Confirm" },
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## With Step Validation
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<script setup>
|
|
43
|
+
import { useStepper } from "@baklavue/composables";
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
currentStep,
|
|
47
|
+
steps,
|
|
48
|
+
next,
|
|
49
|
+
setStepError,
|
|
50
|
+
} = useStepper({
|
|
51
|
+
steps: [
|
|
52
|
+
{ label: "Details" },
|
|
53
|
+
{ label: "Review" },
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const validateAndNext = () => {
|
|
58
|
+
const valid = validateCurrentStep();
|
|
59
|
+
if (!valid) {
|
|
60
|
+
setStepError(currentStep.value, true);
|
|
61
|
+
} else {
|
|
62
|
+
setStepError(currentStep.value, false);
|
|
63
|
+
next();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
</script>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## API
|
|
70
|
+
|
|
71
|
+
### Return Value
|
|
72
|
+
|
|
73
|
+
| Property | Type | Description |
|
|
74
|
+
| --- | --- | --- |
|
|
75
|
+
| `currentStep` | `Ref<number>` | Current step index (0-based) |
|
|
76
|
+
| `steps` | `Ref<StepperStep[]>` | Step configurations |
|
|
77
|
+
| `next` | `() => void` | Go to next step |
|
|
78
|
+
| `prev` | `() => void` | Go to previous step |
|
|
79
|
+
| `goTo` | `(index: number) => void` | Go to specific step |
|
|
80
|
+
| `setStepError` | `(index: number, hasError: boolean) => void` | Set error state for step |
|
|
81
|
+
| `isFirst` | `ComputedRef<boolean>` | True on first step |
|
|
82
|
+
| `isLast` | `ComputedRef<boolean>` | True on last step |
|
|
83
|
+
| `canGoNext` | `ComputedRef<boolean>` | True if can advance |
|
|
84
|
+
| `canGoPrev` | `ComputedRef<boolean>` | True if can go back |
|
|
85
|
+
| `stepVariant` | `(index: number) => StepVariant` | Get variant for step (default, active, success, error) |
|
|
86
|
+
| `totalSteps` | `ComputedRef<number>` | Total number of steps |
|
|
87
|
+
|
|
88
|
+
### Options
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface UseStepperOptions {
|
|
92
|
+
steps: StepperStep[];
|
|
93
|
+
initialStep?: number; // default: 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface StepperStep {
|
|
97
|
+
label: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
completed?: boolean;
|
|
100
|
+
error?: boolean;
|
|
101
|
+
disabled?: boolean;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## TypeScript Support
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import {
|
|
109
|
+
useStepper,
|
|
110
|
+
type UseStepperOptions,
|
|
111
|
+
type StepperStep,
|
|
112
|
+
} from "@baklavue/composables";
|
|
113
|
+
|
|
114
|
+
const { currentStep, next } = useStepper({
|
|
115
|
+
steps: [{ label: "Step 1" }, { label: "Step 2" }],
|
|
116
|
+
});
|
|
117
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# useStepperForm
|
|
2
|
+
|
|
3
|
+
A composable for multi-step form flows with per-step validation. Use with [useStepper](/composables/stepper) and [useZodForm](/composables/formValidation) to validate before advancing to the next step.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
import { useStepper, useStepperForm } from "@baklavue/composables";
|
|
10
|
+
import { useZodForm } from "@baklavue/composables";
|
|
11
|
+
import { ref } from "vue";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
const form = ref({ email: "", name: "", address: "" });
|
|
15
|
+
const schema = z.object({
|
|
16
|
+
email: z.string().email(),
|
|
17
|
+
name: z.string().min(1),
|
|
18
|
+
address: z.string().min(1),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const stepper = useStepper({
|
|
22
|
+
steps: [{ label: "Contact" }, { label: "Address" }],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const formValidation = useZodForm(schema, form);
|
|
26
|
+
const { nextWithValidation, hasStepError } = useStepperForm(stepper, {
|
|
27
|
+
stepFields: (i) => (i === 0 ? ["email", "name"] : ["address"]),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const onNext = () => nextWithValidation(formValidation.validate);
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<BvStepper v-model:current-step="stepper.currentStep" :steps="stepper.steps" />
|
|
35
|
+
<form @submit.prevent="onNext">
|
|
36
|
+
<!-- Step 0: email, name -->
|
|
37
|
+
<template v-if="stepper.currentStep.value === 0">
|
|
38
|
+
<BvInput v-model="form.email" :invalid-text="formValidation.getError('email')" />
|
|
39
|
+
<BvInput v-model="form.name" :invalid-text="formValidation.getError('name')" />
|
|
40
|
+
</template>
|
|
41
|
+
<!-- Step 1: address -->
|
|
42
|
+
<template v-else>
|
|
43
|
+
<BvInput v-model="form.address" :invalid-text="formValidation.getError('address')" />
|
|
44
|
+
</template>
|
|
45
|
+
<BvButton type="submit">Next</BvButton>
|
|
46
|
+
</form>
|
|
47
|
+
</template>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### Parameters
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
useStepperForm(stepper, options?)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Parameter | Type | Description |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `stepper` | `StepperLike` | Return value from useStepper |
|
|
61
|
+
| `options` | `UseStepperFormOptions` | Optional: `{ stepFields?: (stepIndex) => string[] }` |
|
|
62
|
+
|
|
63
|
+
### Return Value
|
|
64
|
+
|
|
65
|
+
| Property | Type | Description |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| `hasStepError` | `() => boolean` | Whether the current step has validation errors |
|
|
68
|
+
| `nextWithValidation` | `(validate: () => Promise<FormErrors \| null>) => Promise<boolean>` | Validates, advances if valid, sets step error if invalid. Returns `true` if advanced |
|
|
69
|
+
|
|
70
|
+
### stepFields
|
|
71
|
+
|
|
72
|
+
When provided, `stepFields(stepIndex)` returns the field paths for that step. Validation errors are filtered to these paths to determine if the current step has errors. If omitted, any validation error marks the current step as having an error.
|
|
73
|
+
|
|
74
|
+
This is useful when you have a single schema for the whole form but want to show step-specific error indicators on the stepper.
|