@progress/kendo-react-inputs
Version:
React Inputs offer a customizable interface for users to enter and pick different information. KendoReact Input package
331 lines (330 loc) • 10.6 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as p from "react";
import e from "prop-types";
import { MaskingService as O } from "./masking.service.mjs";
import { defaultRules as y, maskingChanged as V, returnFalse as b } from "./utils.mjs";
import { useCustomComponent as _, classNames as C, uMaskedTextBox as P, getTabIndex as k, createPropsContext as w, withIdHOC as I, withPropsContext as M, withUnstyledHOC as D } from "@progress/kendo-react-common";
import { FloatingLabel as H } from "@progress/kendo-react-labels";
const a = class a extends p.Component {
constructor() {
super(...arguments), this.state = {}, this._inputId = `k_${this.props.id}`, this._service = new O(), this._isPasted = !1, this._selection = [null, null], this._input = null, this.focus = () => {
this._input && this._input.focus();
}, this.pasteHandler = (t) => {
const { selectionStart: s, selectionEnd: i } = t.target;
i !== s && (this._isPasted = !0, this._selection = [s || 0, i || 0]);
}, this.onChangeHandler = (t) => {
const s = t.currentTarget, i = s.value, l = this._selection[0] || 0, o = this._selection[1] || 0;
if (!this.props.mask) {
this._isPasted = !1, this._selection = [null, null], this.triggerOnChange(i, t);
return;
}
const r = this.value;
let n;
if (this._isPasted) {
this._isPasted = !1;
const d = r.length - o, u = i.length - d;
n = this._service.maskInRange(i.slice(l, u), r, l, o);
} else
n = this._service.maskInput(i, r, s.selectionStart || 0);
this._selection = [n.selection, n.selection], this.triggerOnChange(n.value, t);
}, this.focusHandler = (t) => {
this.state.focused || (this.setState({ focused: !0 }), this.props.onFocus && this.props.onFocus.call(void 0, {
target: this,
syntheticEvent: t,
nativeEvent: t.nativeEvent
}));
}, this.blurHandler = (t) => {
this.state.focused && (this.setState({ focused: !1 }), this.props.onBlur && this.props.onBlur.call(void 0, {
target: this,
syntheticEvent: t,
nativeEvent: t.nativeEvent
}));
}, this.setValidity = () => {
this.element && this.element.setCustomValidity(this.validity.valid ? "" : this.props.validationMessage || "");
};
}
/**
* Gets the element of the MaskedTextBox.
*
* @return - An `HTMLInputElement`.
*
* @example
* ```jsx
* class App extends React.Component {
* constructor(props) {
* super(props);
* }
* element = null;
* render() {
* return (
* <div>
* <MaskedTextBox
* ref={(component) =>
* this.element = component ? component.element : null}
* />
* <button onClick={() => console.log(this.element)}>console.log the element</button>
* </div>
* );
* }
* }
*
* ReactDOM.render(
* <App />,
* document.getElementsByTagName('my-app')[0]
* );
* ```
*/
get element() {
return this._input;
}
/**
* Gets the value with the mask of the MaskedTextBox.
*/
get value() {
return this._valueDuringOnChange !== void 0 ? this._valueDuringOnChange : this.props.value !== void 0 ? this.props.value : this.state.value !== void 0 ? this.state.value : this.props.defaultValue !== void 0 ? this.props.defaultValue : "";
}
/**
* Gets the raw value without the mask of the MaskedTextBox.
*/
get rawValue() {
return this._service.rawValue(this.value);
}
/**
* Represents the validity state into which the MaskedTextBox is set.
*/
get validity() {
const t = this.value, s = this._service.validationValue(t), i = this.props.validationMessage !== void 0, l = this.props.valid !== void 0 ? this.props.valid : (!this.required || !!s) && (!this.props.maskValidation || !this.props.prompt || t.indexOf(this.props.prompt) === -1);
return {
customError: i,
valid: l,
valueMissing: !s
};
}
/**
* @hidden
*/
get validityStyles() {
return this.props.validityStyles !== void 0 ? this.props.validityStyles : a.defaultProps.validityStyles;
}
/**
* @hidden
*/
get required() {
return this.props.required !== void 0 ? this.props.required : !1;
}
/**
* Gets the `name` property of the MaskedTextBox.
*/
get name() {
return this.props.name;
}
/**
* @hidden
*/
componentDidUpdate(t, s) {
if (this.element && this.state.focused && s.focused) {
let [i, l] = this._selection;
const o = t.selection, r = this.props.selection;
(!o && r || o && r && (o.start !== r.start || o.end !== r.end)) && (i = r.start, l = r.end), i !== null && l !== null && this.element.setSelectionRange(i, l);
}
V(t, this.props) && this.updateService(), this.setValidity();
}
/**
* @hidden
*/
componentDidMount() {
this.updateService(), this.setValidity();
}
/**
* @hidden
*/
render() {
const {
size: t = a.defaultProps.size,
fillMode: s = a.defaultProps.fillMode,
rounded: i = a.defaultProps.rounded,
autoFocus: l = a.defaultProps.autoFocus,
prefix: o = a.defaultProps.prefix,
suffix: r = a.defaultProps.suffix,
inputAttributes: n,
unstyled: d,
className: u
} = this.props, c = this.props.id || this._inputId, f = !this.validityStyles || this.validity.valid, v = this.props.style || {}, m = d && d.uMaskedTextBox, [x] = _(o), [S] = _(r), g = /* @__PURE__ */ p.createElement(
"span",
{
dir: this.props.dir,
className: C(
P.wrapper({
c: m,
invalid: !f,
disabled: this.props.disabled,
size: t,
fillMode: s,
rounded: i
}),
u
),
style: this.props.label ? v : { width: this.props.width, ...v }
},
/* @__PURE__ */ p.createElement(x, null),
/* @__PURE__ */ p.createElement(
"input",
{
type: "text",
autoComplete: "off",
autoCorrect: "off",
autoCapitalize: "off",
autoFocus: l,
spellCheck: !1,
className: C(P.inputInner({ c: m })),
value: this.value,
id: c,
"aria-labelledby": this.props.ariaLabelledBy,
"aria-describedby": this.props.ariaDescribedBy,
"aria-placeholder": this.props.mask,
"aria-required": this.props.required,
name: this.props.name,
tabIndex: k(this.props.tabIndex, this.props.disabled, !0),
accessKey: this.props.accessKey,
title: this.props.title,
disabled: this.props.disabled || void 0,
readOnly: this.props.readonly || void 0,
placeholder: this.props.placeholder,
ref: (E) => this._input = E,
onChange: this.onChangeHandler,
onPaste: this.pasteHandler,
onFocus: this.focusHandler,
onBlur: this.blurHandler,
onDragStart: b,
onDrop: b,
...n
}
),
/* @__PURE__ */ p.createElement(S, null)
);
return this.props.label ? /* @__PURE__ */ p.createElement(
H,
{
label: this.props.label,
editorId: c,
editorValue: this.value,
editorValid: f,
editorDisabled: this.props.disabled,
editorPlaceholder: this.props.placeholder,
children: g,
style: { width: this.props.width },
dir: this.props.dir
}
) : g;
}
triggerOnChange(t, s) {
if (this.setState({
value: t
}), this.props.onChange) {
this._valueDuringOnChange = t;
const i = {
syntheticEvent: s,
nativeEvent: s.nativeEvent,
selectionStart: this._selection[0],
selectionEnd: this._selection[1],
target: this,
value: this.value
};
this.props.onChange.call(void 0, i), this._valueDuringOnChange = void 0;
}
}
updateService(t) {
const s = Object.assign(
{
includeLiterals: this.props.includeLiterals,
mask: this.props.mask,
prompt: this.props.prompt,
promptPlaceholder: this.props.promptPlaceholder,
rules: this.rules
},
t
);
this._service.update(s);
}
get rules() {
return Object.assign({}, y, this.props.rules);
}
};
a.displayName = "MaskedTextBox", a.propTypes = {
value: e.string,
defaultValue: e.string,
placeholder: e.string,
title: e.string,
dir: e.string,
id: e.string,
style: e.object,
className: e.string,
prefix: e.any,
suffix: e.any,
ariaLabelledBy: e.string,
ariaDescribedBy: e.string,
width: e.oneOfType([e.string, e.number]),
tabIndex: e.number,
accessKey: e.string,
disabled: e.bool,
readonly: e.bool,
prompt: e.string,
promptPlaceholder: e.string,
includeLiterals: e.bool,
maskValidation: e.bool,
mask: e.string,
rules: function(t, s, i) {
const l = t.rules;
return l !== void 0 && !Object.entries(l).some((r) => typeof r != "string" || !(l[r] instanceof RegExp)) ? new Error(
"Invalid prop `" + s + "` supplied to `" + i + "`. Validation failed."
) : null;
},
selection: e.shape({
start: e.number.isRequired,
end: e.number.isRequired
}),
name: e.string,
label: e.string,
validationMessage: e.string,
required: e.bool,
valid: e.bool,
validityStyles: e.bool,
onChange: e.func,
size: e.oneOf([null, "small", "medium", "large"]),
rounded: e.oneOf([null, "small", "medium", "large", "full"]),
fillMode: e.oneOf([null, "solid", "flat", "outline"]),
autoFocus: e.bool,
inputAttributes: e.object
}, a.defaultProps = {
prompt: "_",
promptPlaceholder: " ",
includeLiterals: !1,
maskValidation: !0,
rules: y,
validityStyles: !0,
prefix: (t) => null,
suffix: (t) => null,
size: "medium",
rounded: "medium",
fillMode: "solid",
autoFocus: !1
};
let h = a;
const q = w(), B = I(
M(
q,
D(h)
)
);
B.displayName = "KendoReactMaskedTextBox";
export {
B as MaskedTextBox,
q as MaskedTextBoxPropsContext,
h as MaskedTextBoxWithoutContext
};