diff --git a/addon/components/bs-dropdown/menu/link-to.hbs b/addon/components/bs-dropdown/menu/link-to.hbs
new file mode 100644
index 000000000..d1ad2d8fe
--- /dev/null
+++ b/addon/components/bs-dropdown/menu/link-to.hbs
@@ -0,0 +1,29 @@
+{{#if this.model}}
+
+ {{yield}}
+
+{{else}}
+
+ {{yield}}
+
+{{/if}}
\ No newline at end of file
diff --git a/addon/components/bs-dropdown/menu/link-to.js b/addon/components/bs-dropdown/menu/link-to.js
index cb8cd73b4..1c0fd8507 100644
--- a/addon/components/bs-dropdown/menu/link-to.js
+++ b/addon/components/bs-dropdown/menu/link-to.js
@@ -1,6 +1,4 @@
-import LinkComponent from '@ember/routing/link-component';
-import { classNames } from '@ember-decorators/component';
-import { macroCondition, getOwnConfig } from '@embroider/macros';
+import LinkComponent from 'ember-bootstrap/components/bs-link-to';
/**
@@ -8,8 +6,7 @@ import { macroCondition, getOwnConfig } from '@embroider/macros';
@class DropdownMenuLinkTo
@namespace Components
- @extends Ember.LinkComponent
+ @extends Ember.Component
@public
*/
-@classNames(macroCondition(getOwnConfig().isBS4) ? 'dropdown-item' : '')
export default class DropdownMenuLinkTo extends LinkComponent {}
diff --git a/addon/components/bs-link-to.js b/addon/components/bs-link-to.js
new file mode 100644
index 000000000..5f7bb4e3c
--- /dev/null
+++ b/addon/components/bs-link-to.js
@@ -0,0 +1,113 @@
+/* eslint-disable ember/classic-decorator-no-classic-methods */
+import Component from '@ember/component';
+import { tagName } from '@ember-decorators/component';
+import { computed } from '@ember/object';
+import { inject as service } from '@ember/service';
+import { assert } from '@ember/debug';
+
+/**
+ This is largely copied from Ember.LinkComponent. It is used as extending from Ember.LinkComponent has been deprecated.
+ We need this to
+ * register ourselves to a parent component that needs to know `active` state due to Bootstrap markup requirements, see Nav/LinkTo
+ * continue supporting positional params until we can remove support
+
+ @class LinkComponent
+ @namespace Components
+ @extends Component
+ @private
+*/
+@tagName('')
+class LinkComponent extends Component {
+ // We still need to use the private service, so this component can react to changes of `currentState`, e.g. changing
+ // the model while the route in unchanged.
+ // eslint-disable-next-line ember/no-private-routing-service
+ @service('-routing')
+ _routing;
+
+ @computed('models', 'query', 'route', '_routing.currentState', 'current-when')
+ get active() {
+ let state = this._routing.currentState;
+
+ if (state) {
+ return this._isActive(state);
+ } else {
+ return false;
+ }
+ }
+
+ @computed('model', 'models')
+ get _models() {
+ let { model, models } = this;
+
+ if (model !== undefined) {
+ return [model];
+ } else if (models !== undefined) {
+ assert('The `@models` argument must be an array.', Array.isArray(models));
+ return models;
+ } else {
+ return [];
+ }
+ }
+
+ _isActive(routerState) {
+ let currentWhen = this['current-when'];
+
+ if (typeof currentWhen === 'boolean') {
+ return currentWhen;
+ }
+
+ let { _models: models, _routing: routing } = this;
+
+ if (typeof currentWhen === 'string') {
+ return currentWhen
+ .split(' ')
+ .some((route) => routing.isActiveForRoute(models, undefined, this._namespaceRoute(route), routerState));
+ } else {
+ return routing.isActiveForRoute(models, this.query || {}, this.route, routerState);
+ }
+ }
+
+ // eslint-disable-next-line ember/no-component-lifecycle-hooks
+ didReceiveAttrs() {
+ super.didReceiveAttrs(...arguments);
+
+ let { params } = this;
+ if (!params || params.length === 0) {
+ return;
+ }
+
+ params = params.slice();
+
+ // Process the positional arguments, in order.
+ // 1. Inline link title comes first, if present.
+ // if (!hasBlock) {
+ // this.set('linkTitle', params.shift());
+ // }
+
+ // 2. The last argument is possibly the `query` object.
+ let queryParams = params[params.length - 1];
+
+ if (queryParams && queryParams.isQueryParams) {
+ this.set('query', params.pop().values);
+ } else {
+ this.set('query', undefined);
+ }
+
+ // 3. If there is a `route`, it is now at index 0.
+ if (params.length === 0) {
+ this.set('route', undefined);
+ } else {
+ this.set('route', params.shift());
+ }
+
+ // 4. Any remaining indices (if any) are `models`.
+ this.set('model', undefined);
+ this.set('models', params);
+ }
+}
+
+LinkComponent.reopenClass({
+ positionalParams: 'params',
+});
+
+export default LinkComponent;
diff --git a/addon/components/bs-nav/item.js b/addon/components/bs-nav/item.js
index 0801d32e7..0f273f4b2 100644
--- a/addon/components/bs-nav/item.js
+++ b/addon/components/bs-nav/item.js
@@ -4,7 +4,7 @@ import { filter, filterBy, gt } from '@ember/object/computed';
import Component from '@ember/component';
import { action } from '@ember/object';
import { scheduleOnce } from '@ember/runloop';
-import LinkComponent from '@ember/routing/link-component';
+import LinkComponent from 'ember-bootstrap/components/bs-link-to';
import ComponentParent from 'ember-bootstrap/mixins/component-parent';
import overrideableCP from 'ember-bootstrap/utils/cp/overrideable';
import { assert } from '@ember/debug';
diff --git a/addon/components/bs-nav/link-to.hbs b/addon/components/bs-nav/link-to.hbs
new file mode 100644
index 000000000..d875a7bb9
--- /dev/null
+++ b/addon/components/bs-nav/link-to.hbs
@@ -0,0 +1,29 @@
+{{#if this.model}}
+
+ {{yield}}
+
+{{else}}
+
+ {{yield}}
+
+{{/if}}
\ No newline at end of file
diff --git a/addon/components/bs-nav/link-to.js b/addon/components/bs-nav/link-to.js
index d7321c212..206b71fed 100644
--- a/addon/components/bs-nav/link-to.js
+++ b/addon/components/bs-nav/link-to.js
@@ -1,7 +1,5 @@
-import LinkComponent from '@ember/routing/link-component';
+import LinkComponent from 'ember-bootstrap/components/bs-link-to';
import ComponentChild from 'ember-bootstrap/mixins/component-child';
-import { classNames } from '@ember-decorators/component';
-import { macroCondition, getOwnConfig } from '@embroider/macros';
/**
@@ -9,9 +7,8 @@ import { macroCondition, getOwnConfig } from '@embroider/macros';
@class NavLinkTo
@namespace Components
- @extends Ember.LinkComponent
+ @extends Ember.Component
@uses Mixins.ComponentChild
@public
*/
-@classNames(macroCondition(getOwnConfig().isBS4) ? 'nav-link' : '')
export default class NavLinkTo extends LinkComponent.extend(ComponentChild) {}
diff --git a/addon/components/bs-navbar/link-to.hbs b/addon/components/bs-navbar/link-to.hbs
new file mode 100644
index 000000000..e7f3a7f3f
--- /dev/null
+++ b/addon/components/bs-navbar/link-to.hbs
@@ -0,0 +1,14 @@
+
+ {{yield}}
+
\ No newline at end of file
diff --git a/addon/components/bs-navbar/link-to.js b/addon/components/bs-navbar/link-to.js
index bdcaf558d..285258780 100644
--- a/addon/components/bs-navbar/link-to.js
+++ b/addon/components/bs-navbar/link-to.js
@@ -1,6 +1,5 @@
-import BsNavLinkToComponent from 'ember-bootstrap/components/bs-nav/link-to';
-import defaultValue from 'ember-bootstrap/utils/default-decorator';
-
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
/**
* Extended `{{link-to}}` component for use within Navbars.
*
@@ -9,25 +8,18 @@ import defaultValue from 'ember-bootstrap/utils/default-decorator';
* @extends Components.NavLinkTo
* @public
*/
-export default class NavbarLinkTo extends BsNavLinkToComponent {
+export default class NavbarLinkTo extends Component {
/**
* @property collapseNavbar
* @type {Boolean}
* @default true
* @public
*/
- @defaultValue
- collapseNavbar = true;
-
- /**
- * @event onCollapse
- * @private
- */
- onCollapse() {}
- click() {
- if (this.collapseNavbar) {
- this.onCollapse();
+ @action
+ onClick() {
+ if (this.args.collapseNavbar ?? true) {
+ this.args.onCollapse();
}
}
}