Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@spectrum-web-components/number-field

Package Overview
Dependencies
Maintainers
6
Versions
219
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@spectrum-web-components/number-field - npm Package Compare versions

Comparing version 0.1.3-alpha.1 to 0.1.3

test/benchmark/basic-test.d.ts

18

custom-elements.json

@@ -10,3 +10,3 @@ {

"name": "format-options",
"description": "An `<sp-number-field>` element will process its numeric value with\n`new Intl.NumberFormat(navigator.language, this.formatOptions).format(this.valueAsNumber)`\nin order to prepare it for visual delivery in the input. In order to customize this\nprocessing supply your own `Intl.NumberFormatOptions` object here.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat",
"description": "An `<sp-number-field>` element will process its numeric value with\n`new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.valueAsNumber)`\nin order to prepare it for visual delivery in the input. In order to customize this\nprocessing supply your own `Intl.NumberFormatOptions` object here.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat",
"type": "NumberFormatOptions",

@@ -40,2 +40,7 @@ "default": "{}"

{
"name": "step-modifier",
"type": "number",
"default": "10"
},
{
"name": "allowed-keys",

@@ -128,3 +133,3 @@ "type": "string",

"attribute": "format-options",
"description": "An `<sp-number-field>` element will process its numeric value with\n`new Intl.NumberFormat(navigator.language, this.formatOptions).format(this.valueAsNumber)`\nin order to prepare it for visual delivery in the input. In order to customize this\nprocessing supply your own `Intl.NumberFormatOptions` object here.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat",
"description": "An `<sp-number-field>` element will process its numeric value with\n`new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.valueAsNumber)`\nin order to prepare it for visual delivery in the input. In order to customize this\nprocessing supply your own `Intl.NumberFormatOptions` object here.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat",
"type": "NumberFormatOptions",

@@ -163,2 +168,8 @@ "default": "{}"

{
"name": "stepModifier",
"attribute": "step-modifier",
"type": "number",
"default": "10"
},
{
"name": "valueAsString",

@@ -283,2 +294,5 @@ "description": "Retreive the value of the element parsed to a Number.",

"name": "input"
},
{
"name": "sp-language-context"
}

@@ -285,0 +299,0 @@ ]

16

package.json
{
"name": "@spectrum-web-components/number-field",
"version": "0.1.3-alpha.1+23ae605e",
"version": "0.1.3",
"publishConfig": {

@@ -48,11 +48,11 @@ "access": "public"

"@internationalized/number": "^3.0.0",
"@spectrum-web-components/action-button": "^0.5.3-alpha.1+23ae605e",
"@spectrum-web-components/base": "^0.4.5-alpha.1+23ae605e",
"@spectrum-web-components/icon": "^0.9.8-alpha.1+23ae605e",
"@spectrum-web-components/icons-ui": "^0.6.8-alpha.1+23ae605e",
"@spectrum-web-components/textfield": "^0.8.10-alpha.1+23ae605e",
"@spectrum-web-components/action-button": "^0.5.3",
"@spectrum-web-components/base": "^0.4.4",
"@spectrum-web-components/icon": "^0.9.7",
"@spectrum-web-components/icons-ui": "^0.6.7",
"@spectrum-web-components/textfield": "^0.8.10",
"tslib": "^2.0.0"
},
"devDependencies": {
"@formatjs/intl-numberformat": "^7.1.0",
"@formatjs/intl-numberformat": "^7.1.4",
"@spectrum-css/stepper": "^3.0.3"

@@ -65,3 +65,3 @@ },

],
"gitHead": "23ae605e3718dd3f86bc3aa5b10229a4eb7f83c9"
"gitHead": "ed13341debd82f86abc062f647d42458c77633cc"
}
## Description
`<sp-number-field>`s are used for numeric inputs. Upon interaction, the input value incrementally increases or decreases.
`<sp-number-field>` elements are used for numeric inputs. Upon interaction via the <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> keys, the scroll wheel, or the stepper UI, when not hidden by the `hide-stepper` attribute, the input value incrementally increases or decreases by the value of the `step` attribute. The <kbd>shift</kbd> key can be used to apply steps at 10 time (or the value of the `step-modifier` attribute times) their normal rate.

@@ -35,4 +35,6 @@ ### Usage

An `<sp-number-field>` element will process its numeric value with `new Intl.NumberFormat(navigator.language, this.formatOptions).format(this.value)` in order to prepare it for visual delivery in the input. In order to customize this processing supply your own `Intl.NumberFormatOptions` via the `formatOptions` property, or `format-options` attribute as follows.
An `<sp-number-field>` element will process its numeric value with `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.value)` in order to prepare it for visual delivery in the input. In order to customize this processing supply your own `Intl.NumberFormatOptions` via the `formatOptions` property, or `format-options` attribute as seen below.
`this.resolvedLanguage` represents the language in which the `<sp-number-field>` element is currently being delivered. By default, this value will represent the language established by the `lang` attribute on the root `<html>` element while falling back to `navigator.language` when that is not present. This value can be customized via a language context provided by a parent element that listens for the `sp-language-context` event and supplies update language settings to the `callback` function contained therein. Applications leveraging the [`<sp-theme>`](./components/theme) element to manage the visual delivery or text direction of their content will be also be provided a reactive context for supplying language information to its descendants.
### Decimals

@@ -39,0 +41,0 @@

@@ -1,2 +0,2 @@

declare const styles: import("@spectrum-web-components/base").CSSResultGroup;
declare const styles: import("@spectrum-web-components/base").CSSResult;
export default styles;
import { CSSResultArray, TemplateResult, PropertyValues } from '@spectrum-web-components/base';
import { NumberFormatter, NumberParser } from '@internationalized/number';
import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron75.js';

@@ -15,3 +16,3 @@ import '@spectrum-web-components/action-button/sp-action-button.js';

* An `<sp-number-field>` element will process its numeric value with
* `new Intl.NumberFormat(navigator.language, this.formatOptions).format(this.valueAsNumber)`
* `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.valueAsNumber)`
* in order to prepare it for visual delivery in the input. In order to customize this

@@ -30,2 +31,3 @@ * processing supply your own `Intl.NumberFormatOptions` object here.

