@progress/kendo-react-inputs
Version:
React Inputs offer a customizable interface for users to enter and pick different information. KendoReact Input package
322 lines (321 loc) • 11.1 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 { SignaturePad as xe } from "@progress/kendo-inputs-common";
import { Button as T } from "@progress/kendo-react-buttons";
import { createPropsContext as Me, validatePackage as we, usePropsContext as Le, useIsomorphicLayoutEffect as Ie, dispatchEvent as h, classNames as B, kendoThemeMaps as ee, getTabIndex as Pe, WatermarkOverlay as De, noop as f } from "@progress/kendo-react-common";
import { Dialog as Te } from "@progress/kendo-react-dialogs";
import { useLocalization as Be } from "@progress/kendo-react-intl";
import a from "prop-types";
import * as o from "react";
import { signatureMaximize as te, messages as R, signatureMinimize as oe, signatureClear as ne } from "../messages/index.mjs";
import { packageMetadata as Re } from "../package-metadata.mjs";
import { hasParent as Fe } from "./utils/index.mjs";
import { hyperlinkOpenIcon as ae, xIcon as _e } from "@progress/kendo-svg-icons";
const Ne = 250, We = 84, ie = 3, le = 2, qe = "#000000", Ge = "#ffffff", re = (d) => d !== void 0, Ae = Me(), F = o.forwardRef((d, se) => {
const ce = !we(Re, { component: "Signature" }), _ = Le(Ae, d), e = o.useMemo(
() => ({
strokeWidth: l.strokeWidth,
smooth: l.smooth,
popupScale: l.popupScale,
exportScale: l.exportScale,
maximizable: l.maximizable,
disabled: l.disabled,
required: l.required,
validityStyles: l.validityStyles,
onChange: l.onChange,
onFocus: l.onFocus,
onBlur: l.onBlur,
onOpen: l.onOpen,
onClose: l.onClose,
size: l.size,
rounded: l.rounded,
fillMode: l.fillMode,
..._
}),
[_]
), z = Be(), c = o.useRef(null), g = o.useRef(null), N = o.useRef(null), W = o.useRef(null), S = o.useRef(null), [r, ue] = o.useState(), [b, q] = o.useState(!1), [E, G] = o.useState(!1), [k, A] = o.useState(), [de, me] = o.useState(), V = re(e.value) ? e.value : k, [pe, fe] = o.useState(!1), p = re(e.open), m = p ? e.open : pe, ge = e.maximized || E || !e.maximizable || e.disabled, be = !(e.maximized && !E), ke = !(!(e.value || k) || E || e.readOnly || e.disabled), j = z.toLanguageString(te, R[te]), U = z.toLanguageString(oe, R[oe]), H = z.toLanguageString(ne, R[ne]), O = e.popupScale || ie, x = e.exportScale || le, M = (t) => {
A(t), e.onChange && e.onChange({ value: t });
}, ye = (t) => {
r == null || r.loadImage(t.value), M(t.value);
};
o.useEffect(() => {
e.value !== k && (A(e.value), r == null || r.loadImage(e.value));
}, [e.value]);
const ve = () => {
r == null || r.clear(), M();
}, y = o.useCallback(
(t) => {
p || fe(t);
},
[p]
), Ce = (t) => {
var n, i;
Q(t), (i = ((n = S.current) == null ? void 0 : n.element) || g.current) == null || i.focus();
}, w = o.useCallback(() => {
let t = qe;
return !e.color && typeof document != "undefined" && c.current && (t = getComputedStyle(c.current).color), e.color || t;
}, [e.color]), L = o.useCallback(() => {
let t = Ge;
return !e.backgroundColor && typeof document != "undefined" && c.current && (t = getComputedStyle(c.current).backgroundColor), e.backgroundColor || t;
}, [e.backgroundColor]), $ = () => ({
scale: e.maximized ? e.popupScale : 1,
color: w(),
backgroundColor: L(),
strokeWidth: e.strokeWidth,
smooth: e.smooth,
readonly: e.readOnly
}), K = async (t) => {
const { width: n, height: i } = t;
return await (r == null ? void 0 : r.exportImage({
width: n * x,
height: i * x
}));
};
o.useEffect(() => {
const t = g.current, n = new xe(t, $());
return V && n.loadImage(V), ue(n), () => n.destroy();
}, []), o.useEffect(() => {
r == null || r.setOptions({
onChange: async () => M(await K(Y())),
onDraw: () => G(!0),
onDrawEnd: () => G(!1)
});
}, [r]), Ie(
() => r == null ? void 0 : r.setOptions($()),
[e.readOnly, e.color, e.backgroundColor, e.strokeWidth, e.smooth]
), o.useEffect(() => {
var i, s;
const t = (s = (i = N.current) == null ? void 0 : i.element) == null ? void 0 : s.querySelector(".k-overlay");
if (!t)
return;
const n = () => y(!1);
return t.addEventListener("click", n), () => t.removeEventListener("click", n);
}, [m]), o.useEffect(() => {
if (!m || typeof document == "undefined")
return;
const t = (n) => {
var i, s;
n.key === "Escape" && (y(!1), (s = (i = S.current) == null ? void 0 : i.element) == null || s.focus());
};
return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
}, [m]), o.useEffect(() => {
var t, n;
e.maximized && ((n = (t = W.current) == null ? void 0 : t.element) == null || n.focus());
}, []);
const I = o.useCallback(() => {
var t;
return (t = g.current) == null ? void 0 : t.focus();
}, []), v = o.useCallback(() => e.value, [e.value]), X = o.useCallback(() => e.name, [e.name]), C = o.useCallback(() => e.required, [e.required]), P = o.useCallback(() => {
const t = e.validationMessage !== void 0, i = !v(), s = e.valid !== void 0 ? e.valid : !C() || !i;
return {
customError: t,
valid: s,
valueMissing: i
};
}, [e.validationMessage, e.valid, v, C]), D = o.useCallback(() => e.validityStyles, [e.validityStyles]), J = o.useCallback(() => e, [e]), u = o.useCallback(() => {
const t = {
element: c.current,
focus: I
};
return Object.defineProperty(t, "name", { get: X }), Object.defineProperty(t, "value", { get: v }), Object.defineProperty(t, "validity", { get: P }), Object.defineProperty(t, "validityStyles", { get: D }), Object.defineProperty(t, "required", { get: C }), Object.defineProperty(t, "props", { get: J }), Object.defineProperty(t, "color", { get: w }), Object.defineProperty(t, "backgroundColor", { get: L }), t;
}, [
X,
v,
P,
D,
C,
I,
J,
w,
L
]);
o.useImperativeHandle(se, u);
const he = o.useCallback(
(t) => {
b || e.maximized || (q(!0), h(e.onFocus, t, u(), {}));
},
[b, e.onFocus, u]
), ze = o.useCallback(
(t) => {
Fe(t.relatedTarget, c.current) || (q(!1), h(e.onBlur, t, u(), {}));
},
[b, e.onBlur, u]
), Se = o.useCallback(
async (t) => {
me(await K(Z())), y(!0), h(e.onOpen, t, u(), {});
},
[m, p, e.onOpen, e.value, k, u]
), Q = o.useCallback(
(t) => {
y(!1), h(e.onClose, t, u(), {});
},
[m, p, e.onClose, u]
), Ee = () => {
ve(), I();
}, Y = () => {
var i, s;
const t = e.width || ((i = c.current) == null ? void 0 : i.offsetWidth) || Ne, n = e.height || ((s = c.current) == null ? void 0 : s.offsetHeight) || We;
return {
width: t,
height: n
};
}, Z = () => {
const { width: t, height: n } = Y();
return {
width: t * O,
height: n * O
};
}, Oe = !D() || P().valid;
return /* @__PURE__ */ o.createElement(
"div",
{
ref: c,
dir: e.dir,
style: { width: e.width, height: e.height, ...e.style },
className: B(
"k-input",
"k-signature",
{
"k-signature-maximized": e.maximized,
[`k-signature-${ee.sizeMap[e.size] || e.size}`]: e.size,
[`k-signature-${e.fillMode}`]: e.fillMode,
[`k-input-${e.fillMode}`]: e.fillMode,
[`k-rounded-${ee.roundedMap[e.rounded] || e.rounded}`]: e.rounded,
"k-invalid": !Oe,
"k-required": e.required,
"k-disabled": e.disabled,
"k-focus": b
},
e.className
),
onFocus: he,
onBlur: ze
},
/* @__PURE__ */ o.createElement(
"div",
{
className: "k-signature-canvas",
ref: g,
tabIndex: Pe(e.tabIndex, e.disabled),
role: "img",
id: e.id,
"aria-label": e.ariaLabel,
"aria-labelledby": e.ariaLabelledBy,
"aria-describedby": e.ariaDescribedBy,
"aria-disabled": e.disabled ? "true" : void 0
}
),
/* @__PURE__ */ o.createElement("div", { className: "k-signature-actions k-signature-actions-top" }, /* @__PURE__ */ o.createElement(
T,
{
type: "button",
className: B("k-signature-action", "k-signature-maximize", {
"k-hidden": e.disabled || ge
}),
ref: S,
icon: "hyperlink-open",
svgIcon: ae,
fillMode: "flat",
size: e.size,
onClick: Se,
"aria-label": j,
title: j
}
), /* @__PURE__ */ o.createElement(
T,
{
type: "button",
className: B("k-signature-action", "k-signature-minimize", "k-rotate-180", {
"k-hidden": e.disabled || be
}),
ref: W,
icon: "hyperlink-open",
svgIcon: ae,
fillMode: "flat",
size: e.size,
onClick: Q,
"aria-label": U,
title: U
}
)),
!e.hideLine && /* @__PURE__ */ o.createElement("div", { className: "k-signature-line", style: { zIndex: 2, pointerEvents: "none" } }),
/* @__PURE__ */ o.createElement("div", { className: "k-signature-actions k-signature-actions-bottom" }, ke && /* @__PURE__ */ o.createElement(
T,
{
type: "button",
className: "k-signature-action k-signature-clear",
icon: "x",
svgIcon: _e,
fillMode: "flat",
size: e.size,
onClick: Ee,
"aria-label": H,
title: H
}
)),
m && /* @__PURE__ */ o.createElement(Te, { ref: N }, /* @__PURE__ */ o.createElement(
F,
{
...e,
...Z(),
value: de,
maximized: !0,
exportScale: 1 / O * x,
open: !1,
onChange: ye,
onClose: Ce
}
)),
ce && /* @__PURE__ */ o.createElement(De, null)
);
});
F.propTypes = {
value: a.string,
width: a.number,
height: a.number,
tabIndex: a.number,
dir: a.string,
ariaDescribedBy: a.string,
ariaLabelledBy: a.string,
ariaLabel: a.string,
readOnly: a.bool,
disabled: a.bool,
validationMessage: a.string,
required: a.bool,
onChange: a.func,
onFocus: a.func,
onBlur: a.func,
onOpen: a.func,
onClose: a.func,
size: a.oneOf([null, "small", "medium", "large"]),
rounded: a.oneOf([null, "small", "medium", "large"]),
fillMode: a.oneOf([null, "solid", "flat", "outline"])
};
const l = {
strokeWidth: 1,
smooth: !1,
popupScale: ie,
exportScale: le,
maximizable: !0,
disabled: !1,
required: !1,
validityStyles: !0,
onChange: (d) => f,
onFocus: (d) => f,
onBlur: (d) => f,
onOpen: (d) => f,
onClose: (d) => f,
size: "medium",
rounded: "medium",
fillMode: "solid"
};
F.displayName = "KendoSignature";
export {
F as Signature,
Ae as SignaturePropsContext
};