vuiii 1.0.0-beta.9 → 1.0.0-beta.91
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/CLAUDE.md +1121 -0
- package/README.md +44 -9
- package/dist/arrow-narrow-down-DGBY4Btu.js +4 -0
- package/dist/arrow-narrow-left-BMfPRee1.js +4 -0
- package/dist/arrow-narrow-right-D7VrDLjb.js +4 -0
- package/dist/arrow-narrow-up-BorlecRd.js +4 -0
- package/dist/arrow-top-right-on-square-i24gMSZm.js +4 -0
- package/dist/arrow-up-tray-iCjPTwBt.js +4 -0
- package/dist/caret-sort-Dg7aRzKb.js +4 -0
- package/dist/check-BBg8cVLv.js +4 -0
- package/dist/chevron-down-cIqpaED9.js +4 -0
- package/dist/chevron-left-CxsikvMX.js +4 -0
- package/dist/chevron-right-ByOcIUwz.js +4 -0
- package/dist/chevron-up-BJHgvkCZ.js +4 -0
- package/dist/components/Autocomplete.vue.d.ts +133 -0
- package/dist/components/Breadcrumbs.vue.d.ts +5 -78
- package/dist/components/Button.vue.d.ts +40 -93
- package/dist/components/ButtonGroup.vue.d.ts +17 -0
- package/dist/components/Checkbox.vue.d.ts +113 -95
- package/dist/components/CheckboxGroup.vue.d.ts +42 -91
- package/dist/components/Divider.vue.d.ts +39 -0
- package/dist/components/Dropdown.vue.d.ts +57 -0
- package/dist/components/DropdownMenu.vue.d.ts +64 -0
- package/dist/components/FilePicker.vue.d.ts +36 -0
- package/dist/components/FormFields.vue.d.ts +30 -99
- package/dist/components/FormGroup.vue.d.ts +84 -83
- package/dist/components/Icon.vue.d.ts +5 -64
- package/dist/components/IconButton.vue.d.ts +11 -0
- package/dist/components/Input.vue.d.ts +93 -106
- package/dist/components/InputWrapper.vue.d.ts +40 -0
- package/dist/components/RadioButtonGroup.vue.d.ts +22 -0
- package/dist/components/RadioGroup.vue.d.ts +119 -96
- package/dist/components/Select.vue.d.ts +106 -152
- package/dist/components/ShortcutIcon.vue.d.ts +6 -0
- package/dist/components/Table.vue.d.ts +83 -70
- package/dist/components/Textarea.vue.d.ts +73 -74
- package/dist/components/Tooltip.vue.d.ts +75 -0
- package/dist/components/dialogStack/DialogLayout.vue.d.ts +42 -0
- package/dist/components/dialogStack/DialogStack.vue.d.ts +2 -0
- package/dist/components/snackbar/SnackbarStack.vue.d.ts +1 -19
- package/dist/components/transitions/FadeTransition.vue.d.ts +22 -0
- package/dist/composables/useAttrsWithoutClass.d.ts +3 -0
- package/dist/composables/useCursor.d.ts +53 -0
- package/dist/composables/useDropArea.d.ts +68 -0
- package/dist/composables/useFilteredProps.d.ts +3 -0
- package/dist/composables/useLoadData.d.ts +106 -0
- package/dist/composables/useLoadPaginatedData.d.ts +78 -0
- package/dist/composables/useOnClickOutside.d.ts +33 -0
- package/dist/composables/useOnFocusOutside.d.ts +26 -0
- package/dist/composables/useOnKeyPress.d.ts +26 -0
- package/dist/composables/usePageFromRouteQuery.d.ts +24 -0
- package/dist/composables/usePreventHandlingDrop.d.ts +20 -0
- package/dist/composables/useRouteQuery.d.ts +13 -0
- package/dist/composables/useSubmitAction.d.ts +110 -0
- package/dist/composables/useValidation.d.ts +81 -0
- package/dist/dialogStack.d.ts +538 -0
- package/dist/exclamation-BYxUQPvg.js +4 -0
- package/dist/index.d.ts +40 -11
- package/dist/mail-bBPeld_t.js +4 -0
- package/dist/minus-jP8I17w-.js +4 -0
- package/dist/pencil-DmJ9fo9U.js +4 -0
- package/dist/plus-CMNu2QQI.js +4 -0
- package/dist/search-CD4RRPi6.js +4 -0
- package/dist/snackbar.d.ts +37 -15
- package/dist/spinner-DlmCGx0i.js +4 -0
- package/dist/stories/assets/iconSizes.d.ts +2 -0
- package/dist/stories/assets/inputSizes.d.ts +2 -0
- package/dist/stories/assets/options.d.ts +12 -0
- package/dist/stories/assets/tableItems.d.ts +8 -0
- package/dist/trash-BMbPD9Je.js +4 -0
- package/dist/triangle-down-iLc4QWFR.js +4 -0
- package/dist/triangle-left-B8krIV2b.js +4 -0
- package/dist/triangle-right-xwrGdoER.js +4 -0
- package/dist/triangle-up-D_dSA8BG.js +4 -0
- package/dist/types.d.ts +200 -29
- package/dist/utils/createTypeParser.d.ts +2 -0
- package/dist/utils/debounce.d.ts +1 -0
- package/dist/utils/iconsResolver.d.ts +40 -2
- package/dist/utils/loadURLAsFile.d.ts +1 -0
- package/dist/utils/normalizeOptions.d.ts +61 -3
- package/dist/utils/resolveFilesFromClipboardEvent.d.ts +4 -0
- package/dist/utils/retrieveFilesFromDataTransfer.d.ts +1 -0
- package/dist/utils/retrieveMediaUrlFromHTML copy.d.ts +1 -0
- package/dist/utils/retrieveMediaUrlFromHTML.d.ts +1 -0
- package/dist/utils/transformInputAttrs.d.ts +4 -4
- package/dist/valueParsers/dateValueParser.d.ts +2 -0
- package/dist/valueParsers/numberValueParser.d.ts +2 -0
- package/dist/vuiii.css +2 -0
- package/dist/vuiii.js +1977 -0
- package/dist/x-bczynWUe.js +4 -0
- package/package.json +53 -48
- package/dist/components/Form.vue.d.ts +0 -189
- package/dist/components/modal/ModalLayout.vue.d.ts +0 -39
- package/dist/components/modal/ModalLayoutDialog.vue.d.ts +0 -36
- package/dist/components/modal/ModalStack.vue.d.ts +0 -28
- package/dist/hooks/useLoadData.d.ts +0 -21
- package/dist/hooks/useOnClickOutside.d.ts +0 -2
- package/dist/hooks/useOnKeyPress.d.ts +0 -1
- package/dist/hooks/useRouteQuery.d.ts +0 -17
- package/dist/hooks/useSubmitAction.d.ts +0 -33
- package/dist/icons/arrow-narrow-down.vue.d.ts +0 -2
- package/dist/icons/arrow-narrow-left.vue.d.ts +0 -2
- package/dist/icons/arrow-narrow-right.vue.d.ts +0 -2
- package/dist/icons/arrow-narrow-up.vue.d.ts +0 -2
- package/dist/icons/check-circle.vue.d.ts +0 -2
- package/dist/icons/check.vue.d.ts +0 -2
- package/dist/icons/chevron-down.vue.d.ts +0 -2
- package/dist/icons/chevron-left.vue.d.ts +0 -2
- package/dist/icons/chevron-right.vue.d.ts +0 -2
- package/dist/icons/chevron-up.vue.d.ts +0 -2
- package/dist/icons/exclamation-circle.vue.d.ts +0 -2
- package/dist/icons/exclamation.vue.d.ts +0 -2
- package/dist/icons/mail.vue.d.ts +0 -2
- package/dist/icons/minus.vue.d.ts +0 -2
- package/dist/icons/plus.vue.d.ts +0 -2
- package/dist/icons/search.vue.d.ts +0 -2
- package/dist/icons/spinner.vue.d.ts +0 -2
- package/dist/icons/trash.vue.d.ts +0 -2
- package/dist/icons/x.vue.d.ts +0 -2
- package/dist/modal.d.ts +0 -69
- package/dist/stories/Button.stories.d.ts +0 -449
- package/dist/stories/Checkbox.stories.d.ts +0 -272
- package/dist/stories/CheckboxGroup.stories.d.ts +0 -272
- package/dist/stories/Icon.stories.d.ts +0 -152
- package/dist/stories/Input.stories.d.ts +0 -422
- package/dist/stories/Radio.stories.d.ts +0 -284
- package/dist/stories/Select.stories.d.ts +0 -686
- package/dist/stories/options.d.ts +0 -7
- package/dist/style.css +0 -1
- package/dist/utils/generateId.d.ts +0 -1
- package/dist/utils/resolveGlobImport.d.ts +0 -3
- package/dist/vuiii.mjs +0 -1562
- package/dist/vuiii.umd.js +0 -1
- /package/dist/stories/{icons.d.ts → assets/icons.d.ts} +0 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
# VUIII - Vue Component Library
|
|
2
|
+
|
|
3
|
+
> AI Agent Context File - Auto-generated from source code JSDoc comments.
|
|
4
|
+
> Run `npm run docs` to regenerate.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
VUIII is a Vue 3 component library with TypeScript support, providing a comprehensive set of UI components, composables, and utilities for building modern web applications.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install vuiii
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { Button, Input, Select, FormFields } from 'vuiii'
|
|
18
|
+
import 'vuiii/style.css'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Components
|
|
22
|
+
|
|
23
|
+
### Autocomplete
|
|
24
|
+
|
|
25
|
+
**File:** `src/components/Autocomplete.vue`
|
|
26
|
+
|
|
27
|
+
Autocomplete input with dropdown suggestions and keyboard navigation.
|
|
28
|
+
Supports custom option rendering, filtering, and various data formats.
|
|
29
|
+
|
|
30
|
+
**Examples:**
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Basic usage with string array
|
|
34
|
+
import { Autocomplete } from 'vuiii'
|
|
35
|
+
|
|
36
|
+
<Autocomplete v-model="search" :options="['Apple', 'Banana', 'Cherry']" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// With object options and extractors
|
|
41
|
+
const users = [
|
|
42
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
|
43
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
<Autocomplete
|
|
47
|
+
v-model="search"
|
|
48
|
+
:options="users"
|
|
49
|
+
option-label="name"
|
|
50
|
+
option-value="id"
|
|
51
|
+
option-description="email"
|
|
52
|
+
@select="(option) => selectedUser = option.data"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// With custom filter function
|
|
58
|
+
const customFilter = (option, query) => {
|
|
59
|
+
return option.label.startsWith(query)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
<Autocomplete
|
|
63
|
+
v-model="search"
|
|
64
|
+
:options="options"
|
|
65
|
+
:filter="customFilter"
|
|
66
|
+
/>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Breadcrumbs
|
|
70
|
+
|
|
71
|
+
**File:** `src/components/Breadcrumbs.vue`
|
|
72
|
+
|
|
73
|
+
Navigation breadcrumbs with router-link support.
|
|
74
|
+
|
|
75
|
+
**Examples:**
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// Basic usage
|
|
79
|
+
import { Breadcrumbs } from 'vuiii'
|
|
80
|
+
import type { BreadcrumbItems } from 'vuiii'
|
|
81
|
+
|
|
82
|
+
const breadcrumbs: BreadcrumbItems = [
|
|
83
|
+
{ label: 'Home', link: '/' },
|
|
84
|
+
{ label: 'Products', link: '/products' },
|
|
85
|
+
{ label: 'Electronics', link: '/products/electronics' }
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
<Breadcrumbs :breadcrumbs="breadcrumbs" />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// With named routes
|
|
93
|
+
const breadcrumbs: BreadcrumbItems = [
|
|
94
|
+
{ label: 'Dashboard', link: { name: 'dashboard' } },
|
|
95
|
+
{ label: 'Users', link: { name: 'users' } },
|
|
96
|
+
{ label: 'John Doe', link: { name: 'user', params: { id: 123 } } },
|
|
97
|
+
]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Button
|
|
101
|
+
|
|
102
|
+
**File:** `src/components/Button.vue`
|
|
103
|
+
|
|
104
|
+
Polymorphic button component that renders as <button>, <a>, or <router-link>.
|
|
105
|
+
Supports multiple variants, sizes, icons, and loading states.
|
|
106
|
+
|
|
107
|
+
**Examples:**
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// Basic button
|
|
111
|
+
import { Button } from 'vuiii'
|
|
112
|
+
|
|
113
|
+
<Button label="Click me" />
|
|
114
|
+
<Button variant="primary" label="Submit" />
|
|
115
|
+
<Button variant="danger" label="Delete" />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// With icons
|
|
120
|
+
<Button prefixIcon="plus" label="Add Item" />
|
|
121
|
+
<Button label="Download" suffixIcon="arrow-down" />
|
|
122
|
+
<Button prefixIcon="save" suffixIcon="chevron-down" label="Save" />
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Different sizes
|
|
127
|
+
<Button size="small" label="Small" />
|
|
128
|
+
<Button size="normal" label="Normal" />
|
|
129
|
+
<Button size="large" label="Large" />
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Checkbox
|
|
133
|
+
|
|
134
|
+
**File:** `src/components/Checkbox.vue`
|
|
135
|
+
|
|
136
|
+
Checkbox input with toggle/switch variant and indeterminate state support.
|
|
137
|
+
Can be used standalone or within CheckboxGroup.
|
|
138
|
+
|
|
139
|
+
**Examples:**
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Basic usage
|
|
143
|
+
import { Checkbox } from 'vuiii'
|
|
144
|
+
|
|
145
|
+
<Checkbox v-model="accepted" label="I accept the terms" />
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Switch variant (toggle)
|
|
150
|
+
<Checkbox v-model="enabled" switch label="Enable notifications" />
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// With description
|
|
155
|
+
<Checkbox
|
|
156
|
+
v-model="newsletter"
|
|
157
|
+
label="Subscribe to newsletter"
|
|
158
|
+
description="Get weekly updates about new features"
|
|
159
|
+
/>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### CheckboxGroup
|
|
163
|
+
|
|
164
|
+
**File:** `src/components/CheckboxGroup.vue`
|
|
165
|
+
|
|
166
|
+
Group of checkboxes for multi-select from a list of options.
|
|
167
|
+
Normalizes various option formats and supports custom value parsing.
|
|
168
|
+
|
|
169
|
+
**Examples:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// Basic usage with string array
|
|
173
|
+
import { CheckboxGroup } from 'vuiii'
|
|
174
|
+
|
|
175
|
+
<CheckboxGroup v-model="selectedFruits" :options="['Apple', 'Banana', 'Cherry']" />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// With object options and extractors
|
|
180
|
+
const permissions = [
|
|
181
|
+
{ id: 'read', name: 'Read', info: 'View content' },
|
|
182
|
+
{ id: 'write', name: 'Write', info: 'Edit content' },
|
|
183
|
+
{ id: 'delete', name: 'Delete', info: 'Remove content' }
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
<CheckboxGroup
|
|
187
|
+
v-model="selectedPermissions"
|
|
188
|
+
:options="permissions"
|
|
189
|
+
option-value="id"
|
|
190
|
+
option-label="name"
|
|
191
|
+
option-description="info"
|
|
192
|
+
/>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Inline layout (horizontal)
|
|
197
|
+
<CheckboxGroup
|
|
198
|
+
v-model="selected"
|
|
199
|
+
:options="['Option A', 'Option B', 'Option C']"
|
|
200
|
+
inline
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Divider
|
|
205
|
+
|
|
206
|
+
**File:** `src/components/Divider.vue`
|
|
207
|
+
|
|
208
|
+
Visual separator line for content sections.
|
|
209
|
+
Can be horizontal (default) or vertical.
|
|
210
|
+
|
|
211
|
+
**Examples:**
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Horizontal divider (default)
|
|
215
|
+
import { Divider } from 'vuiii'
|
|
216
|
+
|
|
217
|
+
<div>Section 1</div>
|
|
218
|
+
<Divider />
|
|
219
|
+
<div>Section 2</div>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Vertical divider (for inline content)
|
|
224
|
+
<div style="display: flex; align-items: center;">
|
|
225
|
+
<span>Item 1</span>
|
|
226
|
+
<Divider orientation="vertical" />
|
|
227
|
+
<span>Item 2</span>
|
|
228
|
+
</div>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// In FormFields (using FORM_DIVIDER constant)
|
|
233
|
+
import { FORM_DIVIDER } from 'vuiii'
|
|
234
|
+
|
|
235
|
+
const fields = [
|
|
236
|
+
{ name: 'name', component: Input, label: 'Name' },
|
|
237
|
+
FORM_DIVIDER,
|
|
238
|
+
{ name: 'email', component: Input, label: 'Email' },
|
|
239
|
+
]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Dropdown
|
|
243
|
+
|
|
244
|
+
**File:** `src/components/Dropdown.vue`
|
|
245
|
+
|
|
246
|
+
Popover dropdown component with customizable trigger and content.
|
|
247
|
+
Closes on click outside or Escape key. Supports programmatic control.
|
|
248
|
+
|
|
249
|
+
**Examples:**
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// Basic dropdown with default button trigger
|
|
253
|
+
import { Dropdown, DropdownMenu } from 'vuiii'
|
|
254
|
+
|
|
255
|
+
<Dropdown label="Options" variant="primary">
|
|
256
|
+
<DropdownMenu :items="menuItems" @itemClick="handleClick" />
|
|
257
|
+
</Dropdown>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// With custom trigger slot
|
|
262
|
+
<Dropdown>
|
|
263
|
+
<template #trigger="{ open, close, toggle, isOpen }">
|
|
264
|
+
<IconButton icon="ellipsis-vertical" @click="toggle()" />
|
|
265
|
+
</template>
|
|
266
|
+
|
|
267
|
+
<template #default="{ close }">
|
|
268
|
+
<div class="custom-dropdown-content">
|
|
269
|
+
<button @click="doSomething(); close()">Action</button>
|
|
270
|
+
</div>
|
|
271
|
+
</template>
|
|
272
|
+
</Dropdown>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// Programmatic control via ref
|
|
277
|
+
const dropdownRef = ref<DropdownRef>()
|
|
278
|
+
|
|
279
|
+
// Open/close programmatically
|
|
280
|
+
dropdownRef.value?.open()
|
|
281
|
+
dropdownRef.value?.close()
|
|
282
|
+
dropdownRef.value?.toggle()
|
|
283
|
+
|
|
284
|
+
// Check state
|
|
285
|
+
if (dropdownRef.value?.isOpen.value) { ... }
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### FilePicker
|
|
289
|
+
|
|
290
|
+
**File:** `src/components/FilePicker.vue`
|
|
291
|
+
|
|
292
|
+
File picker with drag-and-drop support. Opens native file dialog on click
|
|
293
|
+
and accepts files dropped onto the component.
|
|
294
|
+
|
|
295
|
+
**Examples:**
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Basic usage
|
|
299
|
+
import { FilePicker } from 'vuiii'
|
|
300
|
+
|
|
301
|
+
<FilePicker @files="handleFiles" />
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// Multiple files with accept filter
|
|
306
|
+
<FilePicker
|
|
307
|
+
multiple
|
|
308
|
+
accept="image/*"
|
|
309
|
+
label="Upload Images"
|
|
310
|
+
@files="(files) => images = files"
|
|
311
|
+
/>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// Multiple accept types as array
|
|
316
|
+
<FilePicker
|
|
317
|
+
:accept="['image/png', 'image/jpeg', '.pdf']"
|
|
318
|
+
label="Upload Documents"
|
|
319
|
+
@files="handleFiles"
|
|
320
|
+
/>
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### FormFields
|
|
324
|
+
|
|
325
|
+
**File:** `src/components/FormFields.vue`
|
|
326
|
+
|
|
327
|
+
Dynamic form generator that renders fields from a configuration array.
|
|
328
|
+
Supports vertical/horizontal layouts, nested rows, dividers, and validation integration.
|
|
329
|
+
|
|
330
|
+
@example <template #field:email="{ name, label, index }">Custom email input</template>
|
|
331
|
+
|
|
332
|
+
**Examples:**
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// Basic vertical form
|
|
336
|
+
import { FormFields, Input, Select } from 'vuiii'
|
|
337
|
+
|
|
338
|
+
const fields: FormField<UserData>[] = [
|
|
339
|
+
{ name: 'email', component: Input, label: 'Email', props: { type: 'email' } },
|
|
340
|
+
{ name: 'name', component: Input, label: 'Name' },
|
|
341
|
+
{ name: 'role', component: Select, label: 'Role', props: { options: ['admin', 'user'] } }
|
|
342
|
+
]
|
|
343
|
+
|
|
344
|
+
<FormFields :fields="fields" v-model="formData" />
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// Horizontal row (fields side-by-side) - nest arrays for horizontal grouping
|
|
349
|
+
const fields: FormFieldOrRow<UserData>[] = [
|
|
350
|
+
[
|
|
351
|
+
{ name: 'firstName', component: Input, label: 'First Name' },
|
|
352
|
+
{ name: 'lastName', component: Input, label: 'Last Name' },
|
|
353
|
+
],
|
|
354
|
+
{ name: 'email', component: Input, label: 'Email' },
|
|
355
|
+
]
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// With dividers between sections
|
|
360
|
+
import { FORM_DIVIDER } from 'vuiii'
|
|
361
|
+
|
|
362
|
+
const fields: FormFieldOrRow<UserData>[] = [
|
|
363
|
+
{ name: 'name', component: Input, label: 'Name' },
|
|
364
|
+
FORM_DIVIDER,
|
|
365
|
+
{ name: 'email', component: Input, label: 'Email' },
|
|
366
|
+
]
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### FormGroup
|
|
370
|
+
|
|
371
|
+
**File:** `src/components/FormGroup.vue`
|
|
372
|
+
|
|
373
|
+
Form field wrapper with label, description, hint, and error message support.
|
|
374
|
+
Used by FormFields internally, but can be used standalone for custom form layouts.
|
|
375
|
+
|
|
376
|
+
**Examples:**
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// Basic usage with label
|
|
380
|
+
import { FormGroup, Input } from 'vuiii'
|
|
381
|
+
|
|
382
|
+
<FormGroup label="Email">
|
|
383
|
+
<Input v-model="email" type="email" />
|
|
384
|
+
</FormGroup>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
// With description and hint
|
|
389
|
+
<FormGroup
|
|
390
|
+
label="Password"
|
|
391
|
+
description="Choose a strong password for your account"
|
|
392
|
+
hint="Must be at least 8 characters"
|
|
393
|
+
>
|
|
394
|
+
<Input v-model="password" type="password" />
|
|
395
|
+
</FormGroup>
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// With required indicator and validation error
|
|
400
|
+
<FormGroup
|
|
401
|
+
label="Username"
|
|
402
|
+
required
|
|
403
|
+
:error="errors.username"
|
|
404
|
+
>
|
|
405
|
+
<Input v-model="username" :invalid="!!errors.username" />
|
|
406
|
+
</FormGroup>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Icon
|
|
410
|
+
|
|
411
|
+
**File:** `src/components/Icon.vue`
|
|
412
|
+
|
|
413
|
+
Icon component that resolves icons through a customizable resolver.
|
|
414
|
+
Register your icon library using registerCustomIconResolver.
|
|
415
|
+
|
|
416
|
+
**Examples:**
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
// Basic usage
|
|
420
|
+
import { Icon } from 'vuiii'
|
|
421
|
+
|
|
422
|
+
<Icon name="check" />
|
|
423
|
+
<Icon name="user" size="large" />
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
// Different sizes
|
|
428
|
+
<Icon name="star" size="small" />
|
|
429
|
+
<Icon name="star" size="normal" />
|
|
430
|
+
<Icon name="star" size="large" />
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Register custom icon resolver (typically in app setup)
|
|
435
|
+
import { registerCustomIconResolver } from 'vuiii'
|
|
436
|
+
import { defineAsyncComponent } from 'vue'
|
|
437
|
+
|
|
438
|
+
registerCustomIconResolver((name) => {
|
|
439
|
+
return defineAsyncComponent(() => import(`./icons/${name}.vue`))
|
|
440
|
+
})
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### IconButton
|
|
444
|
+
|
|
445
|
+
**File:** `src/components/IconButton.vue`
|
|
446
|
+
|
|
447
|
+
Icon-only button. A simplified Button wrapper for actions that only need an icon.
|
|
448
|
+
|
|
449
|
+
**Examples:**
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
// Basic usage
|
|
453
|
+
import { IconButton } from 'vuiii'
|
|
454
|
+
|
|
455
|
+
<IconButton icon="pencil" @click="edit()" />
|
|
456
|
+
<IconButton icon="trash" variant="danger" @click="remove()" />
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
// Different variants
|
|
461
|
+
<IconButton icon="plus" variant="primary" />
|
|
462
|
+
<IconButton icon="check" variant="secondary" />
|
|
463
|
+
<IconButton icon="x-mark" variant="danger" />
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
// Different sizes
|
|
468
|
+
<IconButton icon="cog" size="small" />
|
|
469
|
+
<IconButton icon="cog" size="normal" />
|
|
470
|
+
<IconButton icon="cog" size="large" />
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### Input
|
|
474
|
+
|
|
475
|
+
**File:** `src/components/Input.vue`
|
|
476
|
+
|
|
477
|
+
Text input component with icon support, size variants, and validation states.
|
|
478
|
+
Wraps native input with InputWrapper for consistent styling.
|
|
479
|
+
|
|
480
|
+
**Examples:**
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
// Basic usage
|
|
484
|
+
import { Input } from 'vuiii'
|
|
485
|
+
|
|
486
|
+
<Input v-model="name" placeholder="Enter your name" />
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
// Different input types (passed via attrs)
|
|
491
|
+
<Input v-model="email" type="email" placeholder="Email" />
|
|
492
|
+
<Input v-model="password" type="password" placeholder="Password" />
|
|
493
|
+
<Input v-model="count" type="number" placeholder="Count" />
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
// With icons
|
|
498
|
+
<Input v-model="search" prefixIcon="magnifying-glass" placeholder="Search..." />
|
|
499
|
+
<Input v-model="email" suffixIcon="envelope" placeholder="Email" />
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### InputWrapper
|
|
503
|
+
|
|
504
|
+
**File:** `src/components/InputWrapper.vue`
|
|
505
|
+
|
|
506
|
+
Base wrapper component for input styling. Used internally by Input, Select, Autocomplete.
|
|
507
|
+
Provides consistent styling, icon slots, and size variants across all input components.
|
|
508
|
+
|
|
509
|
+
**Examples:**
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
// Typically used internally, but can be used for custom inputs
|
|
513
|
+
import { InputWrapper } from 'vuiii'
|
|
514
|
+
|
|
515
|
+
<InputWrapper size="normal" prefix-icon="user">
|
|
516
|
+
<input class="vuiii-input__nested" v-model="value" />
|
|
517
|
+
</InputWrapper>
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
// With validation state
|
|
522
|
+
<InputWrapper :invalid="hasError" size="normal">
|
|
523
|
+
<input class="vuiii-input__nested" v-model="value" />
|
|
524
|
+
</InputWrapper>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
// With clickable icons
|
|
529
|
+
<InputWrapper
|
|
530
|
+
suffix-icon="x-mark"
|
|
531
|
+
@suffix-icon-click="clearValue"
|
|
532
|
+
>
|
|
533
|
+
<input class="vuiii-input__nested" v-model="value" />
|
|
534
|
+
</InputWrapper>
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### RadioButtonGroup
|
|
538
|
+
|
|
539
|
+
**File:** `src/components/RadioButtonGroup.vue`
|
|
540
|
+
|
|
541
|
+
Button-styled radio group for single selection with visual button appearance.
|
|
542
|
+
Each option is rendered as a Button within a ButtonGroup.
|
|
543
|
+
|
|
544
|
+
**Examples:**
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
// Basic usage
|
|
548
|
+
<RadioButtonGroup v-model="view" :options="['List', 'Grid', 'Table']" />
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
// With object options
|
|
553
|
+
<RadioButtonGroup
|
|
554
|
+
v-model="status"
|
|
555
|
+
:options="[{ id: 'active', name: 'Active' }, { id: 'inactive', name: 'Inactive' }]"
|
|
556
|
+
option-value="id"
|
|
557
|
+
option-label="name"
|
|
558
|
+
/>
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
// With icons
|
|
563
|
+
<RadioButtonGroup
|
|
564
|
+
v-model="view"
|
|
565
|
+
:options="[
|
|
566
|
+
{ value: 'list', label: 'List', icon: 'list' },
|
|
567
|
+
{ value: 'grid', label: 'Grid', icon: 'grid' }
|
|
568
|
+
]"
|
|
569
|
+
option-value="value"
|
|
570
|
+
option-label="label"
|
|
571
|
+
option-icon="icon"
|
|
572
|
+
/>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### RadioGroup
|
|
576
|
+
|
|
577
|
+
**File:** `src/components/RadioGroup.vue`
|
|
578
|
+
|
|
579
|
+
Radio button group for single selection from a list of options.
|
|
580
|
+
Normalizes various option formats and supports custom value parsing.
|
|
581
|
+
|
|
582
|
+
**Examples:**
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
// Basic usage with string array
|
|
586
|
+
import { RadioGroup } from 'vuiii'
|
|
587
|
+
|
|
588
|
+
<RadioGroup v-model="color" :options="['Red', 'Green', 'Blue']" />
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
// With object options and extractors
|
|
593
|
+
const plans = [
|
|
594
|
+
{ id: 'free', name: 'Free', info: '0$/month' },
|
|
595
|
+
{ id: 'pro', name: 'Pro', info: '10$/month' },
|
|
596
|
+
{ id: 'enterprise', name: 'Enterprise', info: 'Contact us' }
|
|
597
|
+
]
|
|
598
|
+
|
|
599
|
+
<RadioGroup
|
|
600
|
+
v-model="selectedPlan"
|
|
601
|
+
:options="plans"
|
|
602
|
+
option-value="id"
|
|
603
|
+
option-label="name"
|
|
604
|
+
option-description="info"
|
|
605
|
+
/>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
```typescript
|
|
609
|
+
// Inline layout (horizontal)
|
|
610
|
+
<RadioGroup
|
|
611
|
+
v-model="size"
|
|
612
|
+
:options="['Small', 'Medium', 'Large']"
|
|
613
|
+
inline
|
|
614
|
+
/>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Select
|
|
618
|
+
|
|
619
|
+
**File:** `src/components/Select.vue`
|
|
620
|
+
|
|
621
|
+
Native select dropdown with support for various option formats and type parsing.
|
|
622
|
+
Normalizes arrays, objects, and grouped options into a consistent format.
|
|
623
|
+
|
|
624
|
+
**Examples:**
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
// Basic usage with string array
|
|
628
|
+
import { Select } from 'vuiii'
|
|
629
|
+
|
|
630
|
+
<Select v-model="color" :options="['Red', 'Green', 'Blue']" />
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
// With object array and extractors
|
|
635
|
+
const countries = [
|
|
636
|
+
{ code: 'us', name: 'United States' },
|
|
637
|
+
{ code: 'uk', name: 'United Kingdom' }
|
|
638
|
+
]
|
|
639
|
+
|
|
640
|
+
<Select
|
|
641
|
+
v-model="country"
|
|
642
|
+
:options="countries"
|
|
643
|
+
option-value="code"
|
|
644
|
+
option-label="name"
|
|
645
|
+
placeholder="Select a country"
|
|
646
|
+
/>
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
// With key-value object options
|
|
651
|
+
const statuses = { draft: 'Draft', published: 'Published', archived: 'Archived' }
|
|
652
|
+
|
|
653
|
+
<Select v-model="status" :options="statuses" />
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Table
|
|
657
|
+
|
|
658
|
+
**File:** `src/components/Table.vue`
|
|
659
|
+
|
|
660
|
+
Data table component with sorting, custom columns, cell formatting, and row customization.
|
|
661
|
+
Supports dynamic slot-based cell rendering and sortable columns.
|
|
662
|
+
|
|
663
|
+
**Examples:**
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
// Basic table with typed columns
|
|
667
|
+
import { Table } from 'vuiii'
|
|
668
|
+
import type { TableColumn } from 'vuiii'
|
|
669
|
+
|
|
670
|
+
type User = { id: number; name: string; email: string }
|
|
671
|
+
|
|
672
|
+
const columns: TableColumn<User>[] = [
|
|
673
|
+
{ name: 'name', label: 'Name' },
|
|
674
|
+
{ name: 'email', label: 'Email' }
|
|
675
|
+
]
|
|
676
|
+
|
|
677
|
+
<Table :items="users" :columns="columns" />
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
```typescript
|
|
681
|
+
// With custom cell rendering via slots
|
|
682
|
+
<Table :items="users" :columns="columns">
|
|
683
|
+
<template #column:name="{ item, value }">
|
|
684
|
+
<strong>{{ value }}</strong>
|
|
685
|
+
</template>
|
|
686
|
+
<template #column:status="{ item }">
|
|
687
|
+
<Badge :variant="item.active ? 'success' : 'danger'">
|
|
688
|
+
{{ item.active ? 'Active' : 'Inactive' }}
|
|
689
|
+
</Badge>
|
|
690
|
+
</template>
|
|
691
|
+
</Table>
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
// With row actions (rowOptions slot)
|
|
696
|
+
<Table :items="users" :columns="columns">
|
|
697
|
+
<template #rowOptions="{ item, index }">
|
|
698
|
+
<IconButton icon="pencil" @click="edit(item)" />
|
|
699
|
+
<IconButton icon="trash" @click="remove(item)" />
|
|
700
|
+
</template>
|
|
701
|
+
</Table>
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Textarea
|
|
705
|
+
|
|
706
|
+
**File:** `src/components/Textarea.vue`
|
|
707
|
+
|
|
708
|
+
Multi-line text input with InputWrapper styling.
|
|
709
|
+
Supports prefix icon and programmatic control.
|
|
710
|
+
|
|
711
|
+
**Examples:**
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
// Basic usage
|
|
715
|
+
import { Textarea } from 'vuiii'
|
|
716
|
+
|
|
717
|
+
<Textarea v-model="description" placeholder="Enter description..." />
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
// With rows and placeholder
|
|
722
|
+
<Textarea
|
|
723
|
+
v-model="content"
|
|
724
|
+
placeholder="Write your message..."
|
|
725
|
+
rows="5"
|
|
726
|
+
/>
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
// With prefix icon
|
|
731
|
+
<Textarea v-model="notes" prefix-icon="document-text" placeholder="Notes..." />
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Typography
|
|
735
|
+
|
|
736
|
+
**File:** `src/components/Typography.vue`
|
|
737
|
+
|
|
738
|
+
Typography component for consistent text styling.
|
|
739
|
+
Automatically selects appropriate HTML tag based on variant.
|
|
740
|
+
|
|
741
|
+
**Examples:**
|
|
742
|
+
|
|
743
|
+
```typescript
|
|
744
|
+
// Different variants
|
|
745
|
+
import { Typography } from 'vuiii'
|
|
746
|
+
|
|
747
|
+
<Typography variant="display">Display Text</Typography>
|
|
748
|
+
<Typography variant="heading1">Heading 1</Typography>
|
|
749
|
+
<Typography variant="heading2">Heading 2</Typography>
|
|
750
|
+
<Typography variant="body1">Body text paragraph</Typography>
|
|
751
|
+
<Typography variant="caption">Small caption text</Typography>
|
|
752
|
+
<Typography variant="label">Form label</Typography>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
// Automatic tag selection
|
|
757
|
+
<Typography variant="heading1">Renders as h1</Typography>
|
|
758
|
+
<Typography variant="body1">Renders as p</Typography>
|
|
759
|
+
<Typography variant="label">Renders as span</Typography>
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
```typescript
|
|
763
|
+
// Override the HTML tag
|
|
764
|
+
<Typography variant="heading1" tag="h2">
|
|
765
|
+
Styled as heading1, but renders as h2
|
|
766
|
+
</Typography>
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
## Composables
|
|
770
|
+
|
|
771
|
+
### dialogStack
|
|
772
|
+
|
|
773
|
+
**File:** `src/dialogStack.ts`
|
|
774
|
+
|
|
775
|
+
Dialog stack system for managing modal dialogs with promise-based APIs.
|
|
776
|
+
Supports custom dialog components, alerts, and confirmation dialogs.
|
|
777
|
+
|
|
778
|
+
**Examples:**
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
// Setup: Add DialogStack component to your app root
|
|
782
|
+
import { DialogStack } from 'vuiii'
|
|
783
|
+
|
|
784
|
+
// In App.vue
|
|
785
|
+
<template>
|
|
786
|
+
<router-view />
|
|
787
|
+
<DialogStack />
|
|
788
|
+
</template>
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
```typescript
|
|
792
|
+
// Open a simple alert
|
|
793
|
+
import { useDialogStack } from 'vuiii'
|
|
794
|
+
|
|
795
|
+
const dialog = useDialogStack()
|
|
796
|
+
await dialog.alert('Operation completed!')
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### snackbar
|
|
800
|
+
|
|
801
|
+
**File:** `src/snackbar.ts`
|
|
802
|
+
|
|
803
|
+
Snackbar/toast notification system for displaying brief messages.
|
|
804
|
+
Messages auto-dismiss after a configurable duration (default 7 seconds).
|
|
805
|
+
|
|
806
|
+
**Examples:**
|
|
807
|
+
|
|
808
|
+
```typescript
|
|
809
|
+
// Setup: Add SnackbarStack component to your app root
|
|
810
|
+
import { SnackbarStack } from 'vuiii'
|
|
811
|
+
|
|
812
|
+
// In App.vue
|
|
813
|
+
<template>
|
|
814
|
+
<router-view />
|
|
815
|
+
<SnackbarStack />
|
|
816
|
+
</template>
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
```typescript
|
|
820
|
+
// Show success message
|
|
821
|
+
import { useSnackbar } from 'vuiii'
|
|
822
|
+
|
|
823
|
+
const snackbar = useSnackbar()
|
|
824
|
+
snackbar.success('Item saved!')
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### useCursor
|
|
828
|
+
|
|
829
|
+
**File:** `src/composables/useCursor.ts`
|
|
830
|
+
|
|
831
|
+
Manages cursor position for navigating through arrays.
|
|
832
|
+
Used internally by Autocomplete for keyboard navigation.
|
|
833
|
+
|
|
834
|
+
**Examples:**
|
|
835
|
+
|
|
836
|
+
```typescript
|
|
837
|
+
// Basic usage
|
|
838
|
+
import { useCursor } from 'vuiii'
|
|
839
|
+
|
|
840
|
+
const items = ref(['Apple', 'Banana', 'Cherry'])
|
|
841
|
+
|
|
842
|
+
const { cursorIndex, cursorItem, moveCursorForward, moveCursorBack, resetCursor } = useCursor(items)
|
|
843
|
+
|
|
844
|
+
console.log(cursorItem.value) // 'Apple'
|
|
845
|
+
moveCursorForward()
|
|
846
|
+
console.log(cursorItem.value) // 'Banana'
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
```typescript
|
|
850
|
+
// With cycling
|
|
851
|
+
const { moveCursorForward } = useCursor(items, { cycle: true })
|
|
852
|
+
// At last item, moveCursorForward() goes back to first
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
### useDropArea
|
|
856
|
+
|
|
857
|
+
**File:** `src/composables/useDropArea.ts`
|
|
858
|
+
|
|
859
|
+
Enables drag-and-drop file handling on an element.
|
|
860
|
+
Provides dropzone active state for visual feedback.
|
|
861
|
+
|
|
862
|
+
**Examples:**
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
// Basic usage
|
|
866
|
+
import { useDropArea } from 'vuiii'
|
|
867
|
+
|
|
868
|
+
const dropElement = ref<HTMLElement>()
|
|
869
|
+
|
|
870
|
+
const { isDropzoneActive } = useDropArea(
|
|
871
|
+
dropElement,
|
|
872
|
+
(files) => console.log('Dropped files:', files)
|
|
873
|
+
)
|
|
874
|
+
|
|
875
|
+
// In template
|
|
876
|
+
<div
|
|
877
|
+
ref="dropElement"
|
|
878
|
+
:class="{ 'dropzone-active': isDropzoneActive }"
|
|
879
|
+
>
|
|
880
|
+
Drop files here
|
|
881
|
+
</div>
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
885
|
+
// With file type filter
|
|
886
|
+
useDropArea(dropElement, handleFiles, { accept: 'image/*' })
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
### useLoadData
|
|
890
|
+
|
|
891
|
+
**File:** `src/composables/useLoadData.ts`
|
|
892
|
+
|
|
893
|
+
Wraps a data loading function with loading state, error handling,
|
|
894
|
+
and optional success/error messages. Built on top of useSubmitAction.
|
|
895
|
+
|
|
896
|
+
**Examples:**
|
|
897
|
+
|
|
898
|
+
```typescript
|
|
899
|
+
// Basic data loading
|
|
900
|
+
import { useLoadData } from 'vuiii'
|
|
901
|
+
|
|
902
|
+
const { load, isLoading, data } = useLoadData(
|
|
903
|
+
() => api.fetchUsers()
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
onMounted(load)
|
|
907
|
+
|
|
908
|
+
// In template
|
|
909
|
+
<div v-if="isLoading">Loading...</div>
|
|
910
|
+
<div v-else>{{ data }}</div>
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
```typescript
|
|
914
|
+
// With immediate loading
|
|
915
|
+
const { isLoading, data } = useLoadData(() => api.fetchUsers(), { immediate: true })
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
### useLoadPaginatedData
|
|
919
|
+
|
|
920
|
+
**File:** `src/composables/useLoadPaginatedData.ts`
|
|
921
|
+
|
|
922
|
+
Extends useLoadData with pagination support for loading data in pages.
|
|
923
|
+
Provides methods for loading specific pages, next/previous navigation,
|
|
924
|
+
and optional append mode for infinite scroll.
|
|
925
|
+
|
|
926
|
+
**Examples:**
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
// Basic paginated data loading
|
|
930
|
+
import { useLoadPaginatedData } from 'vuiii'
|
|
931
|
+
import type { PaginatedData } from 'vuiii'
|
|
932
|
+
|
|
933
|
+
const { items, pagination, loadPage, isLoading } = useLoadPaginatedData(({ page, itemsPerPage }) =>
|
|
934
|
+
api.getUsers({ page, itemsPerPage }),
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
onMounted(() => loadPage(1))
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
```typescript
|
|
941
|
+
// With immediate loading
|
|
942
|
+
const { items, pagination } = useLoadPaginatedData(({ page, itemsPerPage }) => api.getItems({ page, itemsPerPage }), {
|
|
943
|
+
immediate: true,
|
|
944
|
+
})
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
### useSubmitAction
|
|
948
|
+
|
|
949
|
+
**File:** `src/composables/useSubmitAction.ts`
|
|
950
|
+
|
|
951
|
+
Wraps an async action with submission state tracking, error handling,
|
|
952
|
+
success/error messages, and optional redirect on success.
|
|
953
|
+
|
|
954
|
+
**Examples:**
|
|
955
|
+
|
|
956
|
+
```typescript
|
|
957
|
+
// Basic form submission
|
|
958
|
+
import { useSubmitAction } from 'vuiii'
|
|
959
|
+
|
|
960
|
+
const { submit, isSubmitting } = useSubmitAction(
|
|
961
|
+
(data) => api.createUser(data),
|
|
962
|
+
{
|
|
963
|
+
successMessage: 'User created!',
|
|
964
|
+
errorMessage: 'Failed to create user',
|
|
965
|
+
redirectOnSuccess: { name: 'users' }
|
|
966
|
+
}
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
// In template
|
|
970
|
+
<Button :loading="isSubmitting" @click="submit(formData)">Save</Button>
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
```typescript
|
|
974
|
+
// With confirmation before submit
|
|
975
|
+
const { submit, isSubmitting } = useSubmitAction((id) => api.deleteUser(id), {
|
|
976
|
+
onBeforeSubmit: async ({ dialog }) => {
|
|
977
|
+
return await dialog.confirm('Are you sure?')
|
|
978
|
+
},
|
|
979
|
+
successMessage: 'User deleted',
|
|
980
|
+
})
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
### useValidation
|
|
984
|
+
|
|
985
|
+
**File:** `src/composables/useValidation.ts`
|
|
986
|
+
|
|
987
|
+
Manages form validation state with async validation support.
|
|
988
|
+
Integrates with FormFields via the validatedFields computed property.
|
|
989
|
+
|
|
990
|
+
**Examples:**
|
|
991
|
+
|
|
992
|
+
```typescript
|
|
993
|
+
// Basic validation
|
|
994
|
+
import { useValidation } from 'vuiii'
|
|
995
|
+
import type { ValidationResults } from 'vuiii'
|
|
996
|
+
|
|
997
|
+
type FormData = { email: string; password: string }
|
|
998
|
+
|
|
999
|
+
function validateForm(data: FormData): ValidationResults<FormData> {
|
|
1000
|
+
const errors: Record<string, string> = {}
|
|
1001
|
+
|
|
1002
|
+
if (!data.email) errors.email = 'Email is required'
|
|
1003
|
+
if (!data.password) errors.password = 'Password is required'
|
|
1004
|
+
|
|
1005
|
+
return {
|
|
1006
|
+
isValid: Object.keys(errors).length === 0,
|
|
1007
|
+
isInvalid: Object.keys(errors).length > 0,
|
|
1008
|
+
errorMessages: errors,
|
|
1009
|
+
validatedFields: {
|
|
1010
|
+
email: { isInvalid: !!errors.email, errorMessage: errors.email },
|
|
1011
|
+
password: { isInvalid: !!errors.password, errorMessage: errors.password },
|
|
1012
|
+
},
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
const { validate, isValid, validatedFields } = useValidation(validateForm)
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
```typescript
|
|
1020
|
+
// With FormFields integration
|
|
1021
|
+
<FormFields
|
|
1022
|
+
:fields="fields"
|
|
1023
|
+
v-model="formData"
|
|
1024
|
+
:validation-results="validatedFields"
|
|
1025
|
+
/>
|
|
1026
|
+
|
|
1027
|
+
async function submit() {
|
|
1028
|
+
if (await validate(formData)) {
|
|
1029
|
+
// form is valid, proceed with submission
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
## Utilities
|
|
1035
|
+
|
|
1036
|
+
### iconsResolver
|
|
1037
|
+
|
|
1038
|
+
**File:** `src/utils/iconsResolver.ts`
|
|
1039
|
+
|
|
1040
|
+
Icon resolution system for the Icon component.
|
|
1041
|
+
Allows registering custom icon libraries (Heroicons, FontAwesome, etc.)
|
|
1042
|
+
|
|
1043
|
+
### normalizeOptions
|
|
1044
|
+
|
|
1045
|
+
**File:** `src/utils/normalizeOptions.ts`
|
|
1046
|
+
|
|
1047
|
+
Utilities for normalizing various option formats into a consistent Option[] structure.
|
|
1048
|
+
Used by Select, Autocomplete, RadioGroup, CheckboxGroup, and RadioButtonGroup components.
|
|
1049
|
+
|
|
1050
|
+
## Option Parsing
|
|
1051
|
+
|
|
1052
|
+
Components that display selectable options (Select, Autocomplete, RadioGroup, CheckboxGroup,
|
|
1053
|
+
RadioButtonGroup) support flexible option formats. The following props control how options
|
|
1054
|
+
are parsed:
|
|
1055
|
+
|
|
1056
|
+
### Extractor Props
|
|
1057
|
+
|
|
1058
|
+
| Prop | Description | Components |
|
|
1059
|
+
| -------------------- | -------------------------------------------------- | --------------------------------------------------------- |
|
|
1060
|
+
| `option-value` | Key or function to extract the option's value | All |
|
|
1061
|
+
| `option-label` | Key or function to extract the display label | All |
|
|
1062
|
+
| `option-disabled` | Key or function to determine if option is disabled | All |
|
|
1063
|
+
| `option-description` | Key or function to extract description text | RadioGroup, CheckboxGroup, Autocomplete, RadioButtonGroup |
|
|
1064
|
+
| `option-icon` | Key or function to extract icon name | Autocomplete, RadioButtonGroup |
|
|
1065
|
+
| `group-label` | Key or function to extract group label | Select, Autocomplete |
|
|
1066
|
+
| `group-options` | Key or function to extract group's options array | Select, Autocomplete |
|
|
1067
|
+
|
|
1068
|
+
### Supported Option Formats
|
|
1069
|
+
|
|
1070
|
+
**1. Primitive Array** - Value and label are the same
|
|
1071
|
+
|
|
1072
|
+
```ts
|
|
1073
|
+
:options="['Apple', 'Banana', 'Cherry']"
|
|
1074
|
+
:options="[1, 2, 3, 4, 5]"
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
**2. Object Array** - Use extractors to specify which properties to use
|
|
1078
|
+
|
|
1079
|
+
```ts
|
|
1080
|
+
:options="[{ id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }]"
|
|
1081
|
+
option-value="id"
|
|
1082
|
+
option-label="name"
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
**3. Key-Value Object** - Keys become values, values become labels
|
|
1086
|
+
|
|
1087
|
+
```ts
|
|
1088
|
+
:options="{ draft: 'Draft', published: 'Published', archived: 'Archived' }"
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
**4. Grouped Options** - For Select and Autocomplete with optgroup support
|
|
1092
|
+
|
|
1093
|
+
```ts
|
|
1094
|
+
:options="[
|
|
1095
|
+
{ category: 'Fruits', items: [{ id: 1, name: 'Apple' }] },
|
|
1096
|
+
{ category: 'Vegetables', items: [{ id: 2, name: 'Carrot' }] }
|
|
1097
|
+
]"
|
|
1098
|
+
group-label="category"
|
|
1099
|
+
group-options="items"
|
|
1100
|
+
option-value="id"
|
|
1101
|
+
option-label="name"
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
### Function Extractors
|
|
1105
|
+
|
|
1106
|
+
Instead of property keys, you can use functions for complex extraction:
|
|
1107
|
+
|
|
1108
|
+
```ts
|
|
1109
|
+
:option-label="(user) => `${user.firstName} ${user.lastName}`"
|
|
1110
|
+
:option-value="(item) => item.id"
|
|
1111
|
+
:option-disabled="(item) => item.status === 'inactive'"
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1114
|
+
## Types
|
|
1115
|
+
|
|
1116
|
+
### types
|
|
1117
|
+
|
|
1118
|
+
**File:** `src/types.ts`
|
|
1119
|
+
|
|
1120
|
+
Core type definitions for vuiii components.
|
|
1121
|
+
Import these types for TypeScript support in your application.
|