@appsbd/vue3-appsbd-ui 1.0.13 → 1.0.14
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/.ai/ai_ref_AbChatInput.md +211 -0
- package/.ai/ai_ref_AbChatInputMenuItem.md +55 -0
- package/.ai/ai_ref_AbFileUploader.md +34 -6
- package/.ai/ai_ref_AbFormCheck.md +71 -12
- package/.ai/ai_ref_AbInputField.md +2 -0
- package/.ai/ai_ref_AbNumberField.md +1 -0
- package/.ai/ai_ref_abDate.md +58 -0
- package/.ai/ai_ref_useFileValidator.md +10 -5
- package/AI_REFERENCE.md +6 -3
- package/CHANGELOG.md +19 -2
- package/dist/style.css +1 -1
- package/dist/vue3-appsbd-ui.cjs.js +96 -76
- package/dist/vue3-appsbd-ui.es.js +11787 -10604
- package/package.json +10 -10
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# AbChatInput — AI Reference
|
|
2
|
+
|
|
3
|
+
A ChatGPT-style auto-growing chat/message composer. Use for AI chat interfaces, comment boxes that need to grow with content, or any message input needing configurable Enter/Shift+Enter/Ctrl+Enter submit behavior. Pair with `AbChatInputMenuItem` for the built-in add/more dropdown.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Not globally registered — import it explicitly:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { AbChatInput, AbChatInputMenuItem } from 'vue3-appsbd-ui';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
No extra peer deps beyond the library's own (`@lucide/vue` for the default "+" icon).
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```vue
|
|
18
|
+
<template>
|
|
19
|
+
<AbChatInput v-model="message" placeholder="Ask anything" @submit="onSubmit">
|
|
20
|
+
<template #right>
|
|
21
|
+
<button type="button" class="btn btn-primary btn-sm rounded-circle">
|
|
22
|
+
<ArrowUp :size="16" />
|
|
23
|
+
</button>
|
|
24
|
+
</template>
|
|
25
|
+
</AbChatInput>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup>
|
|
29
|
+
import { ref } from 'vue';
|
|
30
|
+
import { AbChatInput } from 'vue3-appsbd-ui';
|
|
31
|
+
import { ArrowUp } from '@lucide/vue';
|
|
32
|
+
|
|
33
|
+
const message = ref('');
|
|
34
|
+
function onSubmit({ message, files }) {
|
|
35
|
+
console.log(message, files);
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Add/more dropdown (0 items = no trigger, 1 item = direct action with no popover, 2+ items = a real dropdown):
|
|
41
|
+
|
|
42
|
+
```vue
|
|
43
|
+
<template>
|
|
44
|
+
<AbChatInput v-model="message">
|
|
45
|
+
<template #multiple-input>
|
|
46
|
+
<AbChatInputMenuItem v-for="item in menuItems" :key="item.name" v-bind="item" />
|
|
47
|
+
</template>
|
|
48
|
+
</AbChatInput>
|
|
49
|
+
</template>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
File attachments — selection stays the consumer's job, validation/storage/preview are internal. Every content
|
|
53
|
+
slot (`left`/`right`/`menu-trigger`/`single-input`/`multiple-input`) is scoped, handing back `addToAttach` (opens
|
|
54
|
+
a native file picker and routes the selection through `addFiles`) among other methods — no template
|
|
55
|
+
`<input type="file">` and no ref needed:
|
|
56
|
+
|
|
57
|
+
```vue
|
|
58
|
+
<template>
|
|
59
|
+
<AbChatInput
|
|
60
|
+
v-model="message"
|
|
61
|
+
v-model:files="attachedFiles"
|
|
62
|
+
:max-file-size="2"
|
|
63
|
+
:allowed-extensions="['jpg', 'jpeg', 'png', 'pdf']"
|
|
64
|
+
>
|
|
65
|
+
<template #single-input="{ addToAttach }">
|
|
66
|
+
<AbChatInputMenuItem
|
|
67
|
+
:icon="Paperclip"
|
|
68
|
+
name="Upload file"
|
|
69
|
+
:action="() => addToAttach({ accept: '.jpg,.jpeg,.png,.pdf' })"
|
|
70
|
+
/>
|
|
71
|
+
</template>
|
|
72
|
+
</AbChatInput>
|
|
73
|
+
</template>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Voice input
|
|
77
|
+
|
|
78
|
+
Uses the browser's native Web Speech API (`SpeechRecognition`) — no extra dependency, no API key. A built-in mic
|
|
79
|
+
button renders in the `right` area (next to the `right` slot) whenever `showVoiceButton` is `true` (default).
|
|
80
|
+
Clicking it (or calling `startRecording()`) swaps the whole composer row for a full-width recording bar — a live
|
|
81
|
+
audio-reactive waveform (via `getUserMedia` + `AnalyserNode`) plus three controls:
|
|
82
|
+
|
|
83
|
+
- **✕ cancel** — discards everything spoken this session, reverting `modelValue` to what it was before recording started.
|
|
84
|
+
- **■ stop** — stops recording and keeps the transcribed text in the textarea (no submit).
|
|
85
|
+
- **↑ submit** — stops recording, keeps the text, then fires `submit` immediately.
|
|
86
|
+
|
|
87
|
+
Recognized speech is appended to the existing `modelValue` (not replaced), one final phrase at a time — interim
|
|
88
|
+
(still-speaking) text is not shown live.
|
|
89
|
+
|
|
90
|
+
A small language-code badge (e.g. `EN`, `BN`) sits on the mic button's corner. Clicking it opens an `AbPopover`
|
|
91
|
+
with a searchable list of ~130 BCP-47 locales; picking one sets that recognition session's `SpeechRecognition.lang`
|
|
92
|
+
and persists the choice to `localStorage` (key `apbd-chat-input-voice-lang`) so it's remembered next visit. This
|
|
93
|
+
never touches the browser's own language/locale settings — only this component's own recognizer instance.
|
|
94
|
+
|
|
95
|
+
Not supported in Firefox/Safari — the mic button still renders there but is `disabled`, with a tooltip explaining
|
|
96
|
+
why. Requires the browser's mic permission prompt to be accepted.
|
|
97
|
+
|
|
98
|
+
## Props
|
|
99
|
+
|
|
100
|
+
| Name | Type | Default | Description |
|
|
101
|
+
| --- | --- | --- | --- |
|
|
102
|
+
| `modelValue` | `String` | `""` | Two-way-bound message text. |
|
|
103
|
+
| `files` | `Array` | `[]` | v-model:files — see "Attached file shape" below. |
|
|
104
|
+
| `placeholder` | `String` | `""` | Textarea placeholder (translated). |
|
|
105
|
+
| `disabled` | `Boolean` | `false` | Disables the textarea and the menu trigger. |
|
|
106
|
+
| `readonly` | `Boolean` | `false` | Makes the textarea read-only. |
|
|
107
|
+
| `loading` | `Boolean` | `false` | Visual loading state (CSS hook only — does not itself disable input). |
|
|
108
|
+
| `minHeight` | `Number` | `52` | Minimum textarea height in px. Also the threshold: past this, the composer switches to the "grown" stacked layout (see below). |
|
|
109
|
+
| `maxHeight` | `Number` | `200` | Maximum textarea height in px; internal scroll kicks in beyond this. |
|
|
110
|
+
| `submitOnEnter` | `Boolean` | `true` | `true`: Enter submits, Shift+Enter inserts a newline. `false`: Enter inserts a newline, Ctrl+Enter/Cmd+Enter submits. |
|
|
111
|
+
| `allowNewLine` | `Boolean` | `true` | If `false`, Enter never inserts a newline regardless of `submitOnEnter`. |
|
|
112
|
+
| `autoFocus` | `Boolean` | `false` | Focus the textarea on mount. |
|
|
113
|
+
| `autoPreview` | `Boolean` | `true` | When `true`, clicking a file chip opens the built-in preview lightbox. When `false`, only the `file-click` event fires. |
|
|
114
|
+
| `maxFileSize` | `Number` | `null` | Max size in MB per file. `null` = no limit. Enforced by `addFiles()`. |
|
|
115
|
+
| `allowedExtensions` | `Array` | `[]` | Case-insensitive allowed extensions (e.g. `['jpg','png','pdf']`). Empty = all types allowed. Enforced by `addFiles()`. |
|
|
116
|
+
| `containerClass` | `String` | `undefined` | Wrapper class; falls back to `globalConfig.inputContainerClass`. |
|
|
117
|
+
| `borderRadius` | `String` | `"1.5rem"` | Composer roundness — any CSS length (e.g. `"0.5rem"`, `"8px"`, `"1.5rem"`). |
|
|
118
|
+
| `filePreviewWidth` | `Number` | `24` | Width (px) of each attached file's thumbnail/icon in the chip. |
|
|
119
|
+
| `filePreviewHeight` | `Number` | `24` | Height (px) of each attached file's thumbnail/icon in the chip. |
|
|
120
|
+
| `showFileName` | `Boolean` | `true` | Show/hide the filename text next to the chip thumbnail. |
|
|
121
|
+
| `showVoiceButton` | `Boolean` | `true` | Show/hide the built-in mic button (see "Voice input" below). Set `false` to build custom voice UI via slots instead. |
|
|
122
|
+
|
|
123
|
+
## Events
|
|
124
|
+
|
|
125
|
+
| Event | Payload | Description |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| `update:modelValue` | `string` | v-model sync. |
|
|
128
|
+
| `update:files` | `FileEntry[]` | v-model:files sync — fired after `addFiles`/`removeFile`/`clearFiles`. |
|
|
129
|
+
| `submit` | `{ message: string, files: FileEntry[] }` | Fired on Enter/Ctrl+Enter/Cmd+Enter per `submitOnEnter`. Not fired when `disabled`/`readonly`. |
|
|
130
|
+
| `focus` / `blur` | `FocusEvent` | Forwarded native events. |
|
|
131
|
+
| `keydown` | `KeyboardEvent` | Forwarded native event; fires before any submit/newline logic runs. |
|
|
132
|
+
| `file-click` | `FileEntry` | A file chip was clicked (fires regardless of `autoPreview`). |
|
|
133
|
+
| `file-remove` | `FileEntry` | A file chip's remove button was clicked. |
|
|
134
|
+
| `file-reject` | `{ file: File, reason: string }` | A file failed `maxFileSize`/`allowedExtensions` validation. A `useToast` error is also shown. |
|
|
135
|
+
| `voice-start` | — | Voice recording started (mic button clicked or `startRecording()` called). |
|
|
136
|
+
| `voice-stop` | — | Recording stopped normally (■ button, ↑ submit button, `stopRecording()`, or the browser ending it on its own) — transcribed text is kept in `modelValue`. |
|
|
137
|
+
| `voice-cancel` | — | Recording was cancelled (✕ button or `cancelRecording()`) — `modelValue` is reverted to what it was before recording started. |
|
|
138
|
+
| `voice-error` | `Error \| SpeechRecognitionErrorEvent` | Mic permission was denied, or the recognition engine errored. A `useToast` error is also shown (except benign `no-speech`/`aborted` errors). |
|
|
139
|
+
|
|
140
|
+
## Slots
|
|
141
|
+
|
|
142
|
+
| Name | Description |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `left` | Left action area (e.g. an attachment button). Scoped — see below. |
|
|
145
|
+
| `right` | Right action area (e.g. send/mic button). Scoped — see below. |
|
|
146
|
+
| `menu-trigger` | Overrides the default "+" icon on the add/more trigger. Only rendered when the trigger itself renders (see below). Scoped — see below. |
|
|
147
|
+
| `single-input` | One static `AbChatInputMenuItem` for the add/more dropdown. Scoped — see below. |
|
|
148
|
+
| `multiple-input` | A `v-for`'d set of `AbChatInputMenuItem`s for the add/more dropdown. Scoped — see below. |
|
|
149
|
+
|
|
150
|
+
**All five slots are scoped**, receiving the same props so slot content can drive the composer directly:
|
|
151
|
+
|
|
152
|
+
| Scoped prop | Description |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `addToAttach(options?)` | Opens a native file picker and routes the selection through `addFiles`. `options`: `{ accept, multiple }` (`multiple` defaults to `true`). |
|
|
155
|
+
| `addFiles(files)` | Same as the exposed method — validates and appends an already-obtained `File[]`/`FileList` (drag-drop, paste, etc.). |
|
|
156
|
+
| `removeFile(id)` | Same as the exposed method. |
|
|
157
|
+
| `clearFiles()` | Same as the exposed method. |
|
|
158
|
+
| `updateText(text)` | Replaces the message text (fires `update:modelValue`). |
|
|
159
|
+
| `focus()` | Focuses the textarea. |
|
|
160
|
+
|
|
161
|
+
A single-item `#single-input`/`#multiple-input` action can use these directly — `onMenuTriggerClick`'s no-dropdown
|
|
162
|
+
fast path reads the item's `action` prop with these same bindings applied, so `:action="addToAttach"` works there too.
|
|
163
|
+
|
|
164
|
+
**Layout — single line vs. "grown"**: below `minHeight` worth of content (one line), `left`/textarea/`right` share a single row, centered. Past that, the composer switches to a ChatGPT-style stacked layout: the textarea becomes its own full-width row on top, and `left`/`right` wrap onto a second full-width row below it (`right` stays pinned to that row's end even when `left` isn't rendered at all). This is purely CSS-driven off the same measured content height — no extra prop.
|
|
165
|
+
|
|
166
|
+
**Add/more trigger behavior** is driven by the total count of valid items across `single-input` + `multiple-input` combined, not by which slot they came from:
|
|
167
|
+
- 0 items → no trigger renders at all (fully backward-compatible with plain `left`-slot-only usage).
|
|
168
|
+
- 1 item → the trigger stays the default "+" icon; clicking it calls that item's `action` directly, no dropdown opens.
|
|
169
|
+
- 2+ items → clicking the trigger opens a dropdown (custom-positioned, teleported to `<body>`, matching the composer's full width — not `AbPopover`, which sizes/anchors to the trigger button instead) listing every item (with a divider between the two slot groups if both are non-empty). Opens below by default and flips above (capped to the available space, scrolling internally if needed) when there isn't room below — never clipped by the viewport or a scrolling ancestor.
|
|
170
|
+
|
|
171
|
+
## v-model
|
|
172
|
+
|
|
173
|
+
Yes — `modelValue` + `update:modelValue` (string). Also a second v-model: `files` + `update:files` (`FileEntry[]`).
|
|
174
|
+
|
|
175
|
+
### Attached file shape (`FileEntry`)
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
{
|
|
179
|
+
id, // stable string key, generated internally
|
|
180
|
+
file, // the raw File object
|
|
181
|
+
name,
|
|
182
|
+
size,
|
|
183
|
+
type,
|
|
184
|
+
extension, // lowercased, no dot
|
|
185
|
+
isImage, // boolean — drives chip thumbnail vs icon
|
|
186
|
+
previewKind, // 'image' | 'video' | 'audio' | 'pdf' | 'none' — drives lightbox rendering
|
|
187
|
+
url, // objectURL — revoked automatically on removeFile()/clearFiles()/unmount
|
|
188
|
+
fileIcon, // icon component for non-image chip display
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Exposed methods
|
|
193
|
+
|
|
194
|
+
Same methods as the scoped slot props above (see "Slots"), also available via a template ref for use outside
|
|
195
|
+
any slot — e.g. a toolbar button elsewhere on the page.
|
|
196
|
+
|
|
197
|
+
| Method | Description |
|
|
198
|
+
| --- | --- |
|
|
199
|
+
| `addFiles(files)` | Accepts a `File[]` or `FileList`. Validates each against `maxFileSize`/`allowedExtensions`; rejected files fire `file-reject` + a toast and are never added. Accepted files are appended and `update:files` fires once with the full list. |
|
|
200
|
+
| `removeFile(id)` | Removes one attached file by `id`, revoking its object URL. |
|
|
201
|
+
| `clearFiles()` | Removes all attached files, revoking every object URL. |
|
|
202
|
+
| `addToAttach(options?)` | Opens a native file picker and routes the selection through `addFiles`. `options`: `{ accept, multiple }`. |
|
|
203
|
+
| `updateText(text)` | Replaces the message text (fires `update:modelValue`). |
|
|
204
|
+
| `focus()` | Focuses the textarea. |
|
|
205
|
+
| `startRecording()` | Starts voice input (same as clicking the mic button). No-op if unsupported/disabled/readonly/already recording. |
|
|
206
|
+
| `stopRecording()` | Stops recording, keeping the transcribed text (same as the ■ button). |
|
|
207
|
+
| `cancelRecording()` | Stops recording and discards the transcribed text (same as the ✕ button). |
|
|
208
|
+
|
|
209
|
+
## Provides
|
|
210
|
+
|
|
211
|
+
`abChatInputCloseMenu` (no-arg function) — consumed by `AbChatInputMenuItem` to auto-close the dropdown after its `action` fires. Not meant to be consumed by anything else.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# AbChatInputMenuItem — AI Reference
|
|
2
|
+
|
|
3
|
+
A single row (icon + name + optional description) for `AbChatInput`'s add/more dropdown. Not useful outside `AbChatInput` — see [.ai/ai_ref_AbChatInput.md](./ai_ref_AbChatInput.md).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Not globally registered — import it explicitly. Requires `@lucide/vue` (or any icon component) for the `icon` prop.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```vue
|
|
12
|
+
<template>
|
|
13
|
+
<AbChatInput v-model="message">
|
|
14
|
+
<template #single-input>
|
|
15
|
+
<AbChatInputMenuItem :icon="Paperclip" name="Attach a file" description="jpg, png, pdf" :action="onAttach" />
|
|
16
|
+
</template>
|
|
17
|
+
</AbChatInput>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup>
|
|
21
|
+
import { ref } from 'vue';
|
|
22
|
+
import { AbChatInput, AbChatInputMenuItem } from 'vue3-appsbd-ui';
|
|
23
|
+
import { Paperclip } from '@lucide/vue';
|
|
24
|
+
|
|
25
|
+
const message = ref('');
|
|
26
|
+
function onAttach() { /* open a file picker, etc. */ }
|
|
27
|
+
</script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props
|
|
31
|
+
|
|
32
|
+
| Name | Type | Default | Description |
|
|
33
|
+
| --- | --- | --- | --- |
|
|
34
|
+
| `icon` | `Object \| Function` | `null` | Icon component (e.g. a `@lucide/vue` icon). |
|
|
35
|
+
| `name` | `String` | `""` | Item title (passed through `translateGetMsg`). |
|
|
36
|
+
| `description` | `String` | `""` | Optional secondary line (passed through `translateGetMsg`). |
|
|
37
|
+
| `action` | `Function` | `null` | Called on click. **Important:** when this item is the only one registered across `#single-input`/`#multiple-input`, `AbChatInput` reads this prop directly off the item's VNode and calls it without mounting the item — always pass a plain function, not something that depends on the component being mounted first. |
|
|
38
|
+
|
|
39
|
+
## Events
|
|
40
|
+
|
|
41
|
+
| Event | Payload | Description |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `click` | — | Fired on click, after `action()`. |
|
|
44
|
+
|
|
45
|
+
## Slots
|
|
46
|
+
|
|
47
|
+
None.
|
|
48
|
+
|
|
49
|
+
## v-model
|
|
50
|
+
|
|
51
|
+
Not applicable — stateless presentational item.
|
|
52
|
+
|
|
53
|
+
## Injects
|
|
54
|
+
|
|
55
|
+
`abChatInputCloseMenu` (optional, no-arg function) — provided by the parent `AbChatInput`; called after `action()`/`click` to close the dropdown. No consumer wiring needed.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# AbFileUploader — AI Reference
|
|
2
2
|
|
|
3
|
-
File upload input with drag-and-drop, size validation, and preview.
|
|
3
|
+
File upload input with drag-and-drop, size/type validation, and preview. Supports an image-only
|
|
4
|
+
mode (default) or a generic file mode with extension-icon previews. Can render a default uploader
|
|
5
|
+
UI or accept a custom one via slots.
|
|
4
6
|
|
|
5
7
|
> Also available inside `AbCustomField` via the `FU` field type — see [.ai/ai_ref_AbCustomField.md](./ai_ref_AbCustomField.md).
|
|
6
8
|
|
|
@@ -8,9 +10,17 @@ File upload input with drag-and-drop, size validation, and preview. Can render a
|
|
|
8
10
|
|
|
9
11
|
```vue
|
|
10
12
|
<template>
|
|
11
|
-
<ab-file-uploader v-model="
|
|
13
|
+
<ab-file-uploader v-model="avatar" label="Upload avatar" :max-size="1.5" @on-select-files="handleFiles" />
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
<!-- File mode: allowedTypes is required, non-image files show an extension icon -->
|
|
16
|
+
<ab-file-uploader
|
|
17
|
+
v-model="doc"
|
|
18
|
+
type="file"
|
|
19
|
+
:allowed-types="['pdf', 'doc', 'docx', 'xlsx']"
|
|
20
|
+
:max-size="5"
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
<ab-file-uploader v-model="avatar" :max-size="5">
|
|
14
24
|
<template #dial>
|
|
15
25
|
<div class="my-drop-zone">Drop files here</div>
|
|
16
26
|
</template>
|
|
@@ -19,7 +29,8 @@ File upload input with drag-and-drop, size validation, and preview. Can render a
|
|
|
19
29
|
|
|
20
30
|
<script setup>
|
|
21
31
|
import { ref } from 'vue';
|
|
22
|
-
const
|
|
32
|
+
const avatar = ref(null);
|
|
33
|
+
const doc = ref(null);
|
|
23
34
|
function handleFiles(files) { console.log('Selected files:', files); }
|
|
24
35
|
</script>
|
|
25
36
|
```
|
|
@@ -32,13 +43,18 @@ function handleFiles(files) { console.log('Selected files:', files); }
|
|
|
32
43
|
| `maxSize` | `Number` | `2.0` | Max file size in MB. |
|
|
33
44
|
| `label` | `String` | `""` | Field label. |
|
|
34
45
|
| `containerClass` | `String` | `undefined` | Wrapper class (falls back to globalConfig.inputContainerClass). |
|
|
46
|
+
| `type` | `'image' \| 'file'` | `'image'` | Upload mode. `image` only accepts images and always shows a thumbnail preview. `file` accepts any file listed in `allowedTypes`; non-image files render an extension icon instead of a preview. |
|
|
47
|
+
| `allowedTypes` | `Array<String>` | `[]` | Allowed extensions, no dot (e.g. `['pdf', 'docx']`). **Required when `type="file"`** — logs a console error and rejects every selected file when empty. Also drives the input's `accept` attribute. Ignored in `image` mode. |
|
|
48
|
+
| `showFileName` | `Boolean` | `null` | Whether to render the filename below the container. `null` auto-picks by `type` (off for `image`, on for `file`); pass `true`/`false` to override either mode. |
|
|
49
|
+
| `width` | `String \| Number` | `undefined` | Container width. Number is treated as px. Falls back to the default `100px`. |
|
|
50
|
+
| `height` | `String \| Number` | `undefined` | Container height. Number is treated as px. Falls back to the default `73px`. |
|
|
35
51
|
|
|
36
52
|
## Events
|
|
37
53
|
|
|
38
54
|
| Event | Payload | Description |
|
|
39
55
|
| --- | --- | --- |
|
|
40
|
-
| `update:modelValue` | `file` | v-model sync. |
|
|
41
|
-
| `onSelectFiles` | `files` | All selected files after
|
|
56
|
+
| `update:modelValue` | `file \| null` | v-model sync. |
|
|
57
|
+
| `onSelectFiles` | `files` | All selected files after validation. |
|
|
42
58
|
|
|
43
59
|
## Slots
|
|
44
60
|
|
|
@@ -47,3 +63,15 @@ function handleFiles(files) { console.log('Selected files:', files); }
|
|
|
47
63
|
| `label` | Custom label. |
|
|
48
64
|
| `dial` | Custom uploader UI (replaces the default design). |
|
|
49
65
|
| `default` | Alternative custom UI slot. |
|
|
66
|
+
|
|
67
|
+
## v-model
|
|
68
|
+
|
|
69
|
+
Yes — `modelValue` + `update:modelValue`. Holds a `File` object (or a URL string for pre-existing
|
|
70
|
+
previews), or `null`.
|
|
71
|
+
|
|
72
|
+
## Notes
|
|
73
|
+
|
|
74
|
+
- Icon mapping for non-image files (pdf, zip, doc/docx, xls/xlsx, ppt/pptx, video) comes from the
|
|
75
|
+
shared `useFileValidator()` composable's `getFileIconByExt`, the same mapping `AbChatInput` uses.
|
|
76
|
+
- In `image` mode, validation is unchanged from before: only jpg/jpeg/png/gif/webp are accepted and
|
|
77
|
+
checked against the file's actual MIME type.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AbFormCheck / AbRadioInput — AI Reference
|
|
2
2
|
|
|
3
|
-
Checkbox or radio group with card, segmented, and pill visual variants. `AbRadioInput` is an alias export of `AbFormCheck`.
|
|
3
|
+
Checkbox or radio group with card, icon-card, card-flat-check, image-radio, segmented, and pill visual variants. `AbRadioInput` is an alias export of `AbFormCheck`.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -17,6 +17,41 @@ Checkbox or radio group with card, segmented, and pill visual variants. `AbRadio
|
|
|
17
17
|
/>
|
|
18
18
|
|
|
19
19
|
<ab-form-check v-model="plan" type="radio" name="plan" variant="card" :options="plans" />
|
|
20
|
+
|
|
21
|
+
<!-- Custom check icon (card-family variants only) -->
|
|
22
|
+
<ab-form-check v-model="plan" type="radio" name="plan2" variant="card" :options="plans" :check-icon-component="Check" />
|
|
23
|
+
|
|
24
|
+
<!-- Flat, shadow-free card with the indicator on the right (card-family variants only) -->
|
|
25
|
+
<ab-form-check v-model="plan" type="radio" name="plan3" variant="card" :options="plans" flat-check check-right />
|
|
26
|
+
|
|
27
|
+
<!-- icon-card: icon centered on top by default (no containerClass needed) -->
|
|
28
|
+
<ab-form-check v-model="plan" type="radio" name="plan4" variant="icon-card" :options="plans" />
|
|
29
|
+
|
|
30
|
+
<!-- card-flat-check: flatCheck styling on by default -->
|
|
31
|
+
<ab-form-check v-model="plan" type="radio" name="plan5" variant="card-flat-check" :options="plans" />
|
|
32
|
+
|
|
33
|
+
<!-- isInline false on a card-family variant: full-width stacked column with a gap between cards -->
|
|
34
|
+
<ab-form-check v-model="plan" type="radio" name="plan6" variant="card" :options="plans" :is-inline="false" />
|
|
35
|
+
|
|
36
|
+
<!-- image-radio: big image tile, native input hidden, check badge overlays a corner -->
|
|
37
|
+
<ab-form-check
|
|
38
|
+
v-model="theme"
|
|
39
|
+
type="radio"
|
|
40
|
+
name="theme"
|
|
41
|
+
variant="image-radio"
|
|
42
|
+
card-width="140px"
|
|
43
|
+
selector-position="top-right"
|
|
44
|
+
:options="[
|
|
45
|
+
{ val: 'light', title: 'Light', img_src: '/light.png' },
|
|
46
|
+
{ val: 'dark', title: 'Dark', img_src: '/dark.png' },
|
|
47
|
+
]"
|
|
48
|
+
/>
|
|
49
|
+
|
|
50
|
+
<!-- image-radio chip mode: isInline=true swaps the big tile for a compact icon+text chip -->
|
|
51
|
+
<ab-form-check v-model="theme" type="radio" name="theme2" variant="image-radio" :options="themes" is-inline />
|
|
52
|
+
|
|
53
|
+
<!-- isBoxShadow: checked state as a colored box-shadow glow instead of a border-color change -->
|
|
54
|
+
<ab-form-check v-model="plan" type="radio" name="plan7" variant="card" :options="plans" is-box-shadow />
|
|
20
55
|
</template>
|
|
21
56
|
```
|
|
22
57
|
|
|
@@ -29,16 +64,26 @@ Checkbox or radio group with card, segmented, and pill visual variants. `AbRadio
|
|
|
29
64
|
| `rules` | `String` | `""` | VeeValidate rules. |
|
|
30
65
|
| `val` | `any` | `null` | Initial value. |
|
|
31
66
|
| `type` | `String` | `"checkbox"` | `"checkbox"` or `"radio"`. |
|
|
32
|
-
| `isInline` | `Boolean` | `false` | Render options inline. |
|
|
33
|
-
| `options` | `Array` | `[]` | Each: `{ val, title, description?, icon?, img_src?, iconComponent?, disable? }`. |
|
|
67
|
+
| `isInline` | `Boolean` | `false` | Render options inline. On `variant="image-radio"` this means something different: options always flow in a wrapping tile grid regardless of this prop; `isInline` instead toggles a compact icon+text chip look (`true`, check badge leads on the left like a normal radio/checkbox and only takes up space once checked) vs. the default big image tile (`false`, check badge overlays the image corner). |
|
|
68
|
+
| `options` | `Array` | `[]` | Each: `{ val, title, description?, icon?, img_src?, iconComponent?, disable?, class? }`. `description` is always rendered via `v-html` — only pass trusted/sanitized HTML. |
|
|
34
69
|
| `name` | `String` | **required** | Field name. |
|
|
35
70
|
| `limit` | `Number` | `0` | Max selections (0 = unlimited). |
|
|
36
|
-
| `containerClass` | `String` | `"mb-3"` | Wrapper class. |
|
|
71
|
+
| `containerClass` | `String` | `"mb-3"` | Wrapper class. `variant="card"`/`"icon-card"`/`"card-flat-check"`/`"image-radio"` layout keywords: `left-top`, `middle-top` (icon position). `icon-card` and `image-radio` default to `middle-top` if neither keyword is passed. |
|
|
37
72
|
| `size` | `String` | `"md"` | Control size. |
|
|
38
73
|
| `iconSize` | `String` | `"24px"` | Icon size (when option has an icon). |
|
|
39
74
|
| `iconGap` | `String` | `"10px"` | Gap between icon and label. |
|
|
40
|
-
| `variant` | `String` | `"default"` | `default`, `card`, `segmented`, `pill`. |
|
|
41
|
-
| `cardWidth` | `String` | `"auto"` | Width of card
|
|
75
|
+
| `variant` | `String` | `"default"` | `default`, `card`, `icon-card` (card with the icon centered on top by default), `card-flat-check` (card with `flatCheck` styling on by default), `image-radio` (image-first card; native input hidden, check badge overlays the image's top-left corner), `segmented`, `pill`. |
|
|
76
|
+
| `cardWidth` | `String` | `"auto"` | Width of the card itself for card-family variants (e.g. `"160px"`, `"50%"`, `"12rem"`). Applies in both inline and stacked (`isInline` set to `false`) layouts. |
|
|
77
|
+
| `checkIcon` | `String` | `undefined` | CSS icon class rendered inside the checked input, replacing the native checkmark/dot. Card-family variants only. |
|
|
78
|
+
| `checkIconComponent` | `Component` | `undefined` | A Vue component (e.g. a Lucide icon) rendered inside the checked input, replacing the native checkmark/dot. Card-family variants only. On `variant="image-radio"`, a built-in circle-check icon is used automatically when neither this nor `checkIcon` is set. |
|
|
79
|
+
| `flatCheck` | `Boolean` | `false` | Shadow-free checked style for card-family variants: border-color change + accent-colored title instead of box-shadow, indicator vertically centered. Always on for `variant="card-flat-check"`. |
|
|
80
|
+
| `checkRight` | `Boolean` | `false` | Moves the checkbox/radio indicator to the right side of the card (card-family variants only). Typically combined with `flatCheck`. |
|
|
81
|
+
| `selectorPosition` | `String` | `"top-left"` | Corner the check badge overlays on the image: `"top-left"`, `"top-right"`, `"bottom-left"`, `"bottom-right"`. `variant="image-radio"` only. |
|
|
82
|
+
| `isBoxShadow` | `Boolean` | `false` | Card-family variants only (`card`, `icon-card`, `card-flat-check`, `image-radio`). Shows checked state as a colored box-shadow glow instead of a border-color change — the border stays transparent throughout, matching the classic `AbImageRadioInput` look. |
|
|
83
|
+
|
|
84
|
+
Card-family variants `card`, `icon-card`, `card-flat-check` with `isInline` set to `false` (the default) stack in a full-width column with a gap between cards, instead of the content-sized cards used when `isInline` set to `true`.
|
|
85
|
+
|
|
86
|
+
`variant="image-radio"` behaves differently from the rest of the card family: options always flow in a wrapping tile grid (never full-width stacked), the native checkbox/radio dot is always hidden, and `isInline` instead switches between two looks — `false` (default): a big image fills the tile with the title below and a check badge overlaying the corner set by `selectorPosition`; `true`: a compact icon+text chip where the check badge leads on the left (like a normal radio/checkbox) instead of overlaying a corner, and only takes up space once an option is checked.
|
|
42
87
|
|
|
43
88
|
## Events
|
|
44
89
|
|
|
@@ -48,12 +93,26 @@ Checkbox or radio group with card, segmented, and pill visual variants. `AbRadio
|
|
|
48
93
|
|
|
49
94
|
## Slots
|
|
50
95
|
|
|
96
|
+
Per-option slots are **not** dynamically named per option (no `-{title}`/`-{val}` suffix) — each is a single
|
|
97
|
+
scoped slot rendered once per option, scoped with `{ check, index }` (`check` is the current `options[index]`
|
|
98
|
+
item). If different options need different content, branch inside the template on `check.val`/`index`:
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<ab-form-check variant="card" :options="plans" v-model="plan" type="radio" name="plan">
|
|
102
|
+
<template #option-label="{ check }">
|
|
103
|
+
<template v-if="check.val === 'pro'">
|
|
104
|
+
<ab-badge variant="danger">Popular</ab-badge> {{ check.title }}
|
|
105
|
+
</template>
|
|
106
|
+
<template v-else>{{ check.title }}</template>
|
|
107
|
+
</template>
|
|
108
|
+
</ab-form-check>
|
|
109
|
+
```
|
|
110
|
+
|
|
51
111
|
| Name | Description |
|
|
52
112
|
| --- | --- |
|
|
53
|
-
| `label` | Group label. |
|
|
54
|
-
| `description` |
|
|
113
|
+
| `label` | Group label (the whole component's `label` prop/heading — not per-option). |
|
|
114
|
+
| `description` | Per-option description, scoped `{ check, index }`. Overrides the option's `description` key (the default content renders it via `v-html`). |
|
|
55
115
|
| `help-text` | Helper text. |
|
|
56
|
-
| `input-
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `description-{option.title}` | Per-option description slot. |
|
|
116
|
+
| `input-icon` | Per-option image/icon area, scoped `{ check, index }` (card-family/segmented/pill variants). Overrides `img_src`/`icon`/`iconComponent`. |
|
|
117
|
+
| `option-label` | Per-option title, scoped `{ check, index }` (card-family/segmented/pill variants). Overrides the option's `title`. Deliberately not named `label` — that name is already the group-level heading slot above. |
|
|
118
|
+
| `check-icon` | Per-option checked-state icon, scoped `{ check, index }` (card-family variants only). Default content falls back to `checkIcon`/`checkIconComponent`; overrides both when provided. |
|
|
@@ -43,6 +43,8 @@ const form = reactive({ email: '' });
|
|
|
43
43
|
| `maxlength` | `any` | `null` | Native `maxlength`. |
|
|
44
44
|
| `isLeftIconBorder` | `Boolean` | `false` | Renders border between the prefix icon and the input. |
|
|
45
45
|
| `isRightIconBorder` | `Boolean` | `false` | Renders border between the postfix icon and the input. |
|
|
46
|
+
|
|
47
|
+
> Set both `isLeftIconBorder` and `isRightIconBorder` to `true` to show a border on both sides at once — the whole input group (icons + field) is treated as one unified box on focus.
|
|
46
48
|
| `passIconPosition` | `String` | `"right"` | Position of the show password icon (`"left"`, `"right"`). |
|
|
47
49
|
| `isHideLabel` | `Boolean` | `false` | Hide the label visually. |
|
|
48
50
|
| `iconPosition` | `String` | `undefined` | Position of the custom `#icon` slot (`"left"`, `"right"`). |
|
|
@@ -38,6 +38,7 @@ const qty = ref(1);
|
|
|
38
38
|
| `isBorder` | `Boolean` | `false` | Show inner borders between minus/input/plus. Default is a seamless pill. |
|
|
39
39
|
| `isLeftIconBorder` | `Boolean` | `false` | Render border between the prefix icon and the input. |
|
|
40
40
|
| `isRightIconBorder` | `Boolean` | `false` | Render border between the postfix icon and the input. |
|
|
41
|
+
| `size` | `String` | `undefined` | Input size: `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. Falls back to `globalConfig.size`, then `"md"`. |
|
|
41
42
|
|
|
42
43
|
## Events
|
|
43
44
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# abDate (Library)
|
|
2
|
+
|
|
3
|
+
Chhoto, dependency-free date/datetime/time formatting library (dayjs-er moto). Kono timezone conversion kore na — je value deya hoy sheta as-is (wall-clock) format hoy.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { formatDate, formatDateTime, formatTime, formatCustom } from "@vue3-appsbd-ui/libraries/abDate";
|
|
9
|
+
|
|
10
|
+
formatDate("2026-08-17"); // globalConfig.dateDisplayFormat na thakle -> "2026-08-17"
|
|
11
|
+
formatDateTime("2026-08-17 14:05:09"); // globalConfig.datetimeDisplayFormat na thakle -> "2026-08-17 14:05:09"
|
|
12
|
+
formatTime(new Date()); // globalConfig.timeDisplayFormat na thakle -> "14:05:09"
|
|
13
|
+
formatCustom("2026-08-17", "DD/MM/YYYY"); // -> "17/08/2026"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Default Format Resolution
|
|
17
|
+
|
|
18
|
+
`formatDate` / `formatDateTime` / `formatTime` resolve their format in this order:
|
|
19
|
+
|
|
20
|
+
1. Explicit `format` argument.
|
|
21
|
+
2. `AppsbdUIConfigure`'s `dateDisplayFormat` / `datetimeDisplayFormat` / `timeDisplayFormat` (see [ai_ref_global_config.md](./ai_ref_global_config.md)).
|
|
22
|
+
3. Built-in MySQL default: `'YYYY-MM-DD'` / `'YYYY-MM-DD HH:mm:ss'` / `'HH:mm:ss'`.
|
|
23
|
+
|
|
24
|
+
## API Reference
|
|
25
|
+
|
|
26
|
+
### Functions
|
|
27
|
+
|
|
28
|
+
| Function | Signature | Description |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `formatDate` | `(value, format?) => string` | Formats `value` as a date. Falls back to `globalConfig.dateDisplayFormat`, then `'YYYY-MM-DD'`. |
|
|
31
|
+
| `formatDateTime` | `(value, format?) => string` | Formats `value` as a date+time. Falls back to `globalConfig.datetimeDisplayFormat`, then `'YYYY-MM-DD HH:mm:ss'`. |
|
|
32
|
+
| `formatTime` | `(value, format?) => string` | Formats `value` as a time. Falls back to `globalConfig.timeDisplayFormat`, then `'HH:mm:ss'`. |
|
|
33
|
+
| `formatCustom` | `(value, format) => string` | Generic formatter — `format` is required, no default resolution. |
|
|
34
|
+
|
|
35
|
+
### `value` Input Types
|
|
36
|
+
|
|
37
|
+
- `Date` — used as-is.
|
|
38
|
+
- `number` — treated as an epoch timestamp (`new Date(value)`).
|
|
39
|
+
- `string` — parsed manually (no native `Date` parsing quirks): `YYYY-MM-DD`, `YYYY-MM-DD HH:mm[:ss]`, `YYYY-MM-DDTHH:mm:ss(.sss)(Z|±HH:mm)`, or time-only `HH:mm[:ss]` (attached to today's date). Any trailing `Z`/offset is **ignored**, not applied as a shift. Unrecognized strings fall back to native `new Date(string)`.
|
|
40
|
+
- Falsy or unparseable input → all functions return `''`.
|
|
41
|
+
|
|
42
|
+
### Format Tokens
|
|
43
|
+
|
|
44
|
+
Same token set as `AbDateTimePicker.vue`, plus real second support (`ss`/`s`):
|
|
45
|
+
|
|
46
|
+
| Token | Meaning | Example |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `YYYY` / `YY` | 4/2-digit year | `2026` / `26` |
|
|
49
|
+
| `MMMM` / `MMM` | Full/short month name (uses `globalConfig.monthNames`/`monthNamesShort`, English default) | `August` / `Aug` |
|
|
50
|
+
| `MM` / `M` | 2/1-digit month | `08` / `8` |
|
|
51
|
+
| `DD` / `D` | 2/1-digit day | `17` / `17` |
|
|
52
|
+
| `HH` / `H` | 2/1-digit hour (24h) | `14` / `14` |
|
|
53
|
+
| `hh` / `h` | 2/1-digit hour (12h) | `02` / `2` |
|
|
54
|
+
| `mm` / `m` | 2/1-digit minute | `05` / `5` |
|
|
55
|
+
| `ss` / `s` | 2/1-digit second | `09` / `9` |
|
|
56
|
+
| `A` / `a` | Upper/lowercase AM-PM | `PM` / `pm` |
|
|
57
|
+
|
|
58
|
+
No timezone conversion is performed anywhere in this library.
|
|
@@ -14,10 +14,15 @@ function handleFileUpload(event) {
|
|
|
14
14
|
const file = event.target.files[0];
|
|
15
15
|
if (!file) return;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// Legacy / default: image-only, validated against a static jpg/png/gif/webp mime map.
|
|
18
|
+
const validatedImage = getFileInfo(file, 2.0);
|
|
19
|
+
|
|
20
|
+
// Custom extension list: any extension in the list is allowed (no mime map needed).
|
|
21
|
+
const validatedDoc = getFileInfo(file, 5.0, ["pdf", "doc", "docx", "xlsx"]);
|
|
22
|
+
|
|
23
|
+
if (validatedDoc) {
|
|
24
|
+
// validatedDoc.isImage
|
|
25
|
+
// validatedDoc.fileIcon
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
</script>
|
|
@@ -27,5 +32,5 @@ function handleFileUpload(event) {
|
|
|
27
32
|
|
|
28
33
|
| Method | Signature | Description |
|
|
29
34
|
|---|---|---|
|
|
30
|
-
| `getFileInfo(file, sizeLimitMb)` | `Function` | Validates a `File` object
|
|
35
|
+
| `getFileInfo(file, sizeLimitMb, allowedExtensions?)` | `Function` | Validates a `File` object and max size (`sizeLimitMb`, default `1.0`). Without `allowedExtensions`, only jpg/jpeg/png/gif/webp are allowed and cross-checked against the file's actual MIME type (legacy, image-only behavior). With `allowedExtensions` (array of extensions, no dot, e.g. `['pdf', 'docx']`), any extension in that list is allowed instead — no MIME cross-check. If invalid, spawns a toast error and returns `null`. If valid, returns the `file` augmented with `isImage` and `fileIcon` properties. |
|
|
31
36
|
| `getFileIconByExt(ext, type)` | `Function` | Returns `{ isImage: boolean, fileIcon: Component\|String }` based on file extension and MIME type. Uses `@lucide/vue` icons for known formats (pdf, zip, doc, xls, ppt, mp4). |
|
package/AI_REFERENCE.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| `AbField` | ✅ | Polymorphic field wrapper - renders any input type via a `type` prop. | [.ai/ai_ref_AbField.md](./.ai/ai_ref_AbField.md) |
|
|
22
22
|
| `AbCustomField` | ✅ | Dynamic form scaffold driven by a `fieldInputs` array. | [.ai/ai_ref_AbCustomField.md](./.ai/ai_ref_AbCustomField.md) |
|
|
23
23
|
| `AbDateTimePicker` | ✅ | Date / time / range picker. Also import `v-calendar/style.css` in consuming app. | [.ai/ai_ref_AbDateTimePicker.md](./.ai/ai_ref_AbDateTimePicker.md) |
|
|
24
|
-
| `AbFormCheck` / `AbRadioInput` | ✅ | Checkbox / radio group (default, card, segmented, pill variants). `AbRadioInput` is an alias of `AbFormCheck`.
|
|
24
|
+
| `AbFormCheck` / `AbRadioInput` | ✅ | Checkbox / radio group (default, card, icon-card, card-flat-check, image-radio, segmented, pill variants). `AbRadioInput` is an alias of `AbFormCheck`. | [.ai/ai_ref_AbFormCheck.md](./.ai/ai_ref_AbFormCheck.md) |
|
|
25
25
|
| `AbToggle` | ✅ | Accessible switch/toggle with title & description slots. | [.ai/ai_ref_AbToggle.md](./.ai/ai_ref_AbToggle.md) |
|
|
26
26
|
| `AbInputTag` | ✅ | Multi-tag input with optional option list. | [.ai/ai_ref_AbInputTag.md](./.ai/ai_ref_AbInputTag.md) |
|
|
27
27
|
| `AbMultiSelect` | ✅ | Searchable single/multi/tag select (custom built-in — replaces `@vueform/multiselect`). | [.ai/ai_ref_AbMultiSelect.md](./.ai/ai_ref_AbMultiSelect.md) |
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
| `AbMainLayout` | — | Full-page application shell with left/right sidebar drawers, header, body, and footer slots. Mobile-responsive. | [.ai/ai_ref_AbMainLayout.md](./.ai/ai_ref_AbMainLayout.md) |
|
|
40
40
|
| `AbSlider` | — | Single or range numeric slider. | [.ai/ai_ref_AbSlider.md](./.ai/ai_ref_AbSlider.md) |
|
|
41
41
|
| `AbColorPicker` | — | Radio-style color swatch picker. | [.ai/ai_ref_AbColorPicker.md](./.ai/ai_ref_AbColorPicker.md) |
|
|
42
|
-
| `AbFileUploader` | — | File upload field with
|
|
42
|
+
| `AbFileUploader` | — | File upload field with size validation; image mode (default, preview) or file mode (`allowedTypes` + extension icons). | [.ai/ai_ref_AbFileUploader.md](./.ai/ai_ref_AbFileUploader.md) |
|
|
43
43
|
| `AbFilterPanel` | — | Advanced filter panel with search and scan modes. | [.ai/ai_ref_AbFilterPanel.md](./.ai/ai_ref_AbFilterPanel.md) |
|
|
44
44
|
| `AbSettingsForm` | — | Settings-style form that auto-registers as a wizard step validator. | [.ai/ai_ref_AbSettingsForm.md](./.ai/ai_ref_AbSettingsForm.md) |
|
|
45
45
|
| `AbScrollbar` | — | Styled custom scrollbar wrapper with scroll events. | [.ai/ai_ref_AbScrollbar.md](./.ai/ai_ref_AbScrollbar.md) |
|
|
@@ -56,16 +56,19 @@
|
|
|
56
56
|
| `AbPricingContainer` | — | Layout wrapper for pricing tables. | [.ai/ai_ref_AbPricingContainer.md](./.ai/ai_ref_AbPricingContainer.md) |
|
|
57
57
|
| `AbPricingTable` | — | Stylized, responsive pricing table component with feature list and package columns. | [.ai/ai_ref_AbPricingTable.md](./.ai/ai_ref_AbPricingTable.md) |
|
|
58
58
|
| `AbChart` | — | Flexible chart component powered by Apache ECharts. | [.ai/ai_ref_AbChart.md](./.ai/ai_ref_AbChart.md) |
|
|
59
|
+
| `AbChatInput` | — | ChatGPT-style auto-growing composer with an item-count-driven add/more dropdown, internal file attachment preview, and built-in Web Speech API voice input. | [.ai/ai_ref_AbChatInput.md](./.ai/ai_ref_AbChatInput.md) |
|
|
60
|
+
| `AbChatInputMenuItem` | — | Presentational row (icon/name/description/action) for `AbChatInput`'s add/more dropdown. | [.ai/ai_ref_AbChatInputMenuItem.md](./.ai/ai_ref_AbChatInputMenuItem.md) |
|
|
59
61
|
| `AbDarkModeToggler` | — | Light / dark theme toggle (pairs with `useTheme`). | [.ai/ai_ref_AbDarkModeToggler.md](./.ai/ai_ref_AbDarkModeToggler.md) |
|
|
60
62
|
| `useAlert` | — | Procedural API to trigger SweetAlert-based modal alerts, notifications, and confirmations. | [.ai/ai_ref_useAlert.md](./.ai/ai_ref_useAlert.md) |
|
|
61
63
|
| `abEventBus` / `emitterObj` | — | Lightweight global event bus using `tiny-emitter`. | [.ai/ai_ref_abEventBus.md](./.ai/ai_ref_abEventBus.md) |
|
|
62
64
|
| `useTheme` | — | Composable for light/dark theme toggling with localStorage and system preference sync. | [.ai/ai_ref_useTheme.md](./.ai/ai_ref_useTheme.md) |
|
|
63
65
|
| `useToast` | — | Procedural API to spawn toast notifications (success, error, warning, info). | [.ai/ai_ref_useToast.md](./.ai/ai_ref_useToast.md) |
|
|
64
|
-
| `useFileValidator` | — | File validation utilities (size, MIME type) and file icon/image resolvers.
|
|
66
|
+
| `useFileValidator` | — | File validation utilities (size, MIME type, or a custom allowed-extensions list) and file icon/image resolvers. | [.ai/ai_ref_useFileValidator.md](./.ai/ai_ref_useFileValidator.md) |
|
|
65
67
|
| `useResponsive` | — | Real-time viewport width tracker for responsive layout decisions (Bootstrap 5 aligned). | [.ai/ai_ref_useResponsive.md](./.ai/ai_ref_useResponsive.md) |
|
|
66
68
|
| `abTranslate` | — | Localization utility wrapping `vue3-gettext` with automatic variable interpolation. | [.ai/ai_ref_abTranslate.md](./.ai/ai_ref_abTranslate.md) |
|
|
67
69
|
| `abVeeRules` | — | Collection of pre-configured VeeValidate validation rules integrated with localization. | [.ai/ai_ref_abVeeRules.md](./.ai/ai_ref_abVeeRules.md) |
|
|
68
70
|
| `abRequestParam` | — | Data-transfer classes to build structured API request parameters (pagination, sorting, filtering). | [.ai/ai_ref_abRequestParam.md](./.ai/ai_ref_abRequestParam.md) |
|
|
71
|
+
| `abDate` | — | Dependency-free date/datetime/time formatter (dayjs-style); no timezone conversion, defaults from global config. | [.ai/ai_ref_abDate.md](./.ai/ai_ref_abDate.md) |
|
|
69
72
|
|
|
70
73
|
## Directives & Controller APIs
|
|
71
74
|
|