FIX: Deprecate NumberField, use <input> instead (#25434)
* Revert "FEATURE: Use native number fields for integer inputs (#24984)"
This reverts commit 8fce890ead
.
* FIX: Deprecate NumberField, use <input> instead
This reverts #24984 as it introduced regressions (behavioral and visual) and instead it deprecates the NumberField component and replaces its uses in core with native `<input>` elements.
This commit is contained in:
parent
19b86e7ea2
commit
f2e1363f67
|
@ -1,8 +1,9 @@
|
|||
<NumberField
|
||||
@value={{this.value}}
|
||||
@classNames="input-setting-integer"
|
||||
@min={{if this.setting.min this.setting.min null}}
|
||||
@max={{if this.setting.max this.setting.max null}}
|
||||
<input
|
||||
{{on "input" (action (mut this.value) value="target.value")}}
|
||||
value={{this.value}}
|
||||
min={{if this.setting.min this.setting.min null}}
|
||||
max={{if this.setting.max this.setting.max null}}
|
||||
class="input-setting-integer"
|
||||
/>
|
||||
|
||||
<SettingValidationMessage @message={{this.validationMessage}} />
|
||||
|
|
|
@ -4,10 +4,15 @@
|
|||
<label for="category-position">
|
||||
{{i18n "category.position"}}
|
||||
</label>
|
||||
<NumberField
|
||||
@value={{this.category.position}}
|
||||
@id="category-position"
|
||||
@min="0"
|
||||
<input
|
||||
{{on
|
||||
"input"
|
||||
(action (mut this.category.position) value="target.value")
|
||||
}}
|
||||
value={{this.category.position}}
|
||||
type="number"
|
||||
min="0"
|
||||
id="category-position"
|
||||
class="position-input"
|
||||
/>
|
||||
</section>
|
||||
|
@ -34,10 +39,15 @@
|
|||
{{i18n "category.num_featured_topics"}}
|
||||
{{/if}}
|
||||
</label>
|
||||
<NumberField
|
||||
@value={{this.category.num_featured_topics}}
|
||||
@id="category-number-featured-topics"
|
||||
@min="1"
|
||||
<input
|
||||
{{on
|
||||
"input"
|
||||
(action (mut this.category.num_featured_topics) value="target.value")
|
||||
}}
|
||||
value={{this.category.num_featured_topics}}
|
||||
type="number"
|
||||
min="1"
|
||||
id="category-number-featured-topics"
|
||||
/>
|
||||
</section>
|
||||
|
||||
|
@ -184,10 +194,18 @@
|
|||
<label for="category-number-daily-bump">
|
||||
{{i18n "category.num_auto_bump_daily"}}
|
||||
</label>
|
||||
<NumberField
|
||||
@value={{this.category.category_setting.num_auto_bump_daily}}
|
||||
@id="category-number-daily-bump"
|
||||
@min="0"
|
||||
<input
|
||||
{{on
|
||||
"input"
|
||||
(action
|
||||
(mut this.category.category_setting.num_auto_bump_daily)
|
||||
value="target.value"
|
||||
)
|
||||
}}
|
||||
value={{this.category.category_setting.num_auto_bump_daily}}
|
||||
type="number"
|
||||
min="0"
|
||||
id="category-number-daily-bump"
|
||||
/>
|
||||
</section>
|
||||
|
||||
|
@ -195,10 +213,18 @@
|
|||
<label for="category-auto-bump-cooldown-days">
|
||||
{{i18n "category.auto_bump_cooldown_days"}}
|
||||
</label>
|
||||
<NumberField
|
||||
@value={{this.category.category_setting.auto_bump_cooldown_days}}
|
||||
@id="category-auto-bump-cooldown-days"
|
||||
@min="0"
|
||||
<input
|
||||
{{on
|
||||
"input"
|
||||
(action
|
||||
(mut this.category.category_setting.auto_bump_cooldown_days)
|
||||
value="target.value"
|
||||
)
|
||||
}}
|
||||
value={{this.category.category_setting.auto_bump_cooldown_days}}
|
||||
type="number"
|
||||
min="0"
|
||||
id="category-auto-bump-cooldown-days"
|
||||
/>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -20,10 +20,14 @@
|
|||
|
||||
<td>
|
||||
<div class="reorder-categories-actions">
|
||||
<NumberField
|
||||
@value={{readonly category.position}}
|
||||
@change={{fn this.change category}}
|
||||
@min="0"
|
||||
<input
|
||||
{{on
|
||||
"input"
|
||||
(action (fn this.change category) value="target.value")
|
||||
}}
|
||||
value={{category.position}}
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
<DButton
|
||||
@action={{fn this.move category -1}}
|
||||
|
|
|
@ -134,12 +134,13 @@ export default class ReorderCategories extends Component {
|
|||
}
|
||||
|
||||
@action
|
||||
change(category, event) {
|
||||
let newPosition = parseFloat(event.target.value);
|
||||
change(category, newPosition) {
|
||||
newPosition = parseInt(newPosition, 10);
|
||||
newPosition =
|
||||
newPosition < category.get("position")
|
||||
? Math.ceil(newPosition)
|
||||
: Math.floor(newPosition);
|
||||
|
||||
const direction = newPosition - category.get("position");
|
||||
this.move(category, direction);
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<Input
|
||||
id={{@id}}
|
||||
class={{@classNames}}
|
||||
min={{@min}}
|
||||
max={{@max}}
|
||||
@type="number"
|
||||
@value={{@value}}
|
||||
/>
|
|
@ -0,0 +1,62 @@
|
|||
import TextField from "discourse/components/text-field";
|
||||
import { allowOnlyNumericInput } from "discourse/lib/utilities";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export default TextField.extend({
|
||||
classNameBindings: ["invalid"],
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
deprecated(
|
||||
`NumberField component is deprecated. Use native <input> elements instead.\ne.g. <input {{on "input" (action (mut this.value) value="target.value")}} type="number" value={{this.value}} />`,
|
||||
{
|
||||
id: "discourse.number-field",
|
||||
since: "3.2.0.beta5",
|
||||
dropFrom: "3.3.0",
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
keyDown: function (event) {
|
||||
allowOnlyNumericInput(event, this._minNumber && this._minNumber < 0);
|
||||
},
|
||||
|
||||
get _minNumber() {
|
||||
if (!this.get("min")) {
|
||||
return;
|
||||
}
|
||||
return parseInt(this.get("min"), 10);
|
||||
},
|
||||
|
||||
get _maxNumber() {
|
||||
if (!this.get("max")) {
|
||||
return;
|
||||
}
|
||||
return parseInt(this.get("max"), 10);
|
||||
},
|
||||
|
||||
@discourseComputed("number")
|
||||
value: {
|
||||
get(number) {
|
||||
return parseInt(number, 10);
|
||||
},
|
||||
set(value) {
|
||||
const num = parseInt(value, 10);
|
||||
if (isNaN(num)) {
|
||||
this.set("invalid", true);
|
||||
return value;
|
||||
} else {
|
||||
this.set("invalid", false);
|
||||
this.set("number", num);
|
||||
return num.toString();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@discourseComputed("placeholderKey")
|
||||
placeholder(key) {
|
||||
return key ? I18n.t(key) : "";
|
||||
},
|
||||
});
|
|
@ -2,6 +2,7 @@ import { fillIn, render, triggerKeyEvent } from "@ember/test-helpers";
|
|||
import { hbs } from "ember-cli-htmlbars";
|
||||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import { withSilencedDeprecationsAsync } from "discourse-common/lib/deprecated";
|
||||
|
||||
module("Integration | Component | number-field", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
@ -9,9 +10,11 @@ module("Integration | Component | number-field", function (hooks) {
|
|||
test("number field", async function (assert) {
|
||||
this.set("value", 123);
|
||||
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" />
|
||||
`);
|
||||
await withSilencedDeprecationsAsync("discourse.number-field", async () => {
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" />
|
||||
`);
|
||||
});
|
||||
|
||||
await fillIn(".number-field-test", "33");
|
||||
|
||||
|
@ -34,9 +37,11 @@ module("Integration | Component | number-field", function (hooks) {
|
|||
test("number field | min value", async function (assert) {
|
||||
this.set("value", "");
|
||||
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" @min="1" />
|
||||
`);
|
||||
await withSilencedDeprecationsAsync("discourse.number-field", async () => {
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" @min="1" />
|
||||
`);
|
||||
});
|
||||
|
||||
await triggerKeyEvent(".number-field-test", "keydown", 189); // -
|
||||
await triggerKeyEvent(".number-field-test", "keydown", 49); // 1
|
||||
|
@ -47,9 +52,11 @@ module("Integration | Component | number-field", function (hooks) {
|
|||
"value is cleared when the input is less than the min"
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" @min="-10" />
|
||||
`);
|
||||
await withSilencedDeprecationsAsync("discourse.number-field", async () => {
|
||||
await render(hbs`
|
||||
<NumberField @value={{this.value}} @classNames="number-field-test" @min="-10" />
|
||||
`);
|
||||
});
|
||||
|
||||
await fillIn(".number-field-test", "-1");
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ module("Unit | Component | reorder-categories", function (hooks) {
|
|||
site.set("categories", [elem1, elem2, elem3]);
|
||||
|
||||
// Move category 'foo' from position 0 to position 2
|
||||
component.change(elem1, { target: { value: "2" } });
|
||||
component.change(elem1, "2");
|
||||
|
||||
assert.deepEqual(component.categoriesOrdered.mapBy("slug"), [
|
||||
"bar",
|
||||
|
@ -137,7 +137,7 @@ module("Unit | Component | reorder-categories", function (hooks) {
|
|||
const site = getOwner(this).lookup("service:site");
|
||||
site.set("categories", [elem1, child1, elem2, elem3]);
|
||||
|
||||
component.change(elem1, { target: { value: 3 } });
|
||||
component.change(elem1, "3");
|
||||
|
||||
assert.deepEqual(component.categoriesOrdered.mapBy("slug"), [
|
||||
"bar",
|
||||
|
|
Loading…
Reference in New Issue