From 323f044c795c470f2b70a8d3247fb029bd9f5595 Mon Sep 17 00:00:00 2001
From: Gaurav Munjal
Date: Mon, 2 Nov 2026 08:41:59 -0500
Subject: [PATCH] SCF-2416: keep Bootstrap 3 and subclassing, drop their
deprecations
This fork will not remove Bootstrap 3 support or subclassing of the
component classes, so neither should warn that it is going away.
Subclassing (port of upstream #2049, "Drop component subclassing
deprecation", released in upstream 6.2.0):
- addon/utils/deprecate-subclassing.js and every @deprecateSubclassing
are removed, along with the '__ember-bootstrap_subclass' escape-hatch
fields on the four internal subclasses that used it.
- Unlike #2049, BsProgress and NavbarContent stay empty classes instead
of becoming templateOnly(), which can't be subclassed.
- The API docs no longer say subclassing "is generally not supported,
and may break at any time"; they say it is supported.
- The subclassing test now checks that a subclass of each of the 15
public components renders with no deprecations, replacing the two
tests per component that asserted and silenced the deprecation.
Bootstrap 3: index.js no longer warns at build time that Bootstrap 3
support "will be removed in ember-bootstrap v5". The Glyphicon warning
for Bootstrap 4/5 stays; it is a configuration hint.
README: the intro says Bootstrap 3, 4 or 5, and a new "About this fork"
section explains git-tag installs, the independent version numbers, and
that Bootstrap 3 and subclassing stay supported.
Co-Authored-By: Claude Opus 5.5
---
README.md | 16 +++++++++-
addon/components/bs-accordion.js | 4 +--
addon/components/bs-accordion/item.js | 2 --
addon/components/bs-accordion/item/title.js | 2 --
addon/components/bs-alert.js | 4 +--
addon/components/bs-button-group.js | 4 +--
addon/components/bs-button-group/button.js | 2 --
addon/components/bs-button.js | 4 +--
addon/components/bs-carousel.js | 4 +--
addon/components/bs-carousel/slide.js | 2 --
addon/components/bs-collapse.js | 4 +--
addon/components/bs-dropdown.js | 4 +--
addon/components/bs-dropdown/button.js | 4 +--
addon/components/bs-dropdown/menu.js | 2 --
addon/components/bs-dropdown/menu/divider.js | 2 --
addon/components/bs-dropdown/menu/item.js | 2 --
addon/components/bs-dropdown/toggle.js | 2 --
addon/components/bs-form.js | 4 +--
.../bs-form/element/control/checkbox.js | 2 --
.../bs-form/element/control/input.js | 2 --
.../bs-form/element/control/radio.js | 2 --
.../bs-form/element/control/switch.js | 2 --
.../bs-form/element/control/textarea.js | 2 --
addon/components/bs-form/element/errors.js | 2 --
.../bs-form/element/feedback-icon.js | 2 --
addon/components/bs-form/element/help-text.js | 2 --
addon/components/bs-form/element/label.js | 2 --
addon/components/bs-form/element/legend.js | 6 +---
addon/components/bs-modal.js | 4 +--
addon/components/bs-modal/dialog.js | 2 --
addon/components/bs-nav.js | 4 +--
addon/components/bs-nav/item.js | 2 --
addon/components/bs-navbar.js | 4 +--
addon/components/bs-navbar/content.js | 2 --
addon/components/bs-navbar/nav.js | 2 --
addon/components/bs-navbar/toggle.js | 2 --
addon/components/bs-popover.js | 4 +--
addon/components/bs-progress.js | 4 +--
addon/components/bs-progress/bar.js | 2 --
addon/components/bs-tab.js | 4 +--
addon/components/bs-tab/pane.js | 2 --
addon/components/bs-tooltip.js | 4 +--
addon/utils/deprecate-subclassing.js | 29 -------------------
index.js | 6 ----
.../components/subclassing-test.js | 21 +++++---------
45 files changed, 39 insertions(+), 151 deletions(-)
delete mode 100644 addon/utils/deprecate-subclassing.js
diff --git a/README.md b/README.md
index bb6de3fe0..9f803663c 100644
--- a/README.md
+++ b/README.md
@@ -5,12 +5,26 @@
[](http://emberobserver.com/addons/ember-bootstrap)
[](https://badge.fury.io/js/ember-bootstrap)
-An [ember-cli](http://www.ember-cli.com) addon for using [Bootstrap](http://getbootstrap.com/) 3 or 4 in Ember applications.
+An [ember-cli](http://www.ember-cli.com) addon for using [Bootstrap](http://getbootstrap.com/) 3, 4 or 5 in Ember applications.
The addon includes the Bootstrap CSS (or Sass, Less) in your project (can be disabled). On top of that, it provides a set of native Ember components (no use of Bootstrap JavaScript!).
*See [www.ember-bootstrap.com](http://www.ember-bootstrap.com/) for full documentation.*
+## About this fork
+
+This is SeeClickFix's fork of ember-bootstrap. It is installed from its git tags (for example
+`"ember-bootstrap": "SeeClickFix/ember-bootstrap#v5.0.0"`), not from npm, and its version numbers are
+independent of upstream's npm releases.
+
+This fork keeps supporting two things that upstream deprecated:
+
+* **Bootstrap 3.** Upstream deprecated it in 4.9.0 and removed it in 5.0.0. Here it stays supported
+ and tested, with no deprecation warning.
+* **Subclassing the component classes.** Upstream deprecated extending from ember-bootstrap's
+ components in 4.0.0 (and dropped that deprecation again in 6.2.0). Here subclassing is supported
+ and raises no deprecation.
+
## Installation
In your application's directory:
diff --git a/addon/components/bs-accordion.js b/addon/components/bs-accordion.js
index e5085ca5f..b9c5325d1 100644
--- a/addon/components/bs-accordion.js
+++ b/addon/components/bs-accordion.js
@@ -1,6 +1,5 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import { tracked } from '@glimmer/tracking';
/**
@@ -31,14 +30,13 @@ import { tracked } from '@glimmer/tracking';
In the example above the first accordion item utilizes the yielded `change` action to add some custom behaviour.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Accordion
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class Accordion extends Component {
/**
* The value of the currently selected accordion item. Set this to change selection programmatically.
diff --git a/addon/components/bs-accordion/item.js b/addon/components/bs-accordion/item.js
index 6956f71cf..acf83b957 100644
--- a/addon/components/bs-accordion/item.js
+++ b/addon/components/bs-accordion/item.js
@@ -2,7 +2,6 @@ import Component from '@glimmer/component';
import typeClass from 'ember-bootstrap/utils/cp/type-class';
import { getOwnConfig, macroCondition } from '@embroider/macros';
import { guidFor } from '@ember/object/internals';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import arg from '../../utils/decorators/arg';
/**
@@ -15,7 +14,6 @@ import arg from '../../utils/decorators/arg';
@extends Ember.Component
@public
*/
-@deprecateSubclassing
export default class AccordionItem extends Component {
/**
* The title of the accordion item, displayed as a .panel-title element
diff --git a/addon/components/bs-accordion/item/title.js b/addon/components/bs-accordion/item/title.js
index 922aefc2b..442a13b06 100644
--- a/addon/components/bs-accordion/item/title.js
+++ b/addon/components/bs-accordion/item/title.js
@@ -1,6 +1,5 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component for an accordion item title.
@@ -12,7 +11,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class AccordionItemTitle extends Component {
/**
* @property collapsed
diff --git a/addon/components/bs-alert.js b/addon/components/bs-alert.js
index 0c36c0a24..2adcbac2a 100644
--- a/addon/components/bs-alert.js
+++ b/addon/components/bs-alert.js
@@ -3,7 +3,6 @@ import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { later, schedule } from '@ember/runloop';
import usesTransition from 'ember-bootstrap/utils/decorators/uses-transition';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import arg from 'ember-bootstrap/utils/decorators/arg';
/**
@@ -36,14 +35,13 @@ import arg from 'ember-bootstrap/utils/decorators/arg';
The header is rendered using a `` element by default. You can customize
that one by setting `@headerTag` argument of ``.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Alert
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class Alert extends Component {
/**
* A dismissible alert will have a close button in the upper right corner, that the user can click to dismiss
diff --git a/addon/components/bs-button-group.js b/addon/components/bs-button-group.js
index 03c20c34c..45c015c39 100644
--- a/addon/components/bs-button-group.js
+++ b/addon/components/bs-button-group.js
@@ -1,7 +1,6 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { A, isArray } from '@ember/array';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Bootstrap-style button group, that visually groups buttons, and optionally adds radio/checkbox like behaviour.
@@ -54,14 +53,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
```
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class ButtonGroup
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class ButtonGroup extends Component {
/**
* @property buttonComponent
diff --git a/addon/components/bs-button-group/button.js b/addon/components/bs-button-group/button.js
index 39ba35104..c072aa3d5 100644
--- a/addon/components/bs-button-group/button.js
+++ b/addon/components/bs-button-group/button.js
@@ -10,8 +10,6 @@ import Button from 'ember-bootstrap/components/bs-button';
@private
*/
export default class ButtonGroupButton extends Button {
- '__ember-bootstrap_subclass' = true;
-
/**
* @property groupValue
* @private
diff --git a/addon/components/bs-button.js b/addon/components/bs-button.js
index 30fd12ba9..fb5181f98 100644
--- a/addon/components/bs-button.js
+++ b/addon/components/bs-button.js
@@ -3,7 +3,6 @@ import { action } from '@ember/object';
import { warn } from '@ember/debug';
import Component from '@glimmer/component';
import arg from 'ember-bootstrap/utils/decorators/arg';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import { DEBUG } from '@glimmer/env';
/**
@@ -91,14 +90,13 @@ import { DEBUG } from '@glimmer/env';
You can `reset` the state represented by these properties and used for button's text by setting `reset` property to
`true`.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Button
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class Button extends Component {
/**
* Default label of the button. Not need if used as a block component
diff --git a/addon/components/bs-carousel.js b/addon/components/bs-carousel.js
index d8423994c..798814738 100644
--- a/addon/components/bs-carousel.js
+++ b/addon/components/bs-carousel.js
@@ -10,7 +10,6 @@ import { task, timeout } from 'ember-concurrency';
import RSVP from 'rsvp';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { equal } from '@ember/object/computed';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Ember implementation of Bootstrap's Carousel. Supports all original features but API is partially different:
@@ -55,7 +54,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
| Wrap | wrap slides, cycles without stopping at first or last slide. |
```
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Carousel
@namespace Components
@@ -63,7 +62,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class Carousel extends Component.extend(ComponentParent) {
tabindex = '1';
diff --git a/addon/components/bs-carousel/slide.js b/addon/components/bs-carousel/slide.js
index 39181e279..ce16e8dc3 100644
--- a/addon/components/bs-carousel/slide.js
+++ b/addon/components/bs-carousel/slide.js
@@ -5,7 +5,6 @@ import ComponentChild from 'ember-bootstrap/mixins/component-child';
import { next } from '@ember/runloop';
import overrideableCP from 'ember-bootstrap/utils/cp/overrideable';
import { addObserver } from '@ember/object/observers';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import trackElement from 'ember-bootstrap/utils/track-element';
/**
@@ -19,7 +18,6 @@ import trackElement from 'ember-bootstrap/utils/track-element';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class CarouselSlide extends Component.extend(ComponentChild) {
/**
* @property _element
diff --git a/addon/components/bs-collapse.js b/addon/components/bs-collapse.js
index ae2baef48..a99b40f67 100644
--- a/addon/components/bs-collapse.js
+++ b/addon/components/bs-collapse.js
@@ -3,7 +3,6 @@ import Component from '@glimmer/component';
import { isNone } from '@ember/utils';
import { next } from '@ember/runloop';
import transitionEnd from 'ember-bootstrap/utils/transition-end';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import trackElement from 'ember-bootstrap/utils/track-element';
import arg from '../utils/decorators/arg';
import { tracked } from '@glimmer/tracking';
@@ -22,14 +21,13 @@ import { tracked } from '@glimmer/tracking';
```
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Collapse
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class Collapse extends Component {
/**
* @property _element
diff --git a/addon/components/bs-dropdown.js b/addon/components/bs-dropdown.js
index b1a0e47da..e5e86d162 100644
--- a/addon/components/bs-dropdown.js
+++ b/addon/components/bs-dropdown.js
@@ -3,7 +3,6 @@ import { action, computed } from '@ember/object';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { assert } from '@ember/debug';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
const ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
const SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
@@ -164,7 +163,7 @@ const SUPPORTED_KEYCODES = [ESCAPE_KEYCODE, ARROW_DOWN_KEYCODE, ARROW_UP_KEYCODE
version does. This also allows you to set `renderInPlace=false` on the menu component to render it in a wormhole,
which you might want to do if you experience clipping issues by an outer `overflow: hidden` element.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Dropdown
@namespace Components
@@ -172,7 +171,6 @@ const SUPPORTED_KEYCODES = [ESCAPE_KEYCODE, ARROW_DOWN_KEYCODE, ARROW_UP_KEYCODE
@public
s*/
@tagName('')
-@deprecateSubclassing
export default class Dropdown extends Component {
/**
* The tag name used for the dropdown element.
diff --git a/addon/components/bs-dropdown/button.js b/addon/components/bs-dropdown/button.js
index 46ceb2091..8f194f296 100644
--- a/addon/components/bs-dropdown/button.js
+++ b/addon/components/bs-dropdown/button.js
@@ -10,6 +10,4 @@ import Button from 'ember-bootstrap/components/bs-button';
@extends Components.Button
@public
*/
-export default class DropdownButton extends Button {
- '__ember-bootstrap_subclass' = true;
-}
+export default class DropdownButton extends Button {}
diff --git a/addon/components/bs-dropdown/menu.js b/addon/components/bs-dropdown/menu.js
index f3426fa81..884099513 100644
--- a/addon/components/bs-dropdown/menu.js
+++ b/addon/components/bs-dropdown/menu.js
@@ -4,7 +4,6 @@ import Component from '@ember/component';
import { next } from '@ember/runloop';
import { getDestinationElement } from 'ember-bootstrap/utils/dom';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import trackElement from 'ember-bootstrap/utils/track-element';
/**
@@ -18,7 +17,6 @@ import trackElement from 'ember-bootstrap/utils/track-element';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class DropdownMenu extends Component {
/**
* @property _element
diff --git a/addon/components/bs-dropdown/menu/divider.js b/addon/components/bs-dropdown/menu/divider.js
index ca4a3ed67..4a6e05be5 100644
--- a/addon/components/bs-dropdown/menu/divider.js
+++ b/addon/components/bs-dropdown/menu/divider.js
@@ -1,6 +1,5 @@
import Component from '@ember/component';
import { tagName } from '@ember-decorators/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component for a dropdown menu divider.
@@ -13,5 +12,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class DropdownMenuDivider extends Component {}
diff --git a/addon/components/bs-dropdown/menu/item.js b/addon/components/bs-dropdown/menu/item.js
index 67e41b0ef..cab2a895c 100644
--- a/addon/components/bs-dropdown/menu/item.js
+++ b/addon/components/bs-dropdown/menu/item.js
@@ -1,6 +1,5 @@
import Component from '@ember/component';
import { tagName } from '@ember-decorators/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component for a dropdown menu item.
@@ -13,5 +12,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class DropdownMenuItem extends Component {}
diff --git a/addon/components/bs-dropdown/toggle.js b/addon/components/bs-dropdown/toggle.js
index 03c82a484..e8a23ae49 100644
--- a/addon/components/bs-dropdown/toggle.js
+++ b/addon/components/bs-dropdown/toggle.js
@@ -2,7 +2,6 @@ import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { computed, action } from '@ember/object';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Anchor element that triggers the parent dropdown to open.
@@ -16,7 +15,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@publicø
*/
@tagName('')
-@deprecateSubclassing
export default class DropdownToggle extends Component {
/**
* @property inNav
diff --git a/addon/components/bs-form.js b/addon/components/bs-form.js
index b93fd6770..d71b8c7b8 100644
--- a/addon/components/bs-form.js
+++ b/addon/components/bs-form.js
@@ -9,7 +9,6 @@ import RSVP from 'rsvp';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { macroCondition, getOwnConfig } from '@embroider/macros';
import { DEBUG } from '@glimmer/env';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Render a form with the appropriate Bootstrap layout class (see `formLayout`).
@@ -120,7 +119,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
The submission state is reset as soon as any value of a form element changes. Additionally it can be reset programatically by
calling the yielded `resetSubmissionState` function.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Form
@namespace Components
@@ -128,7 +127,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class Form extends Component {
/**
* Bootstrap form class name (computed)
diff --git a/addon/components/bs-form/element/control/checkbox.js b/addon/components/bs-form/element/control/checkbox.js
index 086757ee8..2bbadc9ea 100644
--- a/addon/components/bs-form/element/control/checkbox.js
+++ b/addon/components/bs-form/element/control/checkbox.js
@@ -1,7 +1,6 @@
import { action } from '@ember/object';
import { tagName } from '@ember-decorators/component';
import Control from '../control';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementControlCheckbox extends Control {
@action
handleClick(event) {
diff --git a/addon/components/bs-form/element/control/input.js b/addon/components/bs-form/element/control/input.js
index cc50f597f..82e9365c6 100644
--- a/addon/components/bs-form/element/control/input.js
+++ b/addon/components/bs-form/element/control/input.js
@@ -3,7 +3,6 @@ import { action } from '@ember/object';
import Control from '../control';
import sizeClass from 'ember-bootstrap/utils/cp/size-class';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -13,7 +12,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementControlInput extends Control {
/**
* @property type
diff --git a/addon/components/bs-form/element/control/radio.js b/addon/components/bs-form/element/control/radio.js
index ffe686662..7f49c180d 100644
--- a/addon/components/bs-form/element/control/radio.js
+++ b/addon/components/bs-form/element/control/radio.js
@@ -1,7 +1,6 @@
import { tagName } from '@ember-decorators/component';
import Control from '../control';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementControlRadio extends Control {
/**
* @property inline
diff --git a/addon/components/bs-form/element/control/switch.js b/addon/components/bs-form/element/control/switch.js
index e9123f77e..ceb81f316 100644
--- a/addon/components/bs-form/element/control/switch.js
+++ b/addon/components/bs-form/element/control/switch.js
@@ -1,7 +1,6 @@
import { action } from '@ember/object';
import { tagName } from '@ember-decorators/component';
import Control from '../control';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementControlSwitch extends Control {
@action
handleClick(event) {
diff --git a/addon/components/bs-form/element/control/textarea.js b/addon/components/bs-form/element/control/textarea.js
index 2f72e1a9a..2b4b1f5fb 100644
--- a/addon/components/bs-form/element/control/textarea.js
+++ b/addon/components/bs-form/element/control/textarea.js
@@ -1,7 +1,6 @@
import { action } from '@ember/object';
import { tagName } from '@ember-decorators/component';
import Control from '../control';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementControlTextarea extends Control {
@action
handleChange(event) {
diff --git a/addon/components/bs-form/element/errors.js b/addon/components/bs-form/element/errors.js
index b1288223e..21c0d218e 100644
--- a/addon/components/bs-form/element/errors.js
+++ b/addon/components/bs-form/element/errors.js
@@ -1,7 +1,6 @@
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@class FormElementErrors
@@ -10,7 +9,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementErrors extends Component {
/**
* @property show
diff --git a/addon/components/bs-form/element/feedback-icon.js b/addon/components/bs-form/element/feedback-icon.js
index 401493679..381ea6bdb 100644
--- a/addon/components/bs-form/element/feedback-icon.js
+++ b/addon/components/bs-form/element/feedback-icon.js
@@ -1,7 +1,6 @@
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementFeedbackIcon extends Component {
/**
* @property show
diff --git a/addon/components/bs-form/element/help-text.js b/addon/components/bs-form/element/help-text.js
index 12a6a8b9d..efcc9cc2f 100644
--- a/addon/components/bs-form/element/help-text.js
+++ b/addon/components/bs-form/element/help-text.js
@@ -1,6 +1,5 @@
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -10,5 +9,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementHelpText extends Component {}
diff --git a/addon/components/bs-form/element/label.js b/addon/components/bs-form/element/label.js
index e9a9ff48d..5ed27f86f 100644
--- a/addon/components/bs-form/element/label.js
+++ b/addon/components/bs-form/element/label.js
@@ -4,7 +4,6 @@ import { equal } from '@ember/object/computed';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { isBlank } from '@ember/utils';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -14,7 +13,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@private
*/
@tagName('')
-@deprecateSubclassing
export default class FormElementLabel extends Component {
/**
* @property label
diff --git a/addon/components/bs-form/element/legend.js b/addon/components/bs-form/element/legend.js
index 52c038654..25cc7d2fa 100644
--- a/addon/components/bs-form/element/legend.js
+++ b/addon/components/bs-form/element/legend.js
@@ -1,9 +1,5 @@
import { tagName } from '@ember-decorators/component';
import FormElementLabel from 'ember-bootstrap/components/bs-form/element/label';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@tagName('')
-@deprecateSubclassing
-export default class FormElementLegend extends FormElementLabel {
- '__ember-bootstrap_subclass' = true;
-}
+export default class FormElementLegend extends FormElementLabel {}
diff --git a/addon/components/bs-modal.js b/addon/components/bs-modal.js
index 7d8b8fb2a..760738910 100644
--- a/addon/components/bs-modal.js
+++ b/addon/components/bs-modal.js
@@ -7,7 +7,6 @@ import transitionEnd from 'ember-bootstrap/utils/transition-end';
import { getDestinationElement } from 'ember-bootstrap/utils/dom';
import usesTransition from 'ember-bootstrap/utils/decorators/uses-transition';
import isFastBoot from 'ember-bootstrap/utils/is-fastboot';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import arg from '../utils/decorators/arg';
import { tracked } from '@glimmer/tracking';
import trackElement from 'ember-bootstrap/utils/track-element';
@@ -55,14 +54,13 @@ function afterRender() {
See the documentation of the [bs-modal-simple](Components.ModalSimple.html) component for further examples.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Modal
@namespace Components
@extends Glimmer.Component
@public
*/
-@deprecateSubclassing
export default class Modal extends Component {
@service('-document')
document;
diff --git a/addon/components/bs-modal/dialog.js b/addon/components/bs-modal/dialog.js
index 049e3615c..09683397b 100644
--- a/addon/components/bs-modal/dialog.js
+++ b/addon/components/bs-modal/dialog.js
@@ -2,7 +2,6 @@ import { action } from '@ember/object';
import { isBlank } from '@ember/utils';
import Component from '@glimmer/component';
import { next } from '@ember/runloop';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import trackElement from 'ember-bootstrap/utils/track-element';
import { tracked } from '@glimmer/tracking';
@@ -14,7 +13,6 @@ import { tracked } from '@glimmer/tracking';
@extends Glimmer.Component
@private
*/
-@deprecateSubclassing
export default class ModalDialog extends Component {
/**
* @property id
diff --git a/addon/components/bs-nav.js b/addon/components/bs-nav.js
index 1f2e4c369..189e9e361 100644
--- a/addon/components/bs-nav.js
+++ b/addon/components/bs-nav.js
@@ -2,7 +2,6 @@ import { tagName } from '@ember-decorators/component';
import { computed } from '@ember/object';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component to generate [bootstrap navs](http://getbootstrap.com/components/#nav)
@@ -75,7 +74,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
The `fill` styling is only available with Bootstrap 4
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Nav
@namespace Components
@@ -84,7 +83,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
*/
@tagName('')
-@deprecateSubclassing
export default class Nav extends Component {
@computed('type')
get typeClass() {
diff --git a/addon/components/bs-nav/item.js b/addon/components/bs-nav/item.js
index 0f273f4b2..188fa9d4d 100644
--- a/addon/components/bs-nav/item.js
+++ b/addon/components/bs-nav/item.js
@@ -8,7 +8,6 @@ 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';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -21,7 +20,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class NavItem extends Component.extend(ComponentParent) {
/**
* Render the nav item as disabled (see [Bootstrap docs](http://getbootstrap.com/components/#nav-disabled-links)).
diff --git a/addon/components/bs-navbar.js b/addon/components/bs-navbar.js
index b7fd83a5f..a8573aa30 100644
--- a/addon/components/bs-navbar.js
+++ b/addon/components/bs-navbar.js
@@ -7,7 +7,6 @@ import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { assert } from '@ember/debug';
import { macroCondition, getOwnConfig } from '@embroider/macros';
import { isBlank } from '@ember/utils';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component to generate [Bootstrap navbars](http://getbootstrap.com/components/#navbar).
@@ -96,7 +95,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
Bootstrap 4 navbars are fluid by default without the need for an additional container. An
additional container is added like with Bootstrap 3 if `fluid` is `false`.
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Navbar
@namespace Components
@@ -104,7 +103,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class Navbar extends Component {
/**
* Manages the state for the responsive menu between the toggle and the content.
diff --git a/addon/components/bs-navbar/content.js b/addon/components/bs-navbar/content.js
index e6f3c3228..7a81f0dff 100644
--- a/addon/components/bs-navbar/content.js
+++ b/addon/components/bs-navbar/content.js
@@ -1,6 +1,5 @@
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
* Component to wrap the collapsible content of a [Components.Navbar](Components.Navbar.html) component.
@@ -12,5 +11,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
* @public
*/
@tagName('')
-@deprecateSubclassing
export default class NavbarContent extends Component {}
diff --git a/addon/components/bs-navbar/nav.js b/addon/components/bs-navbar/nav.js
index 379833b16..14ead4ce7 100644
--- a/addon/components/bs-navbar/nav.js
+++ b/addon/components/bs-navbar/nav.js
@@ -14,8 +14,6 @@ import defaultValue from 'ember-bootstrap/utils/default-decorator';
* @public
*/
export default class NavbarNav extends BsNavComponent {
- '__ember-bootstrap_subclass' = true;
-
@defaultValue
justified = false;
diff --git a/addon/components/bs-navbar/toggle.js b/addon/components/bs-navbar/toggle.js
index 6d6e38612..65847c474 100644
--- a/addon/components/bs-navbar/toggle.js
+++ b/addon/components/bs-navbar/toggle.js
@@ -2,7 +2,6 @@ import { action } from '@ember/object';
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
* Component to implement the responsive menu toggle behavior in a [Components.Navbar](Components.Navbar.html)
@@ -19,7 +18,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
* @public
*/
@tagName('')
-@deprecateSubclassing
export default class NavbarToggle extends Component {
@defaultValue
collapsed = true;
diff --git a/addon/components/bs-popover.js b/addon/components/bs-popover.js
index 4de4345b1..6aa618b47 100644
--- a/addon/components/bs-popover.js
+++ b/addon/components/bs-popover.js
@@ -1,6 +1,5 @@
import ContextualHelp from './bs-contextual-help';
import arg from '../utils/decorators/arg';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component that implements Bootstrap [popovers](http://getbootstrap.com/javascript/#popovers).
@@ -62,14 +61,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
* `onHide`
* `onHidden`
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Popover
@namespace Components
@extends Components.ContextualHelp
@public
*/
-@deprecateSubclassing
export default class Popover extends ContextualHelp {
/**
* @property placement
diff --git a/addon/components/bs-progress.js b/addon/components/bs-progress.js
index c2f472225..f6f27e014 100644
--- a/addon/components/bs-progress.js
+++ b/addon/components/bs-progress.js
@@ -1,6 +1,5 @@
import { tagName } from '@ember-decorators/component';
import Component from '@ember/component';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component to display a Bootstrap progress bar, see http://getbootstrap.com/components/#progress.
@@ -30,7 +29,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
```
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Progress
@namespace Components
@@ -38,7 +37,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class Progress extends Component {
/**
* @property progressBarComponent
diff --git a/addon/components/bs-progress/bar.js b/addon/components/bs-progress/bar.js
index a4f1cc48f..a39a0300c 100644
--- a/addon/components/bs-progress/bar.js
+++ b/addon/components/bs-progress/bar.js
@@ -4,7 +4,6 @@ import Component from '@ember/component';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import typeClass from 'ember-bootstrap/utils/cp/type-class';
import { macroCondition, getOwnConfig } from '@embroider/macros';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
@@ -16,7 +15,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class ProgressBar extends Component {
/**
* The lower limit of the value range
diff --git a/addon/components/bs-tab.js b/addon/components/bs-tab.js
index 205ac6c9e..42981f673 100644
--- a/addon/components/bs-tab.js
+++ b/addon/components/bs-tab.js
@@ -8,7 +8,6 @@ import ComponentParent from 'ember-bootstrap/mixins/component-parent';
import TabPane from 'ember-bootstrap/components/bs-tab/pane';
import listenTo from 'ember-bootstrap/utils/cp/listen-to';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Tab component for dynamic tab functionality that mimics the behaviour of Bootstrap's tab.js plugin,
@@ -106,7 +105,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
```
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Tab
@namespace Components
@@ -115,7 +114,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class Tab extends Component.extend(ComponentParent) {
/**
* Type of nav, either "pills" or "tabs"
diff --git a/addon/components/bs-tab/pane.js b/addon/components/bs-tab/pane.js
index 42cb4ea5b..4462eb971 100644
--- a/addon/components/bs-tab/pane.js
+++ b/addon/components/bs-tab/pane.js
@@ -8,7 +8,6 @@ import transitionEnd from 'ember-bootstrap/utils/transition-end';
import usesTransition from 'ember-bootstrap/utils/cp/uses-transition';
import defaultValue from 'ember-bootstrap/utils/default-decorator';
import { guidFor } from '@ember/object/internals';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import trackElement from 'ember-bootstrap/utils/track-element';
/**
@@ -22,7 +21,6 @@ import trackElement from 'ember-bootstrap/utils/track-element';
@public
*/
@tagName('')
-@deprecateSubclassing
export default class TabPane extends Component.extend(ComponentChild) {
/**
* @property id
diff --git a/addon/components/bs-tooltip.js b/addon/components/bs-tooltip.js
index e01986736..23c298dcf 100644
--- a/addon/components/bs-tooltip.js
+++ b/addon/components/bs-tooltip.js
@@ -1,5 +1,4 @@
import ContextualHelp from './bs-contextual-help';
-import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
/**
Component that implements Bootstrap [tooltips](http://getbootstrap.com/javascript/#tooltips).
@@ -71,14 +70,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
* `onHide`
* `onHidden`
- *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.*
+ *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.*
@class Tooltip
@namespace Components
@extends Components.ContextualHelp
@public
*/
-@deprecateSubclassing
export default class Tooltip extends ContextualHelp {
/**
* @property elementComponent
diff --git a/addon/utils/deprecate-subclassing.js b/addon/utils/deprecate-subclassing.js
deleted file mode 100644
index f4d193188..000000000
--- a/addon/utils/deprecate-subclassing.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { DEBUG } from '@glimmer/env';
-import { deprecate } from '@ember/debug';
-import { next } from '@ember/runloop';
-
-export default function deprecateSubclassing(target) {
- if (DEBUG) {
- const wrapperClass = class extends target {
- constructor() {
- super(...arguments);
- // we need to delay the deprecation check, as the __ember-bootstrap_subclass class field will only be set *after* the constructor
- next(() => {
- deprecate(
- `Extending from ember-bootstrap component classes is not supported, and might break anytime. Detected subclassing of component.`,
- // the `__ember-bootstrap_subclass` flag is an escape hatch for "privileged" addons like validations addons that currently still have to rely on subclassing
- wrapperClass === this.constructor || this['__ember-bootstrap_subclass'] === true,
- {
- id: `ember-bootstrap.subclassing#${target.name}`,
- until: '5.0.0',
- since: '4.0.0',
- for: 'ember-bootstrap',
- }
- );
- });
- }
- };
-
- return wrapperClass;
- }
-}
diff --git a/index.js b/index.js
index 44beda48f..fea10ce32 100644
--- a/index.js
+++ b/index.js
@@ -57,12 +57,6 @@ module.exports = {
let options = Object.assign({}, defaultOptions, app.options['ember-bootstrap']);
- if (options.bootstrapVersion === 3) {
- this.warn(
- 'Support for Bootstrap 3 has been deprecated and will be removed in ember-bootstrap v5! Consider migrating to Bootstrap v4 or v5!'
- );
- }
-
if (options.bootstrapVersion >= 4 && options.importBootstrapFont) {
this.warn(
'Inclusion of the Glyphicon font is only supported for Bootstrap 3. ' +
diff --git a/tests/integration/components/subclassing-test.js b/tests/integration/components/subclassing-test.js
index bed3c2c13..18a9e0bc9 100644
--- a/tests/integration/components/subclassing-test.js
+++ b/tests/integration/components/subclassing-test.js
@@ -89,27 +89,20 @@ module('Integration | subclassing', function (hooks) {
tests.forEach(({ name, clazz }) => {
module(name, function () {
- test('it should not be subclassed', async function (assert) {
- class MyClass extends clazz {}
-
- this.owner.register('component:test-component', MyClass);
-
- await render(hbs``);
-
- assert.deprecationsInclude(
- `Extending from ember-bootstrap component classes is not supported, and might break anytime. Detected subclassing of <${name}> component.`
- );
- });
-
- test('subclass warning can be silenced', async function (assert) {
+ test('it can be subclassed without deprecations', async function (assert) {
+ let constructed = false;
class MyClass extends clazz {
- '__ember-bootstrap_subclass' = true;
+ constructor() {
+ super(...arguments);
+ constructed = true;
+ }
}
this.owner.register('component:test-component', MyClass);
await render(hbs``);
+ assert.true(constructed, 'the subclass is instantiated');
assert.deprecations(0);
});
});