Skip to content

Input field, type="number": allow modifying number of decimals in formatted value #3497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Kiarokh opened this issue Mar 18, 2025 · 0 comments
Assignees

Comments

@Kiarokh
Copy link
Contributor

Kiarokh commented Mar 18, 2025

New feature motivation

Currently, the input type="number" formats the value and rounds it up with 3 decimals. For example, if the user types for example 1.1239, the formatter will turn it to 1.124. But consumers (such as CPQ in Lime CRM) need to control the number of decimals in the formatted value.

New feature description

The number formatting happens in the renderFormattedNumber method in input-field.tsx around line 777:

private renderFormattedNumber = () => {
    if (this.type !== 'number') {
        return;
    }

    let renderValue = this.value;
    if (this.formatNumber && this.value) {
        renderValue = new Intl.NumberFormat(this.locale).format(
            Number(this.value),
        );
        if (renderValue === 'NaN') {
            return;
        }
    }

    return (
        <span class="lime-formatted-input lime-looks-like-input-value">
            {renderValue}
        </span>
    );
};

Currently, the component uses Intl.NumberFormat with just the locale parameter, without specifying any options for controlling decimal places. The JavaScript Intl.NumberFormat API defaults to the locale's standard formatting rules, which typically results in up to 3 decimal places for many locales.

There is no built-in way to control the decimal precision in the component without modifying its source code.

New feature implementation

To control the number of decimal places, we would need to modify the component to accept additional properties like minimumFractionDigits and maximumFractionDigits, and then pass them to the Intl.NumberFormat constructor:

/**
 * Minimum number of fraction digits to display when formatting numbers.
 * Only applies when `type` is `number` and `formatNumber` is `true`.
 * If not specified, the locale's default is used.
 */
@Prop({ reflect: true })
public minimumFractionDigits?: number;

/**
 * Maximum number of fraction digits to display when formatting numbers.
 * Only applies when `type` is `number` and `formatNumber` is `true`.
 * If not specified, the locale's default is used (typically 3).
 */
@Prop({ reflect: true })
public maximumFractionDigits?: number;

Then modify the renderFormattedNumber method

private renderFormattedNumber = () => {
    if (this.type !== 'number') {
        return;
    }

    let renderValue = this.value;
    if (this.formatNumber && this.value) {
        const options: Intl.NumberFormatOptions = {};
        
        if (typeof this.minimumFractionDigits === 'number') {
            options.minimumFractionDigits = this.minimumFractionDigits;
        }
        
        if (typeof this.maximumFractionDigits === 'number') {
            options.maximumFractionDigits = this.maximumFractionDigits;
        }
        
        renderValue = new Intl.NumberFormat(this.locale, options).format(
            Number(this.value)
        );
        if (renderValue === 'NaN') {
            return;
        }
    }

    return (
        <span class="lime-formatted-input lime-looks-like-input-value">
            {renderValue}
        </span>
    );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants