taiga-family/maskito

๐Ÿš€ - Delete calibration on initialization + create `maskitoInitialCalibrationPlugin`

nsbarsukov opened this issue ยท 3 comments

Which package(s) are relevant/related to the feature request?

@maskito/core

Description

Delete this line

this.ensureValueFitsMask();

+ add maskitoInitialCalibrationPlugin (inside @maskito/core or @maskito/kit ???):

export function maskitoInitialCalibrationPlugin(
    customOptions?: MaskitoOptions,
): MaskitoPlugin {
    return (element, options) => {
        element.value = maskitoTransform(element.value, customOptions || options);
    };
}

Why?

The current implementation is not so flexible as required.
Sometimes the such initial calibration is not required for developer, and develop wants calibration to work only on user's interactions.

The new way allows to select: use maskitoInitialCalibrationPlugin or not.

For these cases

describe('runtime changes of postfix', () => {
beforeEach(() => {
cy.visit(DemoPath.Cypress);
cy.get('#runtime-postfix-changes input')
.focus()
.should('have.value', '1 year')
.as('input');
});
it('1| year => Type 0 => 10| years', () => {
cy.get('@input')
.type('{moveToStart}{rightArrow}')
.type('0')
.should('have.value', '10 years')
.should('have.prop', 'selectionStart', '10'.length)
.should('have.prop', 'selectionEnd', '10'.length);
});
it('10| years => Backspace => 1| year', () => {
cy.get('@input')
.type('{moveToStart}{rightArrow}')
.type('0')
.should('have.value', '10 years')
.type('{backspace}')
.should('have.value', '1 year')
.should('have.prop', 'selectionStart', '1'.length)
.should('have.prop', 'selectionEnd', '1'.length);
});

Developer can use the optional argument of maskitoInitialCalibrationPlugin.

input-number.component.ts:

@tuiPure
private calculateMask(
    precision: number,
    decimalMode: TuiDecimal,
    decimalSeparator: string,
    thousandSeparator: string,
    min: number,
    max: number,
    prefix: string,
    postfix: string,
): MaskitoOptions {
    const generatorParams = {
        decimalSeparator,
        thousandSeparator,
        min,
        max,
        prefix,
        postfix,
        precision: decimalMode === 'never' ? 0 : precision,
        decimalZeroPadding: decimalMode === 'always',
    };
    const {plugins, ...options} = maskitoNumberOptionsGenerator(generatorParams);
    const initialCalibrationPlugin = maskitoInitialCalibrationPlugin(
        maskitoNumberOptionsGenerator({
                ...generatorParams,
                min: Number.MIN_SAFE_INTEGER,
                max: Number.MAX_SAFE_INTEGER
        })
    );

    return {
        ...options,
        plugins: [
            ...plugins,
            initialCalibrationPlugin,
            maskitoCaretGuard(value => [
                prefix.length,
                value.length - postfix.length,
            ]),
        ],
    };
}

Drop initialElementState.value && from this line (after solving this issue):

initialElementState.value && (focused || !focusedOnly)

Possibly after solving this issue we can also drop these lines ๐Ÿค”

(!value && !initialElementState.value.startsWith(prefix)) // cases when developer wants input to be empty

if (!value && !initialElementState.value.endsWith(postfix)) {
// cases when developer wants input to be empty (programmatically)
return {value, selection};
}

UPDATE: nope, it will break maskitoRemoveOnBlurPlugin (it dispatches input event and triggers mask check again) and other similar cases