min?: number;
private resolvedLanguage;
/**

@@ -38,2 +40,3 @@ * The distance by which to alter the value of the element when taking a "step".

step?: number;
stepModifier: number;
set value(value: number);

@@ -74,5 +77,14 @@ get value(): number;

protected get displayValue(): string;
protected clearNumberFormatterCache(): void;
protected get numberFormatter(): NumberFormatter;
private _numberFormatter?;
protected get numberParser(): NumberParser;
private _numberParser?;
protected render(): TemplateResult;
protected update(changes: PropertyValues): void;
protected firstUpdated(changes: PropertyValues): void;
protected updated(changes: PropertyValues<this>): void;
connectedCallback(): void;
disconnectedCallback(): void;
private resolveLanguage;
}

@@ -49,3 +49,3 @@ /*

* An `<sp-number-field>` element will process its numeric value with
* `new Intl.NumberFormat(navigator.language, this.formatOptions).format(this.valueAsNumber)`
* `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.valueAsNumber)`
* in order to prepare it for visual delivery in the input. In order to customize this

@@ -62,2 +62,4 @@ * processing supply your own `Intl.NumberFormatOptions` object here.

this.keyboardFocused = false;
this.resolvedLanguage = document.documentElement.lang || navigator.language;
this.stepModifier = 10;
this._value = NaN;

@@ -87,3 +89,3 @@ this.changeCount = 0;

set valueAsString(value) {
this.value = new NumberParser(navigator.language, this.formatOptions).parse(value);
this.value = this.numberParser.parse(value);
}

@@ -93,6 +95,6 @@ get formattedValue() {

return '';
return new NumberFormatter(navigator.language, this.formatOptions).format(this.value);
return this.numberFormatter.format(this.value);
}
convertValueToNumber(value) {
return new NumberParser(navigator.language, this.formatOptions).parse(value);
return this.numberParser.parse(value);
}

@@ -122,3 +124,3 @@ get _step() {

event.clientY <= stepUpRect.y + stepUpRect.height) {
this.change = () => this.increment();
this.change = (event) => this.increment(event.shiftKey ? this.stepModifier : 1);
}

@@ -129,17 +131,17 @@ else if (event.clientX >= stepDownRect.x &&

event.clientY <= stepDownRect.y + stepDownRect.height) {
this.change = () => this.decrement();
this.change = (event) => this.decrement(event.shiftKey ? this.stepModifier : 1);
}
};
this.findChange(event);
this.startChange();
this.startChange(event);
}
startChange() {
startChange(event) {
this.changeCount = 0;
this.doChange();
this.doChange(event);
this.safty = setTimeout(() => {
this.doNextChange();
this.doNextChange(event);
}, 400);
}
doChange() {
this.change();
doChange(event) {
this.change(event);
}

@@ -155,9 +157,9 @@ handlePointermove(event) {

}
doNextChange() {
doNextChange(event) {
this.changeCount += 1;
if (this.changeCount % FRAMES_PER_CHANGE === 0) {
this.doChange();
this.doChange(event);
}
return requestAnimationFrame(() => {
this.nextChange = this.doNextChange();
this.nextChange = this.doNextChange(event);
});

@@ -178,17 +180,13 @@ }

}
increment() {
this.stepBy(1);
increment(factor = 1) {
this.stepBy(1 * factor);
}
decrement() {
this.stepBy(-1);
decrement(factor = 1) {
this.stepBy(-1 * factor);
}
handleKeydown(event) {
if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
// Don't do work when modifiers are present.
return;
}
switch (event.code) {
case 'ArrowUp':
event.preventDefault();
this.increment();
this.increment(event.shiftKey ? this.stepModifier : 1);
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));

@@ -198,3 +196,3 @@ break;

event.preventDefault();
this.decrement();
this.decrement(event.shiftKey ? this.stepModifier : 1);
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));

@@ -206,3 +204,8 @@ break;

event.preventDefault();
this.stepBy(event.deltaY);
const direction = event.shiftKey
? event.deltaX / Math.abs(event.deltaX)
: event.deltaY / Math.abs(event.deltaY);
if (direction !== 0 && !isNaN(direction)) {
this.stepBy(direction * (event.shiftKey ? this.stepModifier : 1));
}
}

@@ -260,10 +263,3 @@ onFocus() {

if (typeof this.max !== 'undefined') {
if (typeof this.step !== 'undefined') {
while (value > this.max) {
value -= this.step;
}
}
else {
value = Math.min(this.max, value);
}
value = Math.min(this.max, value);
}

@@ -275,2 +271,18 @@ return value;

}
clearNumberFormatterCache() {
this._numberFormatter = undefined;
this._numberParser = undefined;
}
get numberFormatter() {
if (!this._numberFormatter) {
this._numberFormatter = new NumberFormatter(this.resolvedLanguage, this.formatOptions);
}
return this._numberFormatter;
}
get numberParser() {
if (!this._numberParser) {
this._numberParser = new NumberParser(this.resolvedLanguage, this.formatOptions);
}
return this._numberParser;
}
render() {

@@ -287,18 +299,17 @@ this.autocomplete = 'off';

@focusout=${this.handleFocusout}
${streamingListener({
start: ['pointerdown', this.handlePointerdown],
streamInside: [
[
'pointermove',
'pointerenter',
'pointerleave',
'pointerover',
'pointerout',
],
this.handlePointermove,
@manage=${streamingListener({
type: 'pointerdown',
fn: this.handlePointerdown,
}, {
type: [
'pointermove',
'pointerenter',
'pointerleave',
'pointerover',
'pointerout',
],
end: [
['pointerup', 'pointercancel'],
this.handlePointerup,
],
fn: this.handlePointermove,
}, {
type: ['pointerup', 'pointercancel'],
fn: this.handlePointerup,
})}

@@ -340,2 +351,8 @@ >

}
update(changes) {
if (changes.has('formatOptions') || changes.has('resolvedLanguage')) {
this.clearNumberFormatterCache();
}
super.update(changes);
}
firstUpdated(changes) {

@@ -351,3 +368,3 @@ super.firstUpdated(changes);

changes.has('min')) {
const value = new NumberParser(navigator.language, this.formatOptions).parse(this.inputElement.value);
const value = this.numberParser.parse(this.inputElement.value);
this.value = this.validateInput(value);

@@ -360,2 +377,3 @@ }

const hasDecimals = maximumFractionDigits && maximumFractionDigits > 0;
/* c8 ignore next 18 */
if (isIPhone()) {

@@ -385,2 +403,23 @@ // iPhone doesn't have a minus sign in either numeric or decimal.

}
connectedCallback() {
super.connectedCallback();
this.resolveLanguage();
}
disconnectedCallback() {
this.resolveLanguage();
super.disconnectedCallback();
}
resolveLanguage() {
const queryThemeEvent = new CustomEvent('sp-language-context', {
bubbles: true,
composed: true,
detail: {
callback: (lang) => {
this.resolvedLanguage = lang;
},
},
cancelable: true,
});
this.dispatchEvent(queryThemeEvent);
}
}

