Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.10.5] - 2026-08-27
Added
<df-image>, an image upload field: a preview of the current image, a drag & drop zone, and a button opening the browser's file dialog. It shares theFileCommscontract with<df-file>, with the difference thatuploadmust resolve to a URL the component can render directly as the image'ssrc.dfInputComponentsByTag, every component this library draws with, keyed by the tag that names it, andDfInputComponentTag, the union of those tags. A rendering layer that resolves a component out of a map rather than through Vue's resolver kept a list of its own, which had to be extended by hand whenever this package gained a component and drew nothing at all until it was.DfInputHintPropsandDfLabelPropsare declared alongside the other components' props and exported throughDfInputComponentProps. The two components declared their props inline, so a caller building<df-input-hint>or<df-label>from a layout had nothing to type the props object against.BreakpointsJSONtakes a second type argument for what a breakpoint may state, defaulting to the whole of the options type.ActionBreakpointRenderOptionsis what it is given for an action:ActionRenderOptionswithoutname,defaultConfirmanddefaultReject, which belong to the action rather than to a screen width and are now a type error at a breakpoint.<df-rtf-editor>'s toolbar gained a "Style" dropdown applying named, class-based looks (article category, title, subtitle, info box, side quote, marker, spoiler, and dark/bright code) to the current block or selection, and a media-embed tool that turns a pasted YouTube or Vimeo URL into a responsive player (any other URL is inserted as a plain link instead).<df-file>/<df-image>'s keep-alivetouchinterval is configurable: atouchIntervalprop per field, falling back to a newdefaultTouchIntervalplugin setting, falling back to the existing 60 second default. Atouch/deleteimplementation can now throwFileGoneErrorto report that the backend has already discarded the file — the component clears the field and, where acontrolis bound, shows the error'serrorTextas a validation error. Any other thrown error is left to the consumer, as before.<df-file>shows a download button next to an existing value's name whenFileCommsimplements the new, optionalgetDownloadUrl; a backend that offers no such lookup draws no button.<df-image>shows one next to its replace button whenever a value is set, since its existing value is already a URL the browser can fetch.<df-file>accepts a dropped file the same way<df-image>does: the field highlights while a file is dragged over it, and dropping uploads the file exactly as picking it from the browser's file dialog would.
Changed
- Breaking:
<df-rtf-editor>is built on TipTap instead of CKEditor 5. CKEditor 5's core is dual-licensed GPL/commercial, which put every application built on this library under the same terms unless it paid for a commercial CKEditor licence; TipTap's core and the extensions this component uses are MIT. The toolbar is now assembled from this library's own Vuetify components and icons rather than a vendor UI, so its buttons follow the application's theme and every one of its labels is atranslatableStringskey like the rest of the library's own text (see Localisation). Saved HTML content, and the content classes (h3.category,p.info-box,span.marker, and the rest) a document may already carry, are unaffected.@ckeditor/ckeditor5-vueandckeditor5are dropped frompeerDependencies, replaced by@tiptap/core,@tiptap/vue-3,@tiptap/pm,@tiptap/starter-kit,@tiptap/extension-image,@tiptap/extension-link,@tiptap/extension-placeholder,@tiptap/extension-tableand its-row/-cell/-headercompanions, and@tiptap/extension-text-align. - Images: insertion by URL, upload, or clipboard paste all embed the picture as a base64
data:URI, matching the previousBase64UploadAdapterbehaviour, and a placed image resizes by dragging its corner and edge handles. - Pasting a Word or Google Docs selection strips the source application's clutter —
mso-*inline styles,Mso*classes,o:pand other namespaced tags, conditional comments — while formatted text, embedded images and tables come through as structured content.
Removed
- Breaking:
setCkEditorLanguage()and theckEditorLanguageobject. CKEditor 5 shipped its own translated UI bundles, which these configured; TipTap is headless, so the RTF editor's entire toolbar is text this library itself owns, translated the same way as everything else, throughtranslateStrings().
Fixed
<df-image>'s drag-over highlight no longer gets stuck on after a drag ends.dragoverfires continuously while a file hovers over the drop zone, and was incrementing the same counter asdragenter; a singledragleavecouldn't bring it back down, so the dashed outline stayed until the page reloaded, surviving even the field's own clear button.<df-file>shows an existing value's name. Its label read the rawmodelValueprop, which stays unset when the field is bound throughcontrolrather thanv-model- every consumer using thecontrolbinding saw a blank input for a field that already held a file.- A field that only a breakpoint states is resolved. The fields taking part in the cascade were read off the base options, so an option named at
mdand nowhere else was dropped:{ label: 'Save', md: { icon: 'save-outline', showIcon: true } }drew no icon at any width, and an action whose value stated nothing at the base drew nothing anywhere. The cascade covers the fields each breakpoint states. getRenderOptionsForBreakpoint()answersname,defaultConfirm,defaultRejectandpassthroughAttrs. It declarednameand returnedundefinedfor it whatever the value held, and did not carry the other three at all, so<df-actions>read the colour flags and the attrs straight off the raw value to draw a button. Resolved options carry every memberActionRenderOptionsdeclares.passthroughAttrsresolves per breakpoint, merged key by key like any plain object, so a breakpoint restatingcolorleaves thedensitybelow it standing.
[0.9.1] - 2026-08-20
Added
<df-actions>draws an action declared as theActionof@dynamicforms/vue-forms. It read the breakpoint options through an accessor only this library's subclass declares and threw aTypeErrorover anything else; it reads them off the action's value instead, so an action stating a label alone is drawn as a button showing it. The subclass is what an action needs to render responsively, as a text link or in a confirm / reject colour - not what it needs to be drawn at all.getRenderOptionsForBreakpoint(value, breakpoint)is exported: theActionRenderOptionsan action's value renders as at one breakpoint, defaults filled in andlabel/iconfiltered by their flags.Action.getBreakpointValue()is acomputed()over it.
Changed
- A button
<df-actions>draws is disabled where any container above the action is disabled, and while a run of the action has yet to settle - the latter draws itloadingbesides. The button bound the action's ownenabledand read nobusy, so an action in a disabledGroupwas clickable where the keyboard would not reach it, and a second click started a second run of a handler still in flight. What disables the button is!action.effectiveEnabled || action.busy;enabledon the action is unchanged and still answers what was written to it. passthroughAttrsnow takes precedence overloadingas well, which is one more prop the component computes on its own.
Fixed
exports["."]states atypescondition. TypeScript resolves a package carrying anexportsmap through that map alone and ignores the top-leveltypesfield, so a consumer onmoduleResolution: "bundler"or"node16"found no declarations: every import from the package wasany, and nothing this library exports -Action,BreakpointNames, the components, the props - was checked at all.
[0.9.0] - 2026-08-20
Changed
The
@dynamicforms/vue-formspeer dependency is^0.17.0, thevuepeer is^3.5.2andengines.nodeis>=22. The last two are the peer library's own floors. Eleven of its releases sit between 0.6.0 and 0.17.0; an application's own use of it migrates in the same step, which the migration guide points at.useInputBase()returnsdensityas theComputedRefit computes, where it returned that computed's value as a plain string read once during setup. A consumer outside a template needs.value, and the density now follows a later change of thedensityprop. An injectedfield-densityand the plugin'sdefaultDensityare read once, as configuration.densityClassis unchanged.The
visibilityprop is resolved throughDisplayMode.fromAny(), so it accepts a constant's name case-insensitively -visibility="hidden"states what it looks like it states - and a value naming noDisplayModeconstant throws where the field renders. Both used to render the field fully and say nothing. The prop is typedForm.DisplayMode | stringaccordingly.An input bound to a
controlemitsupdate:modelValuewith the value the control ended up holding rather than the value that was written to it. The two differ where the field does not take a write verbatim: aValueChangedActionthat normalises it, a disabled field that drops it, a handler that throws and so unwinds the operation. An input with nocontrolemits what was written, as before.An input bound to a control is drawn disabled while any container above that control is disabled. It read the element's own
enabled, so the fields of a disabled section stayed editable.enabledon each element is unchanged and still answers what was written to it; what an input draws from iseffectiveEnabled.ActionRenderOptionsstateslabelandiconas strings.ActionValuetypes bothunknownfrom vue-forms 0.17.0, leaving what a label is to the rendering library, and this is that library saying so.
Fixed
An input treats an accepted write of an array or an object as accepted. An element holds its state behind
reactive(), so such a value reads back as a proxy of what was written; the composable compared identities and concluded that every one of those writes had been refused, holding the written value for a tick and scheduling a second render of the input per change. The comparison is made over the raw objects.Action.labelandAction.iconare the peer library's accessors and answer what the action carries. This class declared both as getters that filter the read byshowLabelandshowIcon; a getter declared alone defines the whole property, so the assignment the peer documents threw aTypeError, and the filter tested the flags for truthiness rather than forfalse, so an action stating neither answeredundefinedfrom both while<df-actions>drew the text and the icon. The filtered reads arerenderedLabelandrenderedIcon, which is what the action draws;labelandiconanswer the text and the name, and take writes.df-fileanddf-datetimeapply their density-dependent wrapper class whatever the density is resolved from. The template read thedensityprop, so the class was missing whenever the density came from an injectedfield-densityor from the plugin settings; both components now read the resolved density fromuseInputBase().df-selectno longer shows a selection the control refused. A write the model unwinds - a validator that throws, a disabled field - never reached the watch that pushes the model's value back into the chips, so they went on displaying a choice the control never took. What the control holds is compared against what was written, deeply, since a multiple selection reads back as a different array holding the same items.df-selectwarns aboutchoicesandfetchChoicesonly when both are set. The check tested the computed list of items, which is an array and so always truthy, and the warning therefore fired for every select given nothing butfetchChoices.
Added
- An element carries the presentation the components render it with.
label,placeholder,helpText,hint,cssClass,densityandvariantare declared on vue-forms'Extrasaugmentation point, so they are typed on every element in an application that installs this library - the fields written inline in aGroupdeclaration included - and are stated in the parameters an element is built with or written later withsetExtendedValues(). A form declared in code therefore describes itself, and<df-input :control="form.fields.name" />needs no attribute of its own. A prop wins where both state something, and what an element carries wins over an injectedfield-density/field-variantand over the plugin defaults. - Documentation of the configuration cascade at
/examples/configuration: the plugin's options, whatprovideoffield-densityandfield-variantreaches, and the order the two are resolved in. - Documentation of
DfInputHintat/examples/df-input-hint: the props of the message row every input renders, and what it takes when it is used on its own for a group's errors. - Documentation of localisation at
/examples/localisation: every translatable string with its default and where it surfaces, CKEditor's interface language, and the date-fns locale<df-date-time>formats and parses with.
[0.8.1] - 2026-08-16
Fixed
ResponsiveRenderOptions.getOptionsForBreakpoint()merges an object-valued option key by key. It replaced the object wholesale, so a breakpoint restating one key dropped every other key it inherited. Single values are replaced as before, and so is anything that is not a plain object - aDate, aMapor a class instance would come out of a merge as a bare copy of its own properties. The options this package ships are single values throughout, soActionand<df-actions>resolve exactly as before.
Added
- Documentation of the cascade for anyone subclassing
ResponsiveRenderOptions, at/examples/responsive-render-options: what each kind of value does at a breakpoint, that the object merge is shallow, and the contractcleanBreakpoint()has to keep - a field the breakpoint does not state comes backundefined, since an empty value is a value and replaces what was inherited.
[0.8.0] - 2026-08-15
Removed
Action.create(). Actions are constructed withnew Action(...), matching @dynamicforms/vue-forms 0.6.0, which removedField.create()andAction.create().Action.closeAction(),Action.yesAction()andAction.noAction()are unaffected.- The
DFInputHintexport. The component was reachable under two names;DfInputHintremains, and is the name the plugin registers it under, so the<df-input-hint>tag resolves underregisterComponents: true.
Changed
- The
controlprop is typedFieldBase<T>. vue-forms removed theIFieldinterface the prop was typed with; the runtime guard has always beeninstanceof FieldBase. - The
@dynamicforms/vue-formspeer dependency is^0.6.0.
Added
- Documentation for group-level validation errors and conditional group visibility, which @dynamicforms/vue-forms 0.6.0 made observable by constructing
GroupandListas Vue reactive objects. - A migration guide at
/guide/migration.
Fixed
- Every input component honours the visibility of its
control;df-checkbox,df-coloranddf-inputignored it altogether, whiledf-selectanddf-text-arearead thevisibilityprop instead of the control. DisplayModeis resolved in one place,useInputBase, which the components consume for both the render decision (SUPPRESS) and thed-none/invisibleclasses (HIDDEN/INVISIBLE).DisplayMode.INVISIBLEhides the element. Theinvisibleclass the components apply for it is defined by the package stylesheet; Vuetify ships no such rule, so the mode had no effect.
[0.7.0] - 2026-01-28
Added
- df-input-hint wrapper around messages-widget. It can take both a fields description / hint or a list of errors and displays errors as priority, otherwise hint / description messages-widget removed as it's provided in the vue-forms package The wrapper itself is now exported for use in further packages / apps
Removed
- messages-widget (see df-input-hint above for details)
[0.6.6] - 2025-11-10
Added
- Translatable editor
[0.6.3 - 0.6.5] - 2025-10-22
Added
- Support additional attributes for rendering the MdString
[0.6.2] - 2025-10-01
Added
- Support MdString for label text
Changed
- All label rendering goes through df-label
[0.6.0] - 2025-09-28
Added
- Initial effort for all the inputs to be correctly vertically aligned
- Initial effort for all inputs to render correctly in all Vuetify variants
- Density: inline for use in tables
[0.5.13] - 2025-09-25
Fixed
- Fix SSR
[0.5.10 - 0.5.12] - 2025-09-24
Fixed
- Version bumps
- Fixed CSS location in package.json
[0.5.9] - 2025-09-19
Added
- Add support for vue-forms' touched property
[0.5.8] - 2025-09-18
Changed
- Support vuetify 3.9+ instead of 3.8+
[0.5.7] - 2025-09-05
Added
- messages-widget now takes additional parameter "classes" to be used on its generated elements. default
'text-error'
Changed
- messages-widget modified to render functions to speed up rendering and remove redundancies in DOM elements
[0.5.6] - 2025-08-25
Added
- input base: all components now take
passthrough-attrsprop that contains any props that should be passed to the underlying vuetify component.
[0.5.5] - 2025-08-21
Added
- df-date-time now supports tracking current locale via
DateTimeLocaleConfig.setDateTimeLocale(locale: Locale | Ref<Locale>)configuration.
[0.5.4] - 2025-07-29
Fixed
- df-date-time did not implement the clearable prop
[0.5.3] - 2025-07-17
Added
- input retains its value when no v-model and no control is given to hold the value instead
[0.5.2] - 2025-07-17
Added
- export props interfaces for the inputs
[0.5.1] - 2025-06-09
Added
- Translation support for predefined actions
Fixed
- Removed breakpoint parameter from predefined actions (it was useless)
[0.5.0] - 2025-05-31
Changed
- Refactored Action component to extend Form.Action instead of using it as a property, providing better inheritance and type safety
- Action is now fully responsive with support for breakpoint-based declarations
[0.4.2 - 0.4.5] - 2025-05-19
Added
- Reactive choices and value support for df-select component
- New slots (append-inner, prepend-inner) for df-select component customization
[0.4.0 - 0.4.1] - 2025-05-18
Fixed
- Uniform input styling across all input-base components
- Error display now only shows after field has been touched, improving user experience
- Proper error rendering with enhanced validation message support
[0.3.1 - 0.3.3] - 2025-05-17
Added
- Settings support with configurable input variants (outlined, underlined, etc.)
- Image support in component labels alongside existing icon support
Fixed
- DateTime component label display issues
- Select component bug where previously selected choices were lost during new searches
- Density and variant processing for df-datetime component
[0.2.4] - 2025-05-13
Changed
- Reorganized dropdown layouts for better user experience
[0.2.3] - 2025-05-08
Added
- Exported getBreakpointName function for external use
[0.2.1 - 0.2.2] - 2025-05-04
Fixed
- Type declarations and member visibility improvements
- Generic solution for ResponsiveRenderOptions with correct exports
[0.1.11 - 0.1.15] - 2025-04-21
Changed
- Simplified select component due to variant changes
- Unified input heights across all components
- Enhanced message widget to support hints and help text
Fixed
- Number input demo styling issues
- Precision handling (null when undefined)
- Selection clearing functionality in df-select component
Removed
- Redundant form data handling
Added
- Proper styles declaration
[0.1.7 - 0.1.10] - 2025-04-19
Fixed
- Color picker closing behavior - no longer closes on every internal click
- Checkbox unnecessary value reassignments
- DateTime values now include timezone information
Changed
- Updated repository URL
- Excluded Vuetify components from package bundle for smaller distribution size
[0.1.0 - 0.1.6] - 2025-04-18
Added
- Initial implementation with three example components
- Helper classes for component development
- Complete documentation with working examples
- Integration with @dynamicforms/vue-forms
- TypeScript support
- Vuetify-based styling
- df-date-time component with full Vuetify integration
- df-textarea component with configurable rows and auto-grow
- df-file component with upload progress indication
- df-select component with static/dynamic options and multiple selection
- InputBase foundation component for all inputs
- Visibility support for textarea and select components
- Clearable functionality for input-base
- df-input component for general text input
- Support for multiple input types (text, email, password, URL, number)
- df-color component for color selection
- df-checkbox component with binary and ternary state support
- df-rtf-editor component with CKEditor integration
- df-actions component moved from separate package for better integration
- MDI font requirement for icons
- Advanced validation rendering supporting string, Markdown, and custom components
- Vue-forms validation support
