Skip to content

Releases: ng2-ui/auto-complete

Angular 22 & Zoneless

Choose a tag to compare

@almothafar almothafar released this 07 Jun 21:07
a4466e3

[22.0.0] — 2026-06-07

A framework-only major: the public API is unchanged from 21.x. The consumer-visible changes are the
bumped Angular peer requirement and one dropdown-positioning fix (below).

⚠️ BREAKING CHANGES

  • Requires Angular 22. peerDependencies now require @angular/cdk, @angular/common and
    @angular/core ^22.0.0. Angular 21 and older projects must stay on @ngui/auto-complete@21 (or the
    matching major).

Fixed

  • Standalone <ngui-auto-complete> dropdown now overlays the content below it instead of pushing it
    down.
    When opening downward (the default), the list was rendered in normal document flow, so it grew
    its host and could scroll the page; it now floats (position: absolute; top: 100%), matching the
    existing upward (dropup) behavior. The directive's CDK-overlay path is unchanged. The float layer uses
    z-index: var(--ngui-ac-z-index, 10), so you can override --ngui-ac-z-index if it collides with other
    stacked UI.

Internal (development tooling only — no impact on consumers)

  • ng update to Angular 22: @angular/cli + @angular/build 22.0.0, @angular/cdk + @angular/material
    22.0.0, ng-packagr 22.0.0, angular-eslint 22.0.0, TypeScript 6.0.x.
  • Adopted ChangeDetectionStrategy.OnPush in the demo app and the spec test-host components, satisfying
    angular-eslint 22's new recommended prefer-on-push-component-change-detection rule with no opt-outs
    (the published library component was already OnPush).
  • TypeScript 6.0 config. TS 6 deprecates baseUrl, so the root tsconfig.json drops it and uses
    relative paths instead.
  • Enabled TypeScript strict mode (strict: true) and tightened types accordingly — replacing
    remaining anys with precise types (e.g. ReturnType<typeof setTimeout>, generics, unknown) and
    adding null-safety guards. No public API or runtime behavior change (#500).
  • Enabled strict template type-checking (strictTemplates: true in the root angularCompilerOptions),
    the natural companion to strict above. The library compiles cleanly under it; the only fix needed was a
    more precise type on a demo field (open-direction binding). No public API or runtime behavior change —
    this only tightens the library's own build (#503).
  • Went fully zoneless. Angular 22 is zoneless by default, so zone.js is removed entirely: the demo app
    bootstraps with provideZonelessChangeDetection() (zone.js polyfill dropped from angular.json), the
    unit-test harness drops zone.js/testing and configures provideZonelessChangeDetection() in TestBed,
    and zone.js is removed from dependencies. The published library was already zoneless-ready (signals +
    OnPush, never shipped zone.js), so this is purely a demo/test change with no consumer impact. The few
    fakeAsync/waitForAsync specs (which still require zone.js) were rewritten to plain async/await.
  • Bumped jasmine-core to 6.3.x (dev/test only).
  • Migrated the build to the @angular/build builders. angular.json now uses @angular/build:*
    (application, dev-server, ng-packagr, karma, extract-i18n) instead of the deprecated
    @angular-devkit/build-angular:* aliases, and the karma.conf.js files drop the old framework/plugin
    (the new karma builder wires these in itself). Removing the @angular-devkit/build-angular package
    (replaced by @angular/build) drops the legacy Webpack toolchain — ~370 fewer installed packages and 0
    audit vulnerabilities. Build output is unchanged.
  • Fixed the Cypress e2e config for TypeScript 6: projects/demo/cypress/tsconfig.json now sets an explicit
    rootDir, which TS 6 requires (TS5011) when an outDir is inherited and the included files span more
    than one directory. Without it, npm run cypress:run failed to compile the spec. Dev/test only.

What's Changed

  • refactor: enable TypeScript strict mode by @almothafar in #500
  • build: enable strict template type-checking by @almothafar in #503
  • feat!: upgrade to Angular 22 by @almothafar in #502
  • build: go fully zoneless (remove zone.js); upgrade jasmine-core by @almothafar in #505
  • fix: float the standalone component dropdown so it overlays content by @almothafar in #506
  • build: migrate to @angular/build builders, drop @angular-devkit/build-angular by @almothafar in #507
  • docs: document the --ngui-ac-z-index theming variable by @almothafar in #508
  • fix(cypress): set explicit rootDir for TypeScript 6 (TS5011) by @almothafar in #509
  • docs: clarify publish step, v22 migration, and license holders by @almothafar in #510

Full Changelog: 21.0.0...22.0.0

Revamp, Modern, Angular 21

Choose a tag to compare

@almothafar almothafar released this 06 Jun 15:18
3c6341f

[21.0.0] — 2026-06-04

⚠️ BREAKING CHANGES

  • Requires Angular 21. peerDependencies now require @angular/common and @angular/core
    ^21.0.0. Angular 20 and older projects must stay on @ngui/auto-complete@20 (or the matching major).
  • Removed NguiAutoCompleteModule. The library's last NgModule has been deleted. Import the
    standalone NguiAutoCompleteComponent / NguiAutoCompleteDirective directly instead:
    imports: [NguiAutoCompleteComponent, NguiAutoCompleteDirective]. Apps that still need the NgModule
    can stay on @ngui/auto-complete@20, which retained it.
  • The directive is now a ControlValueAccessor. NguiAutoCompleteDirective implements
    ControlValueAccessor and provides NG_VALUE_ACCESSOR, so [(ngModel)], [formControl] and
    formControlName integrate through Angular forms (with proper valueChanges, touched/dirty state).
    Consequences (see MIGRATION.md for before/after):
    • Removed the directive's bespoke ngModel input and its (ngModelChange) and
      (valueChanged) outputs. Use [(ngModel)] (Angular still emits (ngModelChange)) or a reactive
      form. (valueChanged) has no direct replacement — use (ngModelChange) or the control's valueChanges.
    • Removed the directive's custom [formControl] / formControlName inputs. The standard Angular
      directives now drive it directly — same template syntax, now with full form integration.
    • Wrapper-<div> usage: bind the value on the host
      (<div ngui-auto-complete [(ngModel)]="x"><input></div>) instead of on a separate inner <input>.
      Direct <input ngui-auto-complete [(ngModel)]="x"> is unchanged.
  • Unified the selection outputs into one (valueSelected) event. valueSelected + customSelected
    are merged into a single (valueSelected) (on both the component and directive) carrying
    NguiAutoCompleteSelection { value, item, index, fromSource }fromSource is true for a list pick,
    false for a typed value. (customSelected) is removed (check fromSource: false). The payload changed
    from the bare value to this object, so (valueSelected)="x = $event"(valueSelected)="x = $event.value"
    (or use [(ngModel)] / [(value)] for the value). The never-emitted textEntered output is also
    removed. (noMatchFound) is unchanged.
  • Consolidated value display into one display-with input. display-property-name and the
    string-template value-formatter are replaced by a single display-with that accepts either a
    property name or a function: display-with="name" or [display-with]="(item) => …". (list-formatter
    still formats the dropdown rows.) Migrate display-property-name="name"display-with="name", and
    value-formatter="(key) name"[display-with]="(item) => '(' + item.key + ') ' + item.name".
  • Removed the is-rtl input. Direction is now auto-detected from the input's computed direction, so
    an ancestor dir="rtl" (or the document direction) positions the dropdown correctly on its own — no
    input and no extra dependency. Replace [is-rtl]="true" with dir="rtl" on the element or an ancestor.
  • Replaced the innerHTML string templates with TemplateRefs. The string loading-template and
    header-item-template inputs are removed. Use the headerTemplate TemplateRef (already available) and
    the new loadingTemplate TemplateRef (loading-text remains for the simple case). This also removes
    an innerHTML sink.
  • source is now a required input. source uses input.required on both the component and directive
    (it was always required in practice — the control does nothing without it). Omitting [source] is now a
    compile-time error under strict templates (and a runtime error otherwise) instead of silently doing
    nothing. Just ensure every [ngui-auto-complete] / <ngui-auto-complete> has a [source].
  • New @angular/cdk peer dependency (directive dropdown now uses the CDK Overlay). The
    [ngui-auto-complete] directive renders its dropdown through @angular/cdk/overlay instead of inserting
    an absolutely-positioned element next to the input. You must install @angular/cdk@^21 and include the
    CDK overlay styles once in your app — either @import '@angular/cdk/overlay-prebuilt.css'; or any
    @angular/material theme (which already bundles them). See MIGRATION.md.

Added

  • [(value)] two-way binding on NguiAutoCompleteComponent. The standalone component now exposes a
    value model — e.g. <ngui-auto-complete [(value)]="myValue">. (valueSelected) continues to fire.
  • NguiAutoCompleteSelection<T> interface exported for the (valueSelected) payload
    ({ value, item, index, fromSource }).
  • Generic NguiAutoCompleteComponent<T = any>. Binding a typed [source] (array or function)
    infers the item type, so [(value)], (valueSelected) (NguiAutoCompleteSelection<T>) and the
    itemTemplate context are all typed without any annotation. Defaults to any, so existing templates
    are unaffected. The directive stays loosely typed (Angular can't infer generics for an attribute
    directive in templates).

Changed

  • Upgraded to Angular 21 (@angular/* 21.2.x, @angular/material + @angular/cdk 21.2.x).
    Install @ngui/auto-complete@21 for Angular 21 projects.
  • Signal-based inputs/outputs. All @Input()s are now signal input()s and all @Output()s are
    output()s on both the component and directive (the component's @ViewChilds became viewChild()
    queries). Template bindings are unchanged — every input keeps its existing name/alias (e.g.
    min-chars, list-formatter). The only consumer-visible effect is for code that reaches into a
    component/directive instance programmatically: those input properties are now read-only signals
    (call them, e.g. cmp.minChars()), not plain fields.
  • Typed attribute coercion. Numeric inputs (min-chars, max-num-list, z-index) now use
    numberAttribute and boolean inputs use booleanAttribute, so string-attribute forms (min-chars="2")
    and bound forms ([min-chars]="2") are both correctly typed.
  • OnPush dropdown component. NguiAutoCompleteComponent now uses ChangeDetectionStrategy.OnPush
    and its internal state (dropdownVisible, isLoading, filteredList, minCharsEntered, itemIndex)
    is signal-based, so remote/async results and directive-driven updates refresh reliably with less change
    detection work. No public API change.
  • Bumped the library's own tslib dependency floor to ^2.8.1.
  • The "drop-up" dropdown now anchors with the logical inset-inline-start instead of left, so it sits
    on the correct edge under RTL (matching the directive's positioning). No API change.
  • CDK Overlay positioning (directive). The dropdown now renders in a CDK overlay at the document root,
    so it escapes ancestor clipping / stacking contexts (e.g. inside a mat-form-field or a card with
    overflow: hidden) and flips above/below automatically on overflow. As a result, open-direction is now
    a preference (the overlay still flips when there isn't room), and z-index is rarely needed (the
    overlay already layers above page content; it now only orders overlapping overlays). RTL follows the
    input's computed direction. Note: because the dropdown is at the document root, custom dropdown
    styles (e.g. classes from a list-formatter) must be global, not scoped to an ancestor of the input.
  • Refreshed, themeable dropdown styling. The dropdown now has a subtle elevation, rounded corners, a
    softer border and roomier rows. Appearance is exposed through CSS variables — --ngui-ac-background,
    --ngui-ac-color, --ngui-ac-border, --ngui-ac-border-radius, --ngui-ac-shadow,
    --ngui-ac-max-height (none to remove the cap), --ngui-ac-item-padding, --ngui-ac-item-border,
    --ngui-ac-hover-background and --ngui-ac-selected-background — each with a sensible default (set them
    on :root). See the
    README "Theming" section. Applies to the directive and component.

Fixed

  • Internal keyword input a11y. The component's internal input (rendered when show-input-tag) now
    carries a unique id, clearing the browser's "a form field element should have an id or name" warning.
    It is bound standalone, so it never registers into a consumer's parent <form> (no stray
    keyword control) — which also fixes a latent error when the component was used inside a <form>.

Internal (development tooling only — no impact on consumers)

  • ng update to Angular 21: @angular/cli + @angular-devkit/build-angular 21.2.x,
    ng-packagr 21.2.5, TypeScript 5.9.3. The demo bootstrapApplication now provides
    provideZoneChangeDetection() (Angular 21 defaults to zoneless; this preserves the existing
    zone-based change detection).
  • ESLint 10. Bumped eslint and @eslint/js to 10 and angular-eslint to 21.4.0 (its ESLint peer
    now allows ^10), unblocking the upgrade deferred in 19.0.0 / 20.0.0.
  • The directive now forwards inputs to the dynamically created dropdown via ComponentRef.setInput()
    (required now that the component's inputs are read-only signals).

What's Changed

Read more

Angular 20

Choose a tag to compare

@almothafar almothafar released this 04 Jun 18:22
64c764b

[20.0.0] — 2026-06-04

⚠️ BREAKING CHANGES

  • Requires Angular 20. peerDependencies now require @angular/common and @angular/core
    ^20.0.0. Angular 19 and older projects must stay on @ngui/auto-complete@19.
  • Removed the unprefixed [auto-complete] directive selector. Use [ngui-auto-complete] instead
    (the directive now matches [ngui-auto-complete] only). Update any templates using the bare
    auto-complete attribute: <input auto-complete …><input ngui-auto-complete …>.

Added

  • itemTemplate and headerTemplate inputs (Angular ng-templates) on the component and directive to
    customize dropdown rows and the header row, as a typed alternative to the string-based list-formatter
    / header-item-template. The item template receives the item as $implicit and the row index; the
    string formatters remain supported and the templates take precedence when provided (fixes #357).
  • open-direction input (auto | up | down) on the directive and component to control whether the
    dropdown opens above or below the input. up/down force the direction; auto (default) keeps the
    previous behaviour of opening above only when the input is near the bottom of the viewport (fixes #386).

Changed

  • Upgraded to Angular 20 (@angular/* 20.3.x, @angular/material + @angular/cdk 20.2.x).
    Install @ngui/auto-complete@20 for Angular 20 projects.
  • Standalone components. NguiAutoCompleteComponent and NguiAutoCompleteDirective are now
    standalone. NguiAutoCompleteModule is retained and re-exports both, so existing
    imports: [NguiAutoCompleteModule] consumers keep working unchanged — you can now alternatively
    import the standalone component/directive directly. (Full NgModule removal is planned for Angular 21.)
  • inject() DI. Constructor parameter injection across the library was migrated to the inject()
    function (no public API change).

Internal (development tooling only — no impact on consumers)

  • ng update to Angular 20: @angular/cli + @angular-devkit/build-angular 20.3.x,
    ng-packagr 20.3.2, angular-eslint 20.7.0. Workspace migrations applied (schematic type
    defaults in angular.json, tsconfig moduleResolutionbundler).
  • Bumped @cypress/schematic 4.3 → 5 (now requires Angular 20).
  • Re-enabled the @angular-eslint/prefer-standalone lint rule (deferred in 19.0.0).
  • The demo app was migrated to a standalone bootstrapApplication setup (AppModule and the routing
    NgModule removed in favour of provideRouter + app.routes.ts).
  • Hardened the library component spec so its focus-triggered dropdown reload resolves against a local
    source array (Angular 20 / zone.js surfaces the previously-swallowed async error).

Notes

  • ESLint 10 remains deferred: angular-eslint 20 still peers on ESLint ^8.57 || ^9. It is planned for
    the Angular 21 release alongside full NgModule removal.

What's Changed

Full Changelog: 19.0.0...20.0.0

Angular 19 Support

Choose a tag to compare

@almothafar almothafar released this 04 Jun 11:36
669a8aa

[19.0.0] — 2026-06-04

Changed

  • Upgraded to Angular 19 (@angular/* 19.2.x). peerDependencies now require @angular/common
    and @angular/core ^19.0.0. Install @ngui/auto-complete@19 for Angular 19 projects.
  • Migrated the library template to Angular's built-in control flow syntax (@if / @for in place of
    *ngIf / *ngFor).

Internal (development tooling only — no impact on consumers)

  • Migrated ESLint from .eslintrc.json to flat config (eslint.config.js); upgraded ESLint 8 → 9 and
    switched to the unified angular-eslint and typescript-eslint packages.
  • Bumped dev dependencies to the newest versions compatible with Angular 19: cypress 13 → 15,
    @cypress/schematic 2 → 4.3, eslint-plugin-cypress 3 → 6, jasmine-core + @types/jasmine 5 → 6,
    @types/node 22 → 24, karma-jasmine-html-reporter 2.1 → 2.2 (reduces npm audit from 52 to 9).
  • Added unit specs for the library component and service, and replaced the stale Angular CLI boilerplate
    demo specs with working TestBed setups.

Notes

  • The library remains NgModule-based in this release; the standalone migration is planned for the
    Angular 20 release.
  • ESLint 10, @cypress/schematic 5, and the standalone migration are deferred to the Angular 20 release
    (they require Angular 20 / angular-eslint 20).

What's Changed

  • fix(demo): suppress built-in no-match row in (noMatchFound) demo card by @almothafar in #478
  • feat: upgrade to Angular 19 + control flow migration (v19.0.0) by @almothafar in #479
  • test(e2e): fix stale cypress smoke spec for current demo by @almothafar in #481
  • docs(changelog): document tooling changes in the 19.0.0 entry by @almothafar in #482

Full Changelog: 18.6.0...19.0.0

Bug Fixes and No Result Event

Choose a tag to compare

@almothafar almothafar released this 03 Jun 21:52
96a931d

[18.6.0] — 2026-06-04

Fixed

  • select-value-of now correctly extracts falsy property values (0, null, false, '') from the
    selected object — previously the truthiness check caused the raw item to be emitted instead of the
    extracted property (fixes #373)

Added

  • no-match-found-text="" (empty string) now fully suppresses the "No Result Found" row — previously
    the empty string fell through to the default text (fixes #307, #292, #198)
  • (noMatchFound) output on both <ngui-auto-complete> component and [ngui-auto-complete] directive —
    fires whenever the filtered list is empty and min-chars threshold has been met, enabling consumers
    to render an "Add new…" affordance

What's Changed

  • Pre-phase: demo polish — hero section, toolbar labels, max-width by @almothafar in #469
  • fix(demo): constrain tabs width, fix grid alignment, fix Material input styling by @almothafar in #470
  • fix(demo): hash routing + no-cache meta to fix GitHub Pages 404 on refresh by @almothafar in #471
  • ci: add GitHub Actions CI + fix premature standalone section in README by @almothafar in #472
  • fix(ci): add checkout step to deploy-docs job by @almothafar in #473
  • fix(demo): remove ES5 browserslist warning & fix Material suffix border by @almothafar in #474
  • fix(demo): correct .00 suffix border + show last build time in footer by @almothafar in #475
  • fix: select-value-of falsy values + configurable no-match-found (v18.6.0) by @almothafar in #476
  • docs(demo): add (noMatchFound) + no-match-found-text demo cards and README updates by @almothafar in #477

Full Changelog: 18.5.0...18.6.0

Revamp Demo and Minor fixes

Choose a tag to compare

@almothafar almothafar released this 02 Jun 22:57
de3b62d

[18.5.0] — 2026-06-03

Fixed

  • Scoped NguiAutoCompleteService per-component instance (was a module singleton — multiple simultaneous
    <ngui-auto-complete> components overwrote each other's source property causing a runtime crash)
  • isLoading no longer stays stuck true after a failed HTTP request — error handler now resets it
  • ngOnDestroy subscription teardown: replaced invalid EventEmitter.unsubscribe() calls with proper
    RxJS Subscription management via dropdownSubs
  • Replaced UntypedFormControl / UntypedFormGroup with typed FormControl / FormGroup
  • Root .eslintrc.json referenced non-existent e2e/tsconfig.json — removed
  • Project ESLint configs used file-relative tsconfig paths — changed to workspace-root-relative
  • demo:prefix in angular.json was docs instead of app
  • Removed broken ct Cypress component-test target from the library angular.json entry
    (referenced non-existent auto-complete:serve target)
  • auto-select-first-item demo was missing [auto-select-first-item]="true" — feature was never active

Changed

  • Replaced deprecated karma-coverage-istanbul-reporter with karma-coverage
  • Removed unused @types/jasminewd2 (Protractor artefact, not needed with Cypress)
  • Pinned cypress to ^13.0.0 instead of "latest"
  • Demo Observable source example replaced from Marvel API (broken auth) to Open Library (free, no key)
  • Demo HTTP source examples replaced from Google Maps (requires key) to Nominatim/OpenStreetMap (free, no key)
  • RTL demo updated to use Arabic city names with dir="rtl" scoped to the demo area only

Added

  • Angular Material toolbar in demo app with library title and links to GitHub / npm
  • Demo examples use <mat-card> layout in a responsive CSS grid (2-column desktop, 1-column mobile)
  • Collapsible "View Template" expansion panel per demo example
  • MatToolbarModule, MatCardModule, MatExpansionModule, MatButtonModule added to demo module
  • Revamped styles.scss: indigo-pink Material theme, global typography, dark code-block styling
  • Descriptive subtitles and usage hints on all directive and component demo examples
  • Restructured README: badges, API reference table, version-compatibility table, updated dev instructions

What's Changed

Full Changelog: 18.0.0...18.5.0

Angular 18 Support

Choose a tag to compare

@almothafar almothafar released this 16 Sep 15:00
8825466

[18.0.0] Major Update

  • Upgraded to support Angular 18
  • Migration for deprecated Observable params
  • Adding e2e smock test for the project removing deprecated protractor adding cypress

What's Changed

Full Changelog: 17.0.0...18.0.0

Angular 17 Support

Choose a tag to compare

@almothafar almothafar released this 16 Sep 03:12
467fe03

[17.0.0] Major Update

  • Upgraded to support Angular 17

What's Changed

Full Changelog: 16.0.0...17.0.0

Angular 16 Support

Choose a tag to compare

@almothafar almothafar released this 16 Sep 02:56
ae924fb

[16.0.0] Major Update

  • Upgraded to support Angular 16

What's Changed

Full Changelog: 15.0.0...16.0.0

Angular 15 Support

Choose a tag to compare

@almothafar almothafar released this 16 Sep 01:59
f22dc6e

[15.0.0] Major Update

  • Upgraded to support Angular 15
  • Remove deprecated modules and services
  • Refactor code base splitting SCSS and HTML to separated files
  • Fix Demo/Docs project

What's Changed

Full Changelog: 14.0.0...15.0.0