@@ -409,7 +448,13 @@ __decorate([

__decorate([
property({ attribute: false })
], NumberField.prototype, "resolvedLanguage", void 0);
__decorate([
property({ type: Number })
], NumberField.prototype, "step", void 0);
__decorate([
property({ type: Number, reflect: true, attribute: 'step-modifier' })
], NumberField.prototype, "stepModifier", void 0);
__decorate([
property({ type: Number })
], NumberField.prototype, "value", null);
//# sourceMappingURL=NumberField.js.map

@@ -1,2 +0,2 @@

declare const styles: import("@spectrum-web-components/base").CSSResultGroup;
declare const styles: import("@spectrum-web-components/base").CSSResult;
export default styles;

@@ -102,2 +102,14 @@ /*

},
stepModifier: {
name: 'step modifier',
type: { name: 'number', required: false },
description: 'Amount to scale the step increment/decrement when holding the shift key',
table: {
type: { summary: 'number' },
defaultValue: { summary: 10 },
},
control: {
type: 'number',
},
},
placeholder: {

@@ -104,0 +116,0 @@ name: 'placeholder',

@@ -68,2 +68,3 @@ /*

await import('@formatjs/intl-numberformat/locale-data/en.js');
await import('@formatjs/intl-numberformat/locale-data/fr.js');
}

@@ -76,15 +77,44 @@ });

});
it('receives input', async () => {
const el = await getElFrom(Default({ value: 1337 }));
expect(el.formattedValue).to.equal('1,337');
expect(el.valueAsString).to.equal('1337');
expect(el.value).to.equal(1337);
el.focus();
await sendKeys({ type: '7331' });
await elementUpdated(el);
await sendKeys({ press: 'Enter' });
await elementUpdated(el);
expect(el.formattedValue).to.equal('13,377,331');
expect(el.valueAsString).to.equal('13377331');
expect(el.value).to.equal(13377331);
describe('receives input', () => {
it('without language context', async () => {
const el = await getElFrom(Default({ value: 1337 }));
expect(el.formattedValue).to.equal('1,337');
expect(el.valueAsString).to.equal('1337');
expect(el.value).to.equal(1337);
el.focus();
await sendKeys({ type: '7331' });
await elementUpdated(el);
await sendKeys({ press: 'Enter' });
await elementUpdated(el);
expect(el.formattedValue).to.equal('13,377,331');
expect(el.valueAsString).to.equal('13377331');
expect(el.value).to.equal(13377331);
});
it('with language context', async () => {
const lang = 'fr';
const langResolvers = [];
const createLangResolver = (event) => {
langResolvers.push(event.detail.callback);
resolveLanguage();
};
const resolveLanguage = () => {
langResolvers.forEach((resolver) => resolver(lang));
};
const el = await getElFrom(html `
<div @sp-language-context=${createLangResolver}>
${Default({ value: 1337 })}
</div>
`);
expect(el.formattedValue).to.equal('1 337');
expect(el.valueAsString).to.equal('1337');
expect(el.value).to.equal(1337);
el.focus();
await sendKeys({ type: '7331' });
await elementUpdated(el);
await sendKeys({ press: 'Enter' });
await elementUpdated(el);
expect(el.formattedValue).to.equal('13 377 331');
expect(el.valueAsString).to.equal('13377331');
expect(el.value).to.equal(13377331);
});
});

@@ -138,3 +168,3 @@ describe('Increments', () => {

expect(el.value).to.equal(0);
el.dispatchEvent(new WheelEvent('wheel', { deltaY: 1 }));
el.dispatchEvent(new WheelEvent('wheel', { deltaY: 100 }));
await elementUpdated(el);

@@ -193,3 +223,3 @@ expect(el.formattedValue).to.equal('1');

expect(el.value).to.equal(0);
el.dispatchEvent(new WheelEvent('wheel', { deltaY: -1 }));
el.dispatchEvent(new WheelEvent('wheel', { deltaY: -100 }));
await elementUpdated(el);

@@ -210,10 +240,8 @@ expect(el.formattedValue).to.equal('-1');

el.addEventListener('input', (event) => {
var _a, _b;
console.log('input event', (_a = event.target) === null || _a === void 0 ? void 0 : _a.value);
inputSpy((_b = event.target) === null || _b === void 0 ? void 0 : _b.value);
var _a;
inputSpy((_a = event.target) === null || _a === void 0 ? void 0 : _a.value);
});
el.addEventListener('change', (event) => {
var _a, _b;
console.log('change event', (_a = event.target) === null || _a === void 0 ? void 0 : _a.value);
changeSpy((_b = event.target) === null || _b === void 0 ? void 0 : _b.value);
var _a;
changeSpy((_a = event.target) === null || _a === void 0 ? void 0 : _a.value);
});

@@ -256,2 +284,3 @@ });

};
await elementUpdated(el);
el.value = 45;

@@ -803,2 +832,7 @@ expect(el.value).to.equal(45);

expect(el.value).to.equal(7);
el.value = 27;
await elementUpdated(el);
expect(el.formattedValue).to.equal('7');
expect(el.valueAsString).to.equal('7');
expect(el.value).to.equal(7);
});

@@ -805,0 +839,0 @@ });

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc