@appsbd/vue3-appsbd-ui 1.0.20 → 1.0.21

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.
@@ -49,7 +49,7 @@ const qty = ref(1);
49
49
  </script>
50
50
  ```
51
51
 
52
- Inset label variant (label inside the bordered box):
52
+ Inset label variant (label inside the bordered box; acts as the placeholder while empty/unfocused, moves to the top on focus / when filled):
53
53
 
54
54
  ```vue
55
55
  <ab-input-field v-model="username" variant="inset" name="username" label="Username" />
@@ -113,7 +113,7 @@ const { toast } = useToast();
113
113
  | `iconPosition` | `String` | `undefined` | Position of the custom `#icon` slot (`"left"`, `"right"`). |
114
114
  | `inputClass` | `String \| Object \| Array` | `undefined` | Additional class(es) for the input element. |
115
115
  | `inputStyle` | `String \| Object \| Array` | `undefined` | Additional style(s) for the input element. |
116
- | `variant` | `String` | `undefined` | Layout variant. `"stepper"` renders a numeric stepper (forces `type="number"`, shows +/- buttons, enables `min`/`max`/`step` clamping). `"inset"` renders the label inside the bordered field, stacked above the value (border/focus/error styles unchanged; a left `#icon`/`prefix` gets a fixed width so the label aligns — use an icon, not long text). `"outlined"` renders a floating label: shown like a placeholder while empty/unfocused, floats onto the top border when focused or filled, the border is cut away behind it, no label background, RTL supported (real `placeholder` appears on focus; scales with `size`). |
116
+ | `variant` | `String` | `undefined` | Layout variant. `"stepper"` renders a numeric stepper (forces `type="number"`, shows +/- buttons, enables `min`/`max`/`step` clamping). `"inset"` renders the label inside the bordered field: it acts as the placeholder (centered) while empty and unfocused, and moves to the top, stacked above the value, on focus or when filled — the real `placeholder` shows on focus (border/focus/error styles unchanged; a left `#icon`/`prefix` gets a fixed width so the label aligns — use an icon, not long text). `"outlined"` renders a floating label: shown like a placeholder while empty/unfocused, floats onto the top border when focused or filled, the border is cut away behind it, no label background, RTL supported (real `placeholder` appears on focus; scales with `size`). |
117
117
  | `min` | `Number \| String` | `null` | *(stepper variant)* Minimum allowed value. Clamps input and disables the minus button at the floor. |
118
118
  | `max` | `Number \| String` | `null` | *(stepper variant)* Maximum allowed value. Clamps input and disables the plus button at the ceiling. |
119
119
  | `step` | `Number \| String` | `1` | *(stepper variant)* Increment/decrement amount. |
package/AI_REFERENCE.md CHANGED
@@ -21,7 +21,7 @@
21
21
  | `AbCard` | ✅ | Flexible card container. Default `variant` is `"default"`; also `"tile"`, `"item"`, `"insight"` layout variants. | [.ai/ai_ref_AbCard.md](./.ai/ai_ref_AbCard.md) |
22
22
  | `AbModal` | ✅ | Full-featured dialog with built-in VeeValidate form, loader, and message-only mode. | [.ai/ai_ref_AbModal.md](./.ai/ai_ref_AbModal.md) |
23
23
  | `AbProgressbar` | ✅ | Animated Bootstrap progress bar with color and size variants. | [.ai/ai_ref_AbProgressbar.md](./.ai/ai_ref_AbProgressbar.md) |
24
- | `AbInputField` | ✅ | Core text input with VeeValidate, prefix/postfix/icon slots. `variant="stepper"` turns it into a numeric stepper (min/max/step, +/- buttons); `variant="inset"` puts the label inside the bordered box; `variant="outlined"` is a floating label that moves onto the top border on focus/filled. | [.ai/ai_ref_AbInputField.md](./.ai/ai_ref_AbInputField.md) |
24
+ | `AbInputField` | ✅ | Core text input with VeeValidate, prefix/postfix/icon slots. `variant="stepper"` turns it into a numeric stepper (min/max/step, +/- buttons); `variant="inset"` puts the label inside the bordered box (placeholder-like until focused/filled, then stacks above the value); `variant="outlined"` is a floating label that moves onto the top border on focus/filled. | [.ai/ai_ref_AbInputField.md](./.ai/ai_ref_AbInputField.md) |
25
25
  | `AbNumberField` | ✅ | Numeric input. Defaults to a plain `type="number"` input; `variant="stepper"` renders `AbInputField`'s numeric stepper (min/max/step, +/- buttons) — thin wrapper around `AbInputField`. | [.ai/ai_ref_AbNumberField.md](./.ai/ai_ref_AbNumberField.md) |
26
26
  | `AbField` | ✅ | Polymorphic field wrapper - renders any input type via a `type` prop. `type="number"` + `variant="stepper"` renders `AbInputField`'s numeric stepper. | [.ai/ai_ref_AbField.md](./.ai/ai_ref_AbField.md) |
27
27
  | `AbCustomField` | ✅ | Dynamic form scaffold driven by a `fieldInputs` array. | [.ai/ai_ref_AbCustomField.md](./.ai/ai_ref_AbCustomField.md) |
package/CHANGELOG.md CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  All notable changes to `@appsbd/vue3-appsbd-ui` are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/).
4
4
 
5
- ## [Unreleased]
5
+ ## [1.0.21] - 2026-09-29
6
+
7
+ - **Changed**: `AbInputField` `variant="inset"` — the label now starts out like a placeholder (centered in the field, input font size) while the field is empty and unfocused, and moves up to its stacked position above the value on focus or once there is a value; previously it always sat above the placeholder. A `placeholder`, if set, appears on focus. Border, focus ring, validation styles, sizes and the left-icon layout are unchanged. The label is now rendered inside `div.apbd-input-body` (same wrapper as `outlined`).
8
+ - **Fixed**: `AbInputField` `variant="outlined"` — the gap cut into the top border under the floated label used a fixed `999px` right edge, so on inputs wider than ~1000px everything to the right of that point (border, addons) disappeared once the label floated. The clip now follows the field width (LTR and RTL).
9
+ - **Fixed**: `AbInputField` `variant="outlined"` — the label-width observer was only attached on mount, so a label that arrived later (async/translated) or a toggled `isHideLabel` left the border gap at a stale width. The observer is now re-attached whenever `label`/`isHideLabel` change.
10
+ - **Fixed**: `AbToggle` — after the switch input was wrapped in `.apbd-toggle-input-wrapper`, its negative left margin was reset but the `.form-switch` 2.5em left padding stayed, so the `column`/`inline` layouts rendered the switch ~2.5em too far right with a wider gap to the label. The padding is now removed too.
11
+ - **Fixed**: `AbFileUploader` (dropzone) — a file dropped onto the card was processed but never put into the native `<input type="file">`, so a plain form submit or `required` did not see it. The dropped file is now mirrored into the input (`v-model`/`onSelectFiles` are unchanged).
12
+ - **Docs**: Filled in the missing release dates for `1.0.17` (2026-08-30) and `1.0.18` (2026-09-09), and moved the previously unreleased entries into `1.0.20`, in both `CHANGELOG.md` and the playground Changelog page.
13
+
14
+ ## [1.0.20] - 2026-09-29
6
15
 
7
16
  - **Added**: `AbInputField` `variant="outlined"` — a floating (Material-style) label. While the field is empty and unfocused the label looks like the placeholder; on focus or once it has a value it shrinks and sits on the top border with the border cut away behind it (the label has no background, so it works on any container color; RTL supported), and takes the focus (or error) color. A `placeholder`, if set, appears on focus. Scales with the existing `size` prop (`xs`–`xxl`); a left `#icon`/`prefix` gets a fixed width so the resting label clears it. The input is now wrapped in a `div.apbd-input-body` (`display: contents` for every other variant, so no layout change). No change when `variant` is unset. See `.ai/ai_ref_AbInputField.md`.
8
17
  - **Added**: `AbFileUploader` `variant="dropzone"` (`"default"` | `"dropzone"`, default `"default"`) — a larger upload card: an icon on top, a `title` and `description`, then an `AbButton` as the upload trigger (`buttonText` default `"Upload"`, `buttonColor` default `"primary"`, `buttonSize`). Clicking the card opens the file browser and a file can also be dropped onto it; the icon area has a fixed height (88px, `--afu-preview-height` to change) that the picked image fills (aspect ratio kept, never wider than the card), so the card has the same size with and without an image and a picked non-image file shows its icon, both with the usual hover-to-remove overlay. `isBorder` (`Boolean`, default `true`) picks a dashed border, or `false` for a borderless card with a box-shadow. `width`/`height` size the card. No change when `variant` is unset.
@@ -10,9 +19,6 @@ All notable changes to `@appsbd/vue3-appsbd-ui` are documented here. Format loos
10
19
  - **Fixed**: `AbFileUploader` — clicking the hover-to-remove overlay threw a `ReferenceError` (`removeFile` reset an undefined `naturalImgSize`) before emitting `update:modelValue`/`onSelectFiles`, so a picked file could not be removed. The leftover lines are gone and removal works again.
11
20
  - **Added**: `AbInputField` `variant="inset"` — the label moves inside the bordered field, stacked above the value (small muted label, normal-weight value). The border, focus ring and validation styles are unchanged from the default field. Scales with the existing `size` prop (`xs`–`xxl`). A left `#icon`/`prefix` gets a fixed width so the label lines up with the value — use an icon there, not long text. No change when `variant` is unset. See `.ai/ai_ref_AbInputField.md`.
12
21
  - **Added**: `AbActionButton` `actions` prop (`Array`, default `[]`) — group mode. Renders a whole row of action buttons from one component instance instead of repeating `<AbActionButton action="..." />` per action (e.g. View + Edit + Delete on a table row). Each item is either a plain action-key `String` or an object `{ action, label?, icon?, color?, variant?, loading?, disabled?, confirm?, confirmOptions?, show? }`, resolved against the same built-in presets as single mode (item override > preset > built-in default); `show` (default `true`) conditionally excludes that button, and extra keys on an item forward through to that item's `AbButton`. The `action` event fires per-button with the same `(action, event)` signature as before. `action` is no longer a required prop — passing a non-empty `actions` array switches the component into group mode and `action`/`label`/`icon`/`color`/`variant`/`confirm`/`confirmOptions` are ignored in favor of per-item values. Existing single-`action` usage is unaffected. New scoped `#action` slot (`{ item, action }`) overrides a group button's label content. See `.ai/ai_ref_AbActionButton.md`.
13
-
14
- ## [1.0.20] - 2026-09-22
15
-
16
22
  - **Added**: `AbFileUploader` `maxWidth`/`maxHeight` props (`String | Number`, both default `undefined`) — caps a picked image file's actual resolution rather than the preview box. If the image exceeds `maxWidth`/`maxHeight` (number = px), it's downscaled client-side (canvas, aspect ratio kept, never upscaled) before being previewed and emitted via `update:modelValue`/`onSelectFiles`, so what a consumer later uploads is already capped without them needing to know the source image's dimensions ahead of time. The preview container is unaffected — it always keeps its own `width`/`height` box (default `100px`/`73px`) and fits the (possibly downscaled) image inside it via the existing `object-fit: contain`, so it never overflows. No change when `maxWidth`/`maxHeight` are unset.
17
23
  - **Added**: `AbFileUploader` `isCrop` (`Boolean`, default `false`) and `cropAspectRatio` (`Number`, default `null` = free-form) props. `isCrop` (image mode only, ignored for `type="file"`) opens a crop dialog right after an image is picked — drag the box to move it, drag a corner to resize, then **Crop**; **Cancel** closes the dialog and selects nothing (a previously selected image stays). Built-in canvas cropper, no new dependency. jpeg/png/webp keep their format, anything else (e.g. gif) is exported as png. `update:modelValue` gets the cropped `File`; `onSelectFiles` receives `[file]`. No change when `isCrop` is off.
18
24
  - **Changed**: `AbColorPicker` — the outline ring on the selected swatch was always the theme color for every swatch. It now takes the selected swatch's own `color` (selecting red gives a red ring). Swatches whose `color` is a gradient or `url()` (not usable in a box-shadow) keep the theme-color ring. The gap between swatches also grew from `0 3px` to `10px` (both directions) so the selected ring, which extends 4px outward, no longer touches neighbouring swatches or wrapped rows.
@@ -48,7 +54,7 @@ All notable changes to `@appsbd/vue3-appsbd-ui` are documented here. Format loos
48
54
  - **Fixed**: `AbConfirmPopover`'s `onConfirm` prop — an async handler that resolved to nothing (the natural `async (itemData) => { await doWork(); }` shape, with no explicit return) fell through to the terminal "Completed successfully" alert panel instead of just closing, forcing an extra unwanted OK click even though the work had already finished; only an explicit `{ next: 'close' }` return closed it, and that contract was undocumented. Resolving to nothing (or `null`) now closes the popover directly, same as `{ next: 'close' }`. Returning `{ next: 'confirm' | 'confirm-ajax', ... }` (chain a second step) or any other truthy object like `{ status, message }` (show the success/error alert panel deliberately) behave exactly as before — see `.ai/ai_ref_AbConfirmPopover.md`'s new "onConfirm return contract" table.
49
55
  - **Removed** (breaking): `AbModal`'s `isModalVisible` prop — it was never wired to anything in the component (no `v-if`/`v-show`/class toggle), so passing it had zero effect; the `.ai/ai_ref_AbModal.md` doc incorrectly documented it as `v-model:is-modal-visible`-capable. Visibility has always actually worked by mounting/unmounting `<AbModal>` itself with `v-if` in the parent (the pattern every existing usage in this library already uses) — that's unchanged.
50
56
 
51
- ## [1.0.18]
57
+ ## [1.0.18] - 2026-09-09
52
58
 
53
59
  - **Fixed**: `AbColorPicker` rendered an empty box with no feedback when used with default props — `colors` defaults to `[]` and the component has no built-in palette (by design, same as `AbMultiSelect`'s `options`), so a first-time use without passing `colors` looked broken. Now warns in dev (`import.meta.env.DEV`, stripped from production builds) when `colors` is empty, pointing at the expected `{ name, color, title? }` shape.
54
60
  - **Fixed**: Playground's `DocsToc` (the "On this page" sidebar) — clicking a section link called the target heading's native `scrollIntoView({ block: "start" })`, which walks up *every* scrollable ancestor, including `.apbd-container`/`.apbd-main-content` (`overflow: hidden` — still a valid scroll container by spec even with no visible scrollbar). That silently scrolled those too, shifting the whole app shell (page header, left sidebar) up and clipping it out of view behind their own `overflow: hidden`, while the doc content itself scrolled correctly — most noticeable on longer pages like Color Picker's "Sizes" section. Now scrolls only the actual doc scroll container (`.apbd-app-body`) directly via `scrollTo()`, matching the pattern already used by the TOC's own "Back to top" button.
@@ -62,7 +68,7 @@ All notable changes to `@appsbd/vue3-appsbd-ui` are documented here. Format loos
62
68
  - **Changed**: `AbNumberField` is now a thin deprecated wrapper around `AbInputField` with `variant="stepper"` — its own props/events/slots and rendered output are unchanged, so existing usage keeps working with no code changes needed. Prefer `<AbInputField variant="stepper" />` directly in new code.
63
69
  - **Added**: `AbField` `variant`, `min`, `step`, `showButtons`, and `isBorder` props (`type="number"` only) — forwarded straight through to `AbInputField`, so `<AbField type="number" variant="stepper" />` now gets the same numeric-stepper behavior (min/max/step clamping, +/- buttons) as using `AbInputField` directly. `type="number"` without `variant` still renders a plain native number input, unchanged. `AbField`'s existing `max` prop (selection limit for multiselect/tag/checkbox, `-1` = unlimited) is reused as the stepper's numeric ceiling for `type="number"` too — `-1`/unset is treated as "no ceiling" there as well, so no default-value change for existing usage.
64
70
 
65
- ## [1.0.17]
71
+ ## [1.0.17] - 2026-08-30
66
72
 
67
73
  - **Fixed**: `AbFilterPanel`'s `isBuilderFilter` popup editor was too narrow (`max-width: 320px`, no `width`) for longer values like a `"dr"` (date range) field's `"01/09/2026 - 15/09/2026"`-style text, which got clipped inside its input. Raising just `max-width` didn't help on its own — `AbPopover`'s content box is `position: absolute; width: auto`, which sizes to shrink-to-fit, and a shrink-to-fit box ignores a percentage-width child (`AbInputField`'s `.form-control` is `width: 100%`) when computing that fit, so the box never actually grew to use the extra ceiling. Giving it an explicit `width` fixed that, but the first pass (`340px`) was tuned tight enough against one specific date pair that it broke again on a different one — Bengali numeral glyphs (০-৯) aren't uniform-width (e.g. "৪"/"৬" render wider than "১"), so a range using wider digits needed more room than the one used to size it. Now `width: 400px` (`min-width: 280px` / `max-width: 440px` as clamps) with real margin instead of a pixel-exact fit; the popover's own default 400px cap is also raised to 480px so it isn't clipped from outside.
68
74
  - **Fixed**: `AbFilterPanel`'s `"tr"` (text range) field's Min/arrow/Max row (`.range-input-panel`, shared by standard, advance, and the new `isBuilderFilter` mode) was built from raw `<div class="input-group">` + `<input class="form-control">` markup instead of `AbInputField`, so it never scaled with the panel's `size` prop — the label/input join used a hardcoded `input-group-sm`, and a copy-paste bug hardcoded the **Max** input to `form-control-sm` specifically (while Min correctly used the dynamic size) — so Min and Max could literally render at two different heights. The row also had no flex layout CSS at all: each `.form-control`'s default `width: 100%` forced Min/Max onto separate stacked lines instead of sitting side by side, and the separator `<svg>` had no explicit size (rendering at the browser's 300×150px SVG default) since the `w-4`/`h-4` classes on it aren't real classes in this project (Bootstrap has no such utilities). Now built from two `AbInputField`s (the first carrying the field's name as its `prefix`, matching every other field type) in a proper flex row with `1em` icon sizing — sizes correctly with the panel's `size` prop like every other field. This had never been visually exercised before — no existing playground demo used a `"tr"` field until `isBuilderFilter`'s "Revenue" example.