@elcrm/form 0.0.87 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +87 -47
  2. package/dist/Form.js +1 -11
  3. package/dist/FormInitContext.js +1 -20
  4. package/dist/assets/styles/Field.module.css +1 -1
  5. package/dist/assets/styles/Form.module.css +1 -1
  6. package/dist/assets/styles/Select.module.css +1 -1
  7. package/dist/core/Field.d.ts +14 -2
  8. package/dist/core/Field.js +2 -35
  9. package/dist/dark.css +22 -3
  10. package/dist/events/onEvent.js +1 -67
  11. package/dist/fields/Check.js +1 -86
  12. package/dist/fields/Code.js +1 -94
  13. package/dist/fields/Color.js +1 -495
  14. package/dist/fields/Date.js +1 -450
  15. package/dist/fields/Display.d.ts +1 -1
  16. package/dist/fields/Display.js +1 -49
  17. package/dist/fields/DragDrop.js +1 -189
  18. package/dist/fields/Email.d.ts +4 -2
  19. package/dist/fields/Email.js +1 -80
  20. package/dist/fields/File.js +1 -115
  21. package/dist/fields/Hidden.js +1 -33
  22. package/dist/fields/Input.d.ts +3 -1
  23. package/dist/fields/Input.js +1 -149
  24. package/dist/fields/Mask.js +1 -119
  25. package/dist/fields/Modal.js +1 -68
  26. package/dist/fields/Money.js +1 -125
  27. package/dist/fields/NativeTextField.d.ts +15 -0
  28. package/dist/fields/NativeTextField.js +1 -0
  29. package/dist/fields/Numeric.d.ts +12 -1
  30. package/dist/fields/Numeric.js +1 -105
  31. package/dist/fields/Options.js +1 -69
  32. package/dist/fields/Password.d.ts +1 -1
  33. package/dist/fields/Password.js +1 -143
  34. package/dist/fields/Percent.d.ts +8 -1
  35. package/dist/fields/Percent.js +1 -100
  36. package/dist/fields/Phone.d.ts +2 -2
  37. package/dist/fields/Phone.js +1 -128
  38. package/dist/fields/Radio.js +1 -88
  39. package/dist/fields/Range.js +1 -109
  40. package/dist/fields/Rating.js +1 -82
  41. package/dist/fields/RichText.js +1 -134
  42. package/dist/fields/Select.d.ts +3 -1
  43. package/dist/fields/Select.js +1 -159
  44. package/dist/fields/Tags.js +1 -97
  45. package/dist/fields/Textarea.d.ts +1 -1
  46. package/dist/fields/Textarea.js +1 -68
  47. package/dist/fields/Time.js +1 -444
  48. package/dist/fields/Url.d.ts +4 -2
  49. package/dist/fields/Url.js +1 -80
  50. package/dist/fields/emit.d.ts +9 -0
  51. package/dist/fields/emit.js +1 -0
  52. package/dist/fields/type.d.ts +1 -1
  53. package/dist/fields/visibility.js +1 -6
  54. package/dist/hooks/use.js +1 -57
  55. package/dist/index.js +2 -42
  56. package/dist/index.umd.js +2 -2
  57. package/dist/light.css +23 -3
  58. package/dist/mask/MaskPhone.js +1 -1384
  59. package/dist/mask/phoneDefaults.d.ts +8 -0
  60. package/dist/mask/phoneDefaults.js +1 -0
  61. package/dist/overlayZ.js +1 -25
  62. package/dist/package.js +1 -130
  63. package/dist/style.css +3 -3
  64. package/dist/styles/Color.module.js +1 -27
  65. package/dist/styles/Field.module.js +1 -77
  66. package/dist/styles/Form.module.js +1 -12
  67. package/dist/styles/Select.module.js +1 -9
  68. package/package.json +2 -2
@@ -1,119 +1 @@
1
- import e from "../styles/Field.module.js";
2
- import t from "../core/Field.js";
3
- import { useFormFieldState as n } from "../hooks/use.js";
4
- import r, { asEditableClipboard as i } from "../events/onEvent.js";
5
- import { isEmptyTextLike as a } from "./visibility.js";
6
- import o from "react";
7
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
8
- //#region src/lib/fields/Mask.tsx
9
- function u(e) {
10
- let t = window.getSelection();
11
- if (!t || t.rangeCount === 0) return 0;
12
- let n = t.getRangeAt(0);
13
- if (!e.contains(n.startContainer)) return 0;
14
- let r = document.createRange();
15
- return r.selectNodeContents(e), r.setEnd(n.startContainer, n.startOffset), r.toString().length;
16
- }
17
- function d(e, t) {
18
- if (t <= 0) return 0;
19
- let n = 0;
20
- for (let r = 0; r < e.length; r++) if (/\d/.test(e[r]) && (n++, n === t)) return r + 1;
21
- return e.length;
22
- }
23
- function f({ value: f = "", form: p, onValue: m, onBlur: h, name: g = "", format: _ = "+_(___) ___-__-__", placeholder: v = "", label: y = "", error: b = "", hidden: x = !1, disabled: S = !1, className: C = "", after: w = "", before: T = "", inputmode: E = "numeric", view: D }) {
24
- let O = !S, { value: k, version: A } = n(p, g, f), j = o.useRef(null), M = o.useRef(!1), N = _, P = !0, F = 0, I = (e, t) => {
25
- let n = t.firstChild;
26
- if (!n || n.nodeType !== Node.TEXT_NODE) return;
27
- let r = n.textContent?.length ?? 0, i = Math.max(0, Math.min(e, r)), a = document.createRange(), o = window.getSelection();
28
- o && (a.setStart(n, i), a.collapse(!0), o.removeAllRanges(), o.addRange(a), t.focus());
29
- }, L = (e) => r.PasteOne(i(e)), R = (e) => {
30
- N = _, P = !0, F = 0;
31
- let t = 0, n = "", r = e.replace(/\D/g, "");
32
- r === "" && (P = !0);
33
- let i = r.split(""), a = "";
34
- i.forEach((e) => {
35
- P && (a += e, P && (F = ("" + a).length, N = _.replace(/* @__PURE__ */ RegExp("[0-9]", "g"), "_"), n = ""), F > ("" + a).length && (P = !0, N = _.replace(/* @__PURE__ */ RegExp("[0-9]", "g"), "_"), n = ""));
36
- });
37
- let o = N.replace(/\D/g, "");
38
- return o.length >= r.length && (r = o), {
39
- q: N.replace(/[_\d]/g, function() {
40
- return r.charAt(t++) || "_";
41
- }),
42
- i: t,
43
- v: r,
44
- f: n
45
- };
46
- };
47
- o.useLayoutEffect(() => {
48
- if (M.current) return;
49
- let e = j.current;
50
- if (!e) return;
51
- let t = R(String(k || ""));
52
- e.textContent !== t.q && (e.textContent = t.q);
53
- }, [
54
- k,
55
- A,
56
- _
57
- ]), R(String(k || ""));
58
- let z = (e) => {
59
- let t = e.target, n = t.textContent || "", r = u(t), i = n.slice(0, r).replace(/\D/g, "").length, a = R(n);
60
- t.textContent = a.q;
61
- let o = d(a.q, i);
62
- a.q.length > 0 && queueMicrotask(() => {
63
- I(Math.min(o, a.q.length), t);
64
- });
65
- let s = {
66
- value: a.q.replace(/\D/g, ""),
67
- name: g
68
- };
69
- p && g && p.onValue(s), m && m !== p?.onValue && m(s);
70
- }, B = (e) => {
71
- e.key === "Enter" && e.preventDefault();
72
- }, V = (e) => {
73
- r.Blur(e), h && h({
74
- value: (e.target.textContent ?? "").replace(/\D/g, ""),
75
- name: g
76
- }), M.current = !1;
77
- }, H = (e) => {
78
- M.current = !0, r.Focus({ target: e.currentTarget });
79
- }, U = {};
80
- v && (U.placeholder = v), U.inputMode = E ?? "numeric";
81
- let W = String(k ?? "").replace(/\D/g, "");
82
- return x && a(W) ? /* @__PURE__ */ c(s, {}) : /* @__PURE__ */ l(t, {
83
- type: "input",
84
- label: y,
85
- error: b,
86
- element_blok: { className: [C] },
87
- element_input: { className: [e.w] },
88
- children: [
89
- T ? /* @__PURE__ */ c("span", {
90
- className: e.affix,
91
- children: T
92
- }) : null,
93
- /* @__PURE__ */ c("div", {
94
- ref: j,
95
- onPaste: L,
96
- onInput: z,
97
- onKeyDown: B,
98
- onBlur: V,
99
- onFocus: H,
100
- role: "textbox",
101
- spellCheck: !1,
102
- "aria-label": y || v || g || "Маска",
103
- "aria-disabled": !O,
104
- tabIndex: S ? -1 : 0,
105
- "data-disabled": !O,
106
- contentEditable: O ? "plaintext-only" : !1,
107
- suppressContentEditableWarning: !0,
108
- ...U
109
- }),
110
- w ? /* @__PURE__ */ c("span", {
111
- className: e.affix,
112
- children: w
113
- }) : null
114
- ]
115
- });
116
- }
117
- f.displayName = "MaskField";
118
- //#endregion
119
- export { f as default };
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import r,{asEditableClipboard as i}from"../events/onEvent.js";import{isEmptyTextLike as a}from"./visibility.js";import o from"react";import{Fragment as s,jsx as c,jsxs as l}from"react/jsx-runtime";function u(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function d(e,t){if(t<=0)return 0;let n=0;for(let r=0;r<e.length;r++)if(/\d/.test(e[r])&&(n++,n===t))return r+1;return e.length}function f({value:f=``,form:p,onValue:m,onBlur:h,name:g=``,format:_=`+_(___) ___-__-__`,placeholder:v=``,label:y=``,error:b=``,hidden:x=!1,disabled:S=!1,className:C=``,after:w=``,before:T=``,inputmode:E=`numeric`,view:D}){let O=!S,{value:k,version:A}=n(p,g,f),j=o.useRef(null),M=o.useRef(!1),N=_,P=!0,F=0,I=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},L=e=>r.PasteOne(i(e)),R=e=>{N=_,P=!0,F=0;let t=0,n=``,r=e.replace(/\D/g,``);r===``&&(P=!0);let i=r.split(``),a=``;i.forEach(e=>{P&&(a+=e,P&&(F=(``+a).length,N=_.replace(RegExp(`[0-9]`,`g`),`_`),n=``),F>(``+a).length&&(P=!0,N=_.replace(RegExp(`[0-9]`,`g`),`_`),n=``))});let o=N.replace(/\D/g,``);return o.length>=r.length&&(r=o),{q:N.replace(/[_\d]/g,function(){return r.charAt(t++)||`_`}),i:t,v:r,f:n}};o.useLayoutEffect(()=>{if(M.current)return;let e=j.current;if(!e)return;let t=R(String(k||``));e.textContent!==t.q&&(e.textContent=t.q)},[k,A,_]),R(String(k||``));let z=e=>{let t=e.target,n=t.textContent||``,r=u(t),i=n.slice(0,r).replace(/\D/g,``).length,a=R(n);t.textContent=a.q;let o=d(a.q,i);a.q.length>0&&queueMicrotask(()=>{I(Math.min(o,a.q.length),t)});let s={value:a.q.replace(/\D/g,``),name:g};p&&g&&p.onValue(s),m&&m!==p?.onValue&&m(s)},B=e=>{e.key===`Enter`&&e.preventDefault()},V=e=>{r.Blur(e),h&&h({value:(e.target.textContent??``).replace(/\D/g,``),name:g}),M.current=!1},H=e=>{M.current=!0,r.Focus({target:e.currentTarget})},U={};v&&(U.placeholder=v),U.inputMode=E??`numeric`;let W=String(k??``).replace(/\D/g,``);return x&&a(W)?c(s,{}):l(t,{type:`input`,label:y,error:b,element_blok:{className:[C]},element_input:{className:[e.w]},children:[T?c(`span`,{className:e.affix,children:T}):null,c(`div`,{ref:j,onPaste:L,onInput:z,onKeyDown:B,onBlur:V,onFocus:H,role:`textbox`,spellCheck:!1,"aria-label":y||v||g||`Маска`,"aria-disabled":!O,tabIndex:S?-1:0,"data-disabled":!O,contentEditable:O?`plaintext-only`:!1,suppressContentEditableWarning:!0,...U}),w?c(`span`,{className:e.affix,children:w}):null]})}f.displayName=`MaskField`;export{f as default};
@@ -1,68 +1 @@
1
- import e from "../styles/Field.module.js";
2
- import t from "../core/Field.js";
3
- import { useFormFieldState as n } from "../hooks/use.js";
4
- import { isEmptyTextLike as r } from "./visibility.js";
5
- import { useFormInit as i } from "../FormInitContext.js";
6
- import "react";
7
- import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
8
- //#region src/lib/fields/Modal.tsx
9
- function c({ value: c, form: l, onValue: u, name: d, placeholder: f = "", label: p, error: m, hidden: h = !1, disabled: g = !1, after: _, before: v, view: y, modal: b, options: x, className: S }) {
10
- let { onModal: C } = i(), { value: w } = n(l, d, c), T = w, E = (e) => e ? Array.isArray(e) ? e[1] || "" : e : "", D = (e) => {
11
- if (Array.isArray(e) && e.length >= 2) return [e[0], String(e[1] ?? "")];
12
- if (typeof e == "object" && e) {
13
- let t = e;
14
- if (t.id !== void 0 && t.name !== void 0) return [t.id, t.name];
15
- }
16
- return String(e ?? "");
17
- }, O = (e) => {
18
- let t = {
19
- value: D(e),
20
- name: d
21
- };
22
- l && d && l.setValue(t), u && u !== l?.onValue && u(t);
23
- }, k = () => {
24
- if (g) return;
25
- if (!b) return console.error("modal - empty");
26
- let e = b.split(".");
27
- if (e.length < 2) return console.error("modal должен быть в формате 'module.name'");
28
- let t = Array.isArray(T) ? T[0] : T;
29
- C({
30
- module: e[0],
31
- modalName: e[1],
32
- callback: O,
33
- onValue: O,
34
- options: x,
35
- fieldName: d,
36
- value: t
37
- });
38
- }, A = {};
39
- f && (A.placeholder = f);
40
- let j = r(E(T));
41
- return h && j ? /* @__PURE__ */ o(a, {}) : /* @__PURE__ */ s(t, {
42
- type: "input",
43
- label: p,
44
- element_blok: { className: [S || ""] },
45
- error: m,
46
- element_input: {
47
- className: [e.w],
48
- props: { onClick: k }
49
- },
50
- children: [
51
- v ? /* @__PURE__ */ o("span", {
52
- className: e.affix,
53
- children: v
54
- }) : null,
55
- /* @__PURE__ */ o("div", {
56
- ...A,
57
- children: E(T)
58
- }),
59
- _ ? /* @__PURE__ */ o("span", {
60
- className: e.affix,
61
- children: _
62
- }) : null
63
- ]
64
- });
65
- }
66
- c.displayName = "ModalField";
67
- //#endregion
68
- export { c as default };
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{isEmptyTextLike as r}from"./visibility.js";import{useFormInit as i}from"../FormInitContext.js";import"react";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";function c({value:c,form:l,onValue:u,name:d,placeholder:f=``,label:p,error:m,hidden:h=!1,disabled:g=!1,after:_,before:v,view:y,modal:b,options:x,className:S}){let{onModal:C}=i(),{value:w}=n(l,d,c),T=w,E=e=>e?Array.isArray(e)?e[1]||``:e:``,D=e=>{if(Array.isArray(e)&&e.length>=2)return[e[0],String(e[1]??``)];if(typeof e==`object`&&e){let t=e;if(t.id!==void 0&&t.name!==void 0)return[t.id,t.name]}return String(e??``)},O=e=>{let t={value:D(e),name:d};l&&d&&l.setValue(t),u&&u!==l?.onValue&&u(t)},k=()=>{if(g||!b)return;let e=b.split(`.`);if(e.length<2)return;let t=Array.isArray(T)?T[0]:T;C({module:e[0],modalName:e[1],callback:O,onValue:O,options:x,fieldName:d,value:t})},A={};f&&(A.placeholder=f);let j=r(E(T));return h&&j?o(a,{}):s(t,{type:`input`,label:p,element_blok:{className:[S||``]},error:m,element_input:{className:[e.w],props:{onClick:k}},children:[v?o(`span`,{className:e.affix,children:v}):null,o(`div`,{...A,children:E(T)}),_?o(`span`,{className:e.affix,children:_}):null]})}c.displayName=`ModalField`;export{c as default};
@@ -1,125 +1 @@
1
- import e from "../styles/Field.module.js";
2
- import t from "../core/Field.js";
3
- import { useFormFieldState as n } from "../hooks/use.js";
4
- import r, { pastePlainTextIntoSelection as i } from "../events/onEvent.js";
5
- import { isEmptyTextLike as a } from "./visibility.js";
6
- import o from "react";
7
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
8
- //#region src/lib/fields/Money.tsx
9
- function l(e) {
10
- let t = window.getSelection();
11
- if (!t || t.rangeCount === 0) return 0;
12
- let n = t.getRangeAt(0);
13
- if (!e.contains(n.startContainer)) return 0;
14
- let r = document.createRange();
15
- return r.selectNodeContents(e), r.setEnd(n.startContainer, n.startOffset), r.toString().length;
16
- }
17
- function u(e, t, n) {
18
- let r = Math.max(0, Math.min(t, e.length));
19
- return n(e.slice(0, r)).length;
20
- }
21
- function d({ value: d, form: p, onValue: m, name: h = "", placeholder: g = "", label: _ = "", error: v = "", hidden: y = !1, disabled: b = !1, onBlur: x, className: S = "", after: C = "", before: w = "", inputmode: T = "decimal", course: E = 100, view: D, type: O, isClear: k = !1 }) {
22
- let { value: A, version: j } = n(p, h || "", d), M = p && h ? A : d, N = o.useRef(null), P = o.useRef(!1);
23
- o.useLayoutEffect(() => {
24
- if (P.current) return;
25
- let e = N.current;
26
- if (!e) return;
27
- let t = M != null && (typeof M == "number" ? !0 : !a(String(M))), n = !g || t ? f(M ?? "", E) : "";
28
- e.textContent !== n && (e.textContent = n);
29
- }, [
30
- M,
31
- j,
32
- g,
33
- E
34
- ]);
35
- let F = (e) => O === "multi" ? e.replace(/[^+\d.+-]/g, "") : e.replace(/[^+\d.]/g, ""), I = (e, t) => {
36
- let n = t.firstChild;
37
- if (!n || n.nodeType !== Node.TEXT_NODE) return;
38
- let r = n.textContent?.length ?? 0, i = Math.max(0, Math.min(e, r)), a = document.createRange(), o = window.getSelection();
39
- o && (a.setStart(n, i), a.collapse(!0), o.removeAllRanges(), o.addRange(a), t.focus());
40
- }, L = (e) => {
41
- let t = e.target, n = t.textContent || "", r = l(t), i = F(n), a = u(n, r, F), o = {
42
- value: Number(i || 0) * E,
43
- name: h
44
- };
45
- p && h && p.onValue(o), m && m !== p?.onValue && m(o), t.textContent = i, i.length > 0 && queueMicrotask(() => {
46
- I(Math.min(a, i.length), t);
47
- });
48
- }, R = (e) => {
49
- let t = e.target;
50
- r.Blur(e), (t.textContent || "") === "" && (t.textContent = "0");
51
- let n = {
52
- value: Number(F(t.textContent || "")) * E,
53
- name: h
54
- };
55
- p && h && p.setValue(n), x?.(n), m && m !== p?.onValue && m(n), t.textContent = f(F(t.textContent || "").trim() || "0"), P.current = !1;
56
- }, z = (e) => {
57
- P.current = !0;
58
- let t = e.target;
59
- t.textContent = F(t.textContent || ""), r.Focus({ target: e.currentTarget });
60
- }, B = (e) => {
61
- let t = e.currentTarget.previousElementSibling;
62
- t && (t.textContent = "");
63
- let n = {
64
- value: 0,
65
- name: h
66
- };
67
- p && h && p.setValue(n), m && m !== p?.onValue && m(n);
68
- }, V = (e) => {
69
- e.key === "Enter" && e.preventDefault();
70
- }, H = (e) => {
71
- e.preventDefault(), i(F(e.clipboardData?.getData("text/plain") ?? ""), e.currentTarget);
72
- }, U = !b, W = M == null || (typeof M == "number" ? !1 : a(String(M ?? "")));
73
- if (y && W) return "";
74
- let G = {};
75
- return G.inputMode = T ?? "decimal", g && (G.placeholder = g), U && (G.edit = ""), /* @__PURE__ */ c(t, {
76
- type: "input",
77
- label: _,
78
- error: v,
79
- element_blok: { className: [S] },
80
- element_input: { className: [e.w] },
81
- children: [
82
- w ? /* @__PURE__ */ s("span", {
83
- className: e.affix,
84
- children: w
85
- }) : null,
86
- /* @__PURE__ */ s("div", {
87
- ref: N,
88
- ...G,
89
- onInput: L,
90
- onPaste: H,
91
- onBlur: R,
92
- onKeyDown: V,
93
- onFocus: z,
94
- role: "textbox",
95
- spellCheck: !1,
96
- "aria-label": _ || g || "Сумма",
97
- "aria-disabled": !U,
98
- tabIndex: b ? -1 : 0,
99
- contentEditable: U ? "plaintext-only" : !1,
100
- suppressContentEditableWarning: !0
101
- }),
102
- k && /* @__PURE__ */ s("button", {
103
- type: "button",
104
- onClick: B,
105
- "aria-label": "Очистить поле",
106
- children: "x"
107
- }),
108
- C ? /* @__PURE__ */ s("span", {
109
- className: e.affix,
110
- children: C
111
- }) : null
112
- ]
113
- });
114
- }
115
- d.displayName = "MoneyField";
116
- function f(e, t) {
117
- let n;
118
- if (typeof e == "string") {
119
- let t = e.replace(/\s/g, "").replace(",", ".");
120
- n = parseFloat(t === "" ? "0" : t);
121
- } else n = Number(e ?? 0);
122
- return Number.isNaN(n) && (n = 0), t != null && t > 0 && (n /= t), n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1 ");
123
- }
124
- //#endregion
125
- export { d as default };
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import r,{pastePlainTextIntoSelection as i}from"../events/onEvent.js";import{isEmptyTextLike as a}from"./visibility.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function u(e,t,n){let r=Math.max(0,Math.min(t,e.length));return n(e.slice(0,r)).length}function d({value:d,form:p,onValue:m,name:h=``,placeholder:g=``,label:_=``,error:v=``,hidden:y=!1,disabled:b=!1,onBlur:x,className:S=``,after:C=``,before:w=``,inputmode:T=`decimal`,course:E=100,view:D,type:O,isClear:k=!1}){let{value:A,version:j}=n(p,h||``,d),M=p&&h?A:d,N=o.useRef(null),P=o.useRef(!1);o.useLayoutEffect(()=>{if(P.current)return;let e=N.current;if(!e)return;let t=M!=null&&(typeof M==`number`?!0:!a(String(M))),n=!g||t?f(M??``,E):``;e.textContent!==n&&(e.textContent=n)},[M,j,g,E]);let F=e=>O===`multi`?e.replace(/[^+\d.+-]/g,``):e.replace(/[^+\d.]/g,``),I=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},L=e=>{let t=e.target,n=t.textContent||``,r=l(t),i=F(n),a=u(n,r,F),o={value:Number(i||0)*E,name:h};p&&h&&p.onValue(o),m&&m!==p?.onValue&&m(o),t.textContent=i,i.length>0&&queueMicrotask(()=>{I(Math.min(a,i.length),t)})},R=e=>{let t=e.target;r.Blur(e),(t.textContent||``)===``&&(t.textContent=`0`);let n={value:Number(F(t.textContent||``))*E,name:h};p&&h&&p.setValue(n),x?.(n),m&&m!==p?.onValue&&m(n),t.textContent=f(F(t.textContent||``).trim()||`0`),P.current=!1},z=e=>{P.current=!0;let t=e.target;t.textContent=F(t.textContent||``),r.Focus({target:e.currentTarget})},B=e=>{let t=e.currentTarget.previousElementSibling;t&&(t.textContent=``);let n={value:0,name:h};p&&h&&p.setValue(n),m&&m!==p?.onValue&&m(n)},V=e=>{e.key===`Enter`&&e.preventDefault()},H=e=>{e.preventDefault(),i(F(e.clipboardData?.getData(`text/plain`)??``),e.currentTarget)},U=!b,W=M==null||(typeof M==`number`?!1:a(String(M??``)));if(y&&W)return``;let G={};return G.inputMode=T??`decimal`,g&&(G.placeholder=g),U&&(G.edit=``),c(t,{type:`input`,label:_,error:v,element_blok:{className:[S]},element_input:{className:[e.w]},children:[w?s(`span`,{className:e.affix,children:w}):null,s(`div`,{ref:N,...G,onInput:L,onPaste:H,onBlur:R,onKeyDown:V,onFocus:z,role:`textbox`,spellCheck:!1,"aria-label":_||g||`Сумма`,"aria-disabled":!U,tabIndex:b?-1:0,contentEditable:U?`plaintext-only`:!1,suppressContentEditableWarning:!0}),k&&s(`button`,{type:`button`,onClick:B,"aria-label":`Очистить поле`,children:`x`}),C?s(`span`,{className:e.affix,children:C}):null]})}d.displayName=`MoneyField`;function f(e,t){let n;if(typeof e==`string`){let t=e.replace(/\s/g,``).replace(`,`,`.`);n=parseFloat(t===``?`0`:t)}else n=Number(e??0);return Number.isNaN(n)&&(n=0),t!=null&&t>0&&(n/=t),n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,`$1 `)}export{d as default};
@@ -0,0 +1,15 @@
1
+ import { TInput } from './type';
2
+ export type TNativeTextField = TInput & {
3
+ /** data-field / визуальный тип обёртки */
4
+ fieldType: string;
5
+ /** type у input */
6
+ inputType: "email" | "url" | "text" | "search" | "tel";
7
+ /** fallback для aria-label, если нет label/placeholder */
8
+ defaultAriaLabel: string;
9
+ };
10
+ /**
11
+ * Общее нативное текстовое поле (Email / Url и т.п.).
12
+ * Подпись и ошибка связываются через Field a11y (htmlFor / aria-describedby).
13
+ */
14
+ declare function NativeTextField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxLength, autoComplete, inputmode, id, size, fieldType, inputType, defaultAriaLabel, }: TNativeTextField): import("react/jsx-runtime").JSX.Element | null;
15
+ export default NativeTextField;
@@ -0,0 +1 @@
1
+ import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import{isEmptyTextLike as i}from"./visibility.js";import{createFieldEmit as a}from"./emit.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l({value:n=``,form:l,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,maxLength:S,autoComplete:C,inputmode:w,id:T,size:E=`md`,fieldType:D,inputType:O,defaultAriaLabel:k}){let{value:A,version:j}=r(l,p,n),M=!v,N=typeof A==`string`||typeof A==`number`?String(A):``,P=o.useRef(null),F=a(l,p,d);return o.useEffect(()=>{let e=P.current;!e||e.value===N||(e.value=N)},[N,j]),_&&i(A)?null:c(t,{type:D,label:h,error:g,id:T,size:E,element_blok:{className:[y||``]},element_input:{className:[e.w],props:{"data-disabled":v||!M?`true`:void 0}},children:[x?s(`span`,{className:e.affix,children:x}):null,s(u,{inputRef:P,name:p,display:N,placeholder:m,maxLength:S,disabled:v,editable:M,autoComplete:C,inputMode:w,inputType:O,label:h,defaultAriaLabel:k,emit:F,onBlurField:f}),b?s(`span`,{className:e.affix,children:b}):null]})}function u({inputRef:t,name:r,display:i,placeholder:a,maxLength:o,disabled:c,editable:l,autoComplete:u,inputMode:d,inputType:f,label:p,defaultAriaLabel:m,emit:h,onBlurField:g}){let _=n();return s(`div`,{className:e.nativeWrap,children:s(`input`,{id:_?.controlId,ref:t,className:e.nativeInput,type:f,name:r||void 0,defaultValue:i,placeholder:a,maxLength:o,disabled:c,readOnly:!l,autoComplete:u,inputMode:d,spellCheck:!1,"aria-label":p?void 0:a||m,"aria-describedby":_?.describedBy,"aria-invalid":_?.errorId?!0:void 0,onChange:e=>h(e.target.value),onBlur:e=>{let t=(e.target.value||``).trim();h(t,!0),g?.({value:t,name:r})},onKeyDown:e=>{e.key===`Enter`&&e.preventDefault()}})})}export{l as default};
@@ -1,8 +1,19 @@
1
1
  import { TInput } from './type';
2
+ /**
3
+ * NumberField — целые цифры как **строка** в форме (`"123"`).
4
+ *
5
+ * **Не путать с PercentField:**
6
+ * - сюда в форму пишется **строка цифр**, не `number`;
7
+ * - проп **`max`** (и `maxLength`) — лимит **символов**, не верхняя граница числа;
8
+ * - дробных нет (только `\d`).
9
+ *
10
+ * Для процентов / clamp 0–100 / `number` используйте **`PercentField`**.
11
+ */
2
12
  type TNumeric = TInput & {
13
+ /** Макс. число символов (если нет `maxLength`). Не числовой максимум значения. */
3
14
  max?: number;
4
15
  };
5
- declare function NumberField({ value, form, onValue, name, placeholder, label, hidden, disabled, onBlur: onBlurField, className, after, before, error, size, inputmode, maxLength, max, view, }: TNumeric): import("react/jsx-runtime").JSX.Element;
16
+ declare function NumberField({ value, form, onValue, name, placeholder, label, hidden, disabled, onBlur: onBlurField, className, after, before, error, size, inputmode, maxLength, max, view, }: TNumeric): import("react/jsx-runtime").JSX.Element | null;
6
17
  declare namespace NumberField {
7
18
  var displayName: string;
8
19
  }
@@ -1,105 +1 @@
1
- import e from "../styles/Field.module.js";
2
- import t from "../core/Field.js";
3
- import { useFormFieldState as n } from "../hooks/use.js";
4
- import r, { asEditableClipboard as i } from "../events/onEvent.js";
5
- import { isEmptyTextLike as a } from "./visibility.js";
6
- import o from "react";
7
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
8
- //#region src/lib/fields/Numeric.tsx
9
- function u({ value: u, form: d, onValue: f, name: p = "", placeholder: m = "", label: h = "", hidden: g = !1, disabled: _ = !1, onBlur: v, className: y = "", after: b = "", before: x = "", error: S = "", size: C = "md", inputmode: w = "numeric", maxLength: T, max: E, view: D }) {
10
- let O = !_, { value: k, version: A } = n(d, p, u);
11
- m = m === void 0 ? "" : m, E = E === void 0 ? 99 : E;
12
- let j = k != null && k !== "" ? String(k) : "", M = o.useRef(null), N = o.useRef(!1);
13
- o.useLayoutEffect(() => {
14
- if (N.current) return;
15
- let e = M.current;
16
- e && e.textContent !== j && (e.textContent = j);
17
- }, [j, A]);
18
- let P = T ?? E, F = !1, I = (e, t) => {
19
- e.textContent !== t && (e.textContent = t, queueMicrotask(() => {
20
- let n = e.firstChild;
21
- if (n && n.nodeType === Node.TEXT_NODE) {
22
- let e = t.length, r = window.getSelection(), i = document.createRange();
23
- i.setStart(n, e), i.collapse(!0), r?.removeAllRanges(), r?.addRange(i);
24
- } else t || (e.innerHTML = "<br>");
25
- }));
26
- }, L = (e) => {
27
- let t = e.currentTarget, n = (t.textContent || "").replace(/\D/g, "");
28
- P > 0 && n.length > P && (n = n.slice(0, P)), I(t, n);
29
- let r = {
30
- value: n,
31
- name: p
32
- };
33
- d && p && d.onValue(r), f && f !== d?.onValue && f(r);
34
- }, R = (e) => {
35
- N.current = !0;
36
- let t = e.currentTarget;
37
- t.textContent = (t.textContent || "").replace(/\D/g, ""), r.Focus({ target: e.currentTarget });
38
- }, z = (e) => {
39
- if (F && e.which === 86) return;
40
- if (e.which === 17 || e.which === 91) return F = !0;
41
- if (e.key === "Backspace") return;
42
- let t = (e.currentTarget.textContent ?? "").replace(/\D/g, "").length;
43
- P > 0 && t >= P && e.key.length === 1 && /\d/.test(e.key) && e.preventDefault(), e.key === "Enter" && e.preventDefault(), e.key.length === 1 && !/\d/.test(e.key) && !e.metaKey && !e.ctrlKey && e.preventDefault();
44
- }, B = (e) => {
45
- if (e.which === 17 || e.which === 91) return F = !1;
46
- }, V = (e) => {
47
- r.PasteDigits(P, i(e)), queueMicrotask(() => {
48
- let e = M.current;
49
- if (!e) return;
50
- let t = (e.textContent || "").replace(/\D/g, "");
51
- P > 0 && t.length > P && (t = t.slice(0, P)), I(e, t), d && p && d.onValue({
52
- value: t,
53
- name: p
54
- });
55
- });
56
- }, H = (e) => {
57
- e.preventDefault();
58
- }, U = (e) => {
59
- r.Blur(e);
60
- let t = (e.currentTarget.textContent || "").replace(/\D/g, "");
61
- e.currentTarget.textContent !== t && (e.currentTarget.textContent = t), v?.({
62
- value: t,
63
- name: p
64
- }), N.current = !1;
65
- }, W = {};
66
- return O && (W.edit = ""), W.inputMode = w ?? "numeric", m && (W.placeholder = m), g && a(k) ? /* @__PURE__ */ c(s, {}) : /* @__PURE__ */ l(t, {
67
- type: "numeric",
68
- label: h,
69
- error: S,
70
- size: C,
71
- element_blok: { className: [y || ""] },
72
- element_input: { className: [e.w] },
73
- children: [
74
- x ? /* @__PURE__ */ c("span", {
75
- className: e.affix,
76
- children: x
77
- }) : null,
78
- /* @__PURE__ */ c("div", {
79
- ref: M,
80
- onPaste: V,
81
- onDrop: H,
82
- onDragOver: (e) => e.preventDefault(),
83
- onInput: L,
84
- onFocus: R,
85
- onBlur: U,
86
- onKeyDown: z,
87
- onKeyUp: B,
88
- spellCheck: !1,
89
- role: "textbox",
90
- tabIndex: O ? 0 : -1,
91
- "aria-label": h || m || "Число",
92
- contentEditable: O ? "plaintext-only" : !1,
93
- suppressContentEditableWarning: !0,
94
- ...W
95
- }),
96
- b ? /* @__PURE__ */ c("span", {
97
- className: e.affix,
98
- children: b
99
- }) : null
100
- ]
101
- });
102
- }
103
- u.displayName = "NumberField";
104
- //#endregion
105
- export { u as default };
1
+ import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import i,{asEditableClipboard as a}from"../events/onEvent.js";import{isEmptyTextLike as o}from"./visibility.js";import s from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u({value:n,form:u,onValue:f,name:p=``,placeholder:m=``,label:h=``,hidden:g=!1,disabled:_=!1,onBlur:v,className:y=``,after:b=``,before:x=``,error:S=``,size:C=`md`,inputmode:w=`numeric`,maxLength:T,max:E,view:D}){let O=!_,{value:k,version:A}=r(u,p,n);m=m===void 0?``:m,E=E===void 0?99:E;let j=k!=null&&k!==``?String(k):``,M=s.useRef(null),N=s.useRef(!1);s.useLayoutEffect(()=>{if(N.current)return;let e=M.current;e&&e.textContent!==j&&(e.textContent=j)},[j,A]);let P=T??E,F=(e,t)=>{e.textContent!==t&&(e.textContent=t,queueMicrotask(()=>{let n=e.firstChild;if(n&&n.nodeType===Node.TEXT_NODE){let e=t.length,r=window.getSelection(),i=document.createRange();i.setStart(n,e),i.collapse(!0),r?.removeAllRanges(),r?.addRange(i)}else t||(e.innerHTML=`<br>`)}))},I=e=>{let t=e.currentTarget,n=(t.textContent||``).replace(/\D/g,``);P>0&&n.length>P&&(n=n.slice(0,P)),F(t,n);let r={value:n,name:p};u&&p&&u.onValue(r),f&&f!==u?.onValue&&f(r)},L=e=>{N.current=!0;let t=e.currentTarget;t.textContent=(t.textContent||``).replace(/\D/g,``),i.Focus({target:e.currentTarget})},R=e=>{if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`v`||e.key===`Backspace`)return;let t=(e.currentTarget.textContent??``).replace(/\D/g,``).length;P>0&&t>=P&&e.key.length===1&&/\d/.test(e.key)&&e.preventDefault(),e.key===`Enter`&&e.preventDefault(),e.key.length===1&&!/\d/.test(e.key)&&!e.metaKey&&!e.ctrlKey&&e.preventDefault()},z=e=>{i.PasteDigits(P,a(e)),queueMicrotask(()=>{let e=M.current;if(!e)return;let t=(e.textContent||``).replace(/\D/g,``);P>0&&t.length>P&&(t=t.slice(0,P)),F(e,t),u&&p&&u.onValue({value:t,name:p})})},B=e=>{e.preventDefault()},V=e=>{i.Blur(e);let t=(e.currentTarget.textContent||``).replace(/\D/g,``);e.currentTarget.textContent!==t&&(e.currentTarget.textContent=t),v?.({value:t,name:p}),N.current=!1},H={};return O&&(H.edit=``),H.inputMode=w??`numeric`,m&&(H.placeholder=m),g&&o(k)?null:l(t,{type:`numeric`,label:h,error:S,size:C,element_blok:{className:[y||``]},element_input:{className:[e.w]},children:[x?c(`span`,{className:e.affix,children:x}):null,c(d,{divRef:M,editable:O,label:h,placeholder:m,dd:H,onPaste:z,onDrop:B,onInput:I,onFocus:L,onBlur:V,onKeyDown:R}),b?c(`span`,{className:e.affix,children:b}):null]})}function d({divRef:e,editable:t,label:r,placeholder:i,dd:a,onPaste:o,onDrop:s,onInput:l,onFocus:u,onBlur:d,onKeyDown:f}){let p=n();return c(`div`,{ref:e,id:p?.controlId,onPaste:o,onDrop:s,onDragOver:e=>e.preventDefault(),onInput:l,onFocus:u,onBlur:d,onKeyDown:f,spellCheck:!1,role:`textbox`,"aria-multiline":`false`,tabIndex:t?0:-1,"aria-label":r?void 0:i||`Число`,"aria-describedby":p?.describedBy,"aria-invalid":p?.errorId?!0:void 0,contentEditable:t?`plaintext-only`:!1,suppressContentEditableWarning:!0,...a})}u.displayName=`NumberField`;export{u as default};
@@ -1,69 +1 @@
1
- import e from "../styles/Field.module.js";
2
- import t from "../core/Field.js";
3
- import { useFormFieldState as n } from "../hooks/use.js";
4
- import { useFormInit as r } from "../FormInitContext.js";
5
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
6
- //#region src/lib/fields/Options.tsx
7
- var s = (e, t = ",") => (e !== void 0 && e !== "" ? e.split(t) : []).filter((e) => e !== "").reduce((e, t) => (e[t] = !0, e), {});
8
- function c({ value: c, form: l, onValue: u, name: d, placeholder: f = "", separator: p = ",", label: m, error: h, hidden: g = !1, disabled: _ = !1, outFormat: v = "object", after: y, before: b, modal: x, options: S, className: C }) {
9
- let { onModal: w } = r(), { value: T } = n(l, d, c), E = T, D = typeof E == "string" ? s(E, p) : E && typeof E == "object" ? E : {}, O = () => {
10
- if (_) return;
11
- if (!x) return console.error("modal - empty");
12
- let e = x.split(".");
13
- w({
14
- module: e[0],
15
- modalName: e[1],
16
- callback: (e) => {
17
- let t = e;
18
- if (u) switch (v === "array" || v === "string" && Object.keys(t).filter((e) => t[e]).join(p), v) {
19
- case "array":
20
- u !== l?.onValue && u({
21
- value: Object.keys(t),
22
- name: d
23
- });
24
- break;
25
- case "string":
26
- u !== l?.onValue && u({
27
- value: Object.keys(t).filter((e) => t[e]).join(p),
28
- name: d
29
- });
30
- break;
31
- default: u !== l?.onValue && u({
32
- value: t,
33
- name: d
34
- });
35
- }
36
- },
37
- onValue: u,
38
- options: S,
39
- fieldName: d,
40
- value: D
41
- });
42
- }, k = {};
43
- f && (k.placeholder = f);
44
- let A = Object.keys(D).length === 0;
45
- return g && A ? /* @__PURE__ */ a(i, {}) : /* @__PURE__ */ o(t, {
46
- type: "group",
47
- label: m,
48
- error: h,
49
- element_blok: { className: [C || ""] },
50
- element_input: {
51
- className: [e.g],
52
- props: { onClick: O }
53
- },
54
- children: [
55
- b ? /* @__PURE__ */ a("span", {
56
- className: e.affix,
57
- children: b
58
- }) : null,
59
- Object.keys(D).map((e) => /* @__PURE__ */ a("div", { children: S?.[e]?.label }, e)),
60
- y ? /* @__PURE__ */ a("span", {
61
- className: e.affix,
62
- children: y
63
- }) : null
64
- ]
65
- });
66
- }
67
- c.displayName = "OptionsField";
68
- //#endregion
69
- export { c as default };
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{useFormInit as r}from"../FormInitContext.js";import{Fragment as i,jsx as a,jsxs as o}from"react/jsx-runtime";var s=(e,t=`,`)=>(e!==void 0&&e!==``?e.split(t):[]).filter(e=>e!==``).reduce((e,t)=>(e[t]=!0,e),{});function c({value:c,form:l,onValue:u,name:d,placeholder:f=``,separator:p=`,`,label:m,error:h,hidden:g=!1,disabled:_=!1,outFormat:v=`object`,after:y,before:b,modal:x,options:S,className:C}){let{onModal:w}=r(),{value:T}=n(l,d,c),E=T,D=typeof E==`string`?s(E,p):E&&typeof E==`object`?E:{},O=()=>{if(_||!x)return;let e=x.split(`.`);w({module:e[0],modalName:e[1],callback:e=>{let t=e;if(u)switch(v===`array`||v===`string`&&Object.keys(t).filter(e=>t[e]).join(p),v){case`array`:u!==l?.onValue&&u({value:Object.keys(t),name:d});break;case`string`:u!==l?.onValue&&u({value:Object.keys(t).filter(e=>t[e]).join(p),name:d});break;default:u!==l?.onValue&&u({value:t,name:d})}},onValue:u,options:S,fieldName:d,value:D})},k={};f&&(k.placeholder=f);let A=Object.keys(D).length===0;return g&&A?a(i,{}):o(t,{type:`group`,label:m,error:h,element_blok:{className:[C||``]},element_input:{className:[e.g],props:{onClick:O}},children:[b?a(`span`,{className:e.affix,children:b}):null,Object.keys(D).map(e=>a(`div`,{children:S?.[e]?.label},e)),y?a(`span`,{className:e.affix,children:y}):null]})}c.displayName=`OptionsField`;export{c as default};
@@ -1,5 +1,5 @@
1
1
  import { TPasswordField } from './type';
2
- declare function PasswordField({ value, form, onValue, name, placeholder, label, error, hidden, disabled, onBlur: onBlurField, className, after, before, native, maxLength, eyes, }: TPasswordField): import("react/jsx-runtime").JSX.Element | "";
2
+ declare function PasswordField({ value, form, onValue, name, placeholder, label, error, hidden, disabled, onBlur: onBlurField, className, after, before, native, maxLength, eyes, id, size, }: TPasswordField): import("react/jsx-runtime").JSX.Element | "";
3
3
  declare namespace PasswordField {
4
4
  var displayName: string;
5
5
  }