@elcrm/form 0.0.79 → 0.0.81

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 (40) hide show
  1. package/dist/assets/styles/Color.module.css +1 -1
  2. package/dist/assets/styles/Field.module.css +1 -1
  3. package/dist/core/Field.js +1 -1
  4. package/dist/fields/Code.d.ts +14 -0
  5. package/dist/fields/Code.js +94 -0
  6. package/dist/fields/Color.js +133 -91
  7. package/dist/fields/Date.js +132 -77
  8. package/dist/fields/Display.d.ts +17 -0
  9. package/dist/fields/Display.js +49 -0
  10. package/dist/fields/DragDrop.d.ts +26 -0
  11. package/dist/fields/DragDrop.js +189 -0
  12. package/dist/fields/Email.d.ts +8 -0
  13. package/dist/fields/Email.js +80 -0
  14. package/dist/fields/File.d.ts +24 -0
  15. package/dist/fields/File.js +115 -0
  16. package/dist/fields/Hidden.d.ts +11 -0
  17. package/dist/fields/Hidden.js +33 -0
  18. package/dist/fields/Numeric.js +42 -24
  19. package/dist/fields/Percent.d.ts +13 -0
  20. package/dist/fields/Percent.js +100 -0
  21. package/dist/fields/Radio.d.ts +22 -0
  22. package/dist/fields/Radio.js +88 -0
  23. package/dist/fields/Rating.d.ts +12 -0
  24. package/dist/fields/Rating.js +82 -0
  25. package/dist/fields/RichText.d.ts +14 -0
  26. package/dist/fields/RichText.js +134 -0
  27. package/dist/fields/Tags.d.ts +12 -0
  28. package/dist/fields/Tags.js +97 -0
  29. package/dist/fields/Time.d.ts +8 -1
  30. package/dist/fields/Time.js +330 -156
  31. package/dist/fields/Url.d.ts +8 -0
  32. package/dist/fields/Url.js +80 -0
  33. package/dist/index.d.ts +27 -0
  34. package/dist/index.js +18 -6
  35. package/dist/index.umd.js +2 -2
  36. package/dist/package.js +1 -1
  37. package/dist/style.css +2 -2
  38. package/dist/styles/Color.module.js +23 -23
  39. package/dist/styles/Field.module.js +72 -24
  40. package/package.json +1 -1
@@ -29,8 +29,34 @@ function p(e, t, n) {
29
29
  }
30
30
  return r;
31
31
  }
32
- function m({ label: i = "", error: d, hidden: f = !1, className: p, placeholder: m, disabled: g = !1, onValue: _, max: v, min: b, form: x, icon: S, name: C = "", value: w, after: T = "", before: E = "" }) {
33
- let D = a.useCallback((e) => {
32
+ function m(e) {
33
+ if (!(e instanceof HTMLElement)) return !1;
34
+ let t = e.tagName;
35
+ return t === "INPUT" || t === "TEXTAREA" || t === "SELECT" ? !0 : !!e.isContentEditable;
36
+ }
37
+ function h(e) {
38
+ let t = (e || "").trim();
39
+ if (!t) return null;
40
+ let n = t.split(/\s+/)[0].replace(/,/g, "."), r = (e, t, n) => {
41
+ if (t < 1 || t > 12 || n < 1 || n > 31) return null;
42
+ let r = e < 100 ? 2e3 + e : e, i = new Date(r, t - 1, n);
43
+ return Number.isNaN(i.getTime()) || i.getFullYear() !== r || i.getMonth() !== t - 1 || i.getDate() !== n ? null : i;
44
+ }, i = /^(\d{1,2})[./](\d{1,2})[./](\d{2,4})$/.exec(n);
45
+ if (i) return r(parseInt(i[3], 10), parseInt(i[2], 10), parseInt(i[1], 10));
46
+ if (i = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(n), i) return r(parseInt(i[1], 10), parseInt(i[2], 10), parseInt(i[3], 10));
47
+ if (i = /^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/.exec(n), i) return r(parseInt(i[3], 10), parseInt(i[2], 10), parseInt(i[1], 10));
48
+ let a = n.replace(/\D/g, "");
49
+ return a.length === 8 ? r(parseInt(a.slice(4, 8), 10), parseInt(a.slice(2, 4), 10), parseInt(a.slice(0, 2), 10)) || r(parseInt(a.slice(0, 4), 10), parseInt(a.slice(4, 6), 10), parseInt(a.slice(6, 8), 10)) : null;
50
+ }
51
+ function g(e, t, n) {
52
+ let r = e.getTime();
53
+ return t && r < t.getTime() && (r = t.getTime()), n && r > n.getTime() && (r = n.getTime()), new Date(r);
54
+ }
55
+ function _(e) {
56
+ return e.getFullYear() + "-" + S(2, e.getMonth() + 1) + "-" + S(2, e.getDate());
57
+ }
58
+ function v({ label: i = "", error: d, hidden: f = !1, className: p, placeholder: v, disabled: b = !1, onValue: x, max: S, min: w, form: T, icon: E, name: D = "", value: O, after: k = "", before: A = "" }) {
59
+ let j = a.useCallback((e) => {
34
60
  if (e == null || typeof e == "string" && r(e)) return "";
35
61
  if (e instanceof Date) return Number.isNaN(e.getTime()) ? "" : e;
36
62
  if (typeof e == "string" || typeof e == "number") {
@@ -38,106 +64,135 @@ function m({ label: i = "", error: d, hidden: f = !1, className: p, placeholder:
38
64
  return Number.isNaN(t.getTime()) ? "" : e;
39
65
  }
40
66
  return "";
41
- }, []), { value: O } = n(x, C, w), [k, A] = a.useState(D(O)), j = a.useRef(null), [M, N] = a.useState(null), [P, F] = a.useState(!1), I = a.useCallback(() => {
42
- let e = j.current;
67
+ }, []), { value: M } = n(T, D, O), [N, P] = a.useState(j(M)), F = a.useRef(null), [I, L] = a.useState(null), [R, z] = a.useState(!1), B = a.useCallback(() => {
68
+ let e = F.current;
43
69
  if (!e) return;
44
70
  let t = e.getBoundingClientRect();
45
- N({
71
+ L({
46
72
  x: t.left,
47
73
  y: t.top,
48
74
  b: t.bottom
49
75
  });
50
76
  }, []);
51
77
  a.useEffect(() => {
52
- if (!P) return;
53
- I();
78
+ if (!R) return;
79
+ B();
54
80
  let e = () => {
55
- I();
81
+ B();
56
82
  };
57
83
  return window.addEventListener("scroll", e, !0), window.addEventListener("resize", e), () => {
58
84
  window.removeEventListener("scroll", e, !0), window.removeEventListener("resize", e);
59
85
  };
60
- }, [P, I]), a.useEffect(() => {
61
- A(D(O));
62
- }, [O, D]);
63
- let L = (e) => {
86
+ }, [R, B]), a.useEffect(() => {
87
+ P(j(M));
88
+ }, [M, j]);
89
+ let V = a.useCallback((e) => {
64
90
  let t = {
65
91
  value: e,
66
- name: C
92
+ name: D
67
93
  };
68
- A(e), x && C && x.setValue(t), _ && _ !== x?.onValue && _(t);
69
- }, R = (e) => {
70
- if (g) return;
94
+ P(e), T && D && T.setValue(t), x && x !== T?.onValue && x(t);
95
+ }, [
96
+ T,
97
+ D,
98
+ x
99
+ ]);
100
+ a.useEffect(() => {
101
+ if (!R || b) return;
102
+ let e = "", t = (t) => {
103
+ let n = h(t);
104
+ if (!n) return !1;
105
+ let r = _(g(n, w, S));
106
+ return r === e ? !0 : (e = r, V(r), z(!1), !0);
107
+ }, n = (e) => {
108
+ m(e.target) || t(e.clipboardData?.getData("text/plain") ?? "") && (e.preventDefault(), e.stopPropagation());
109
+ }, r = (e) => {
110
+ (e.ctrlKey || e.metaKey) && (e.key !== "v" && e.key !== "V" || m(e.target) || navigator.clipboard?.readText && (e.preventDefault(), navigator.clipboard.readText().then((e) => {
111
+ t(e);
112
+ })));
113
+ };
114
+ return document.addEventListener("paste", n, !0), window.addEventListener("keydown", r, !0), () => {
115
+ document.removeEventListener("paste", n, !0), window.removeEventListener("keydown", r, !0);
116
+ };
117
+ }, [
118
+ R,
119
+ b,
120
+ w,
121
+ S,
122
+ V
123
+ ]);
124
+ let H = (e) => {
125
+ if (b) return;
71
126
  let t = e.currentTarget.getBoundingClientRect();
72
- N({
127
+ L({
73
128
  x: t.left,
74
129
  y: t.top,
75
130
  b: t.bottom
76
- }), F(!0);
77
- }, z = {};
78
- m && (z.placeholder = m);
79
- let B = O == null || O === "" || typeof O == "string" && r(O);
80
- return f && B ? /* @__PURE__ */ s(o, {}) : /* @__PURE__ */ c(o, { children: [S ? S() : /* @__PURE__ */ c(t, {
131
+ }), z(!0);
132
+ }, U = {};
133
+ v && (U.placeholder = v);
134
+ let W = M == null || M === "" || typeof M == "string" && r(M);
135
+ return f && W ? /* @__PURE__ */ s(o, {}) : /* @__PURE__ */ c(o, { children: [E ? E() : /* @__PURE__ */ c(t, {
81
136
  type: "date",
82
137
  label: i,
83
138
  error: d,
84
139
  element_blok: { className: [p || ""] },
85
140
  element_input: {
86
141
  className: [e.w],
87
- props: { "data-disabled": g ? "true" : void 0 }
142
+ props: { "data-disabled": b ? "true" : void 0 }
88
143
  },
89
144
  children: [
90
- E ? /* @__PURE__ */ s("span", {
145
+ A ? /* @__PURE__ */ s("span", {
91
146
  className: e.affix,
92
- children: E
147
+ children: A
93
148
  }) : null,
94
149
  /* @__PURE__ */ s("div", {
95
- ref: j,
96
- onClick: R,
150
+ ref: F,
151
+ onClick: H,
97
152
  onKeyDown: (e) => {
98
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), R(e));
153
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), H(e));
99
154
  },
100
- tabIndex: g ? -1 : 0,
155
+ tabIndex: b ? -1 : 0,
101
156
  role: "button",
102
157
  "aria-haspopup": "dialog",
103
- "aria-expanded": P,
104
- "aria-label": i || m || "Дата",
105
- "data-edit": g ? void 0 : "true",
106
- ...z,
107
- style: { cursor: g ? "not-allowed" : "pointer" },
108
- children: u(k) ? "" : y(k, "dd.mm.yyyy")
158
+ "aria-expanded": R,
159
+ "aria-label": i || v || "Дата",
160
+ "data-edit": b ? void 0 : "true",
161
+ ...U,
162
+ style: { cursor: b ? "not-allowed" : "pointer" },
163
+ children: u(N) ? "" : C(N, "dd.mm.yyyy")
109
164
  }),
110
- T ? /* @__PURE__ */ s("span", {
165
+ k ? /* @__PURE__ */ s("span", {
111
166
  className: e.affix,
112
- children: T
167
+ children: k
113
168
  }) : null
114
169
  ]
115
- }), P && M && l(/* @__PURE__ */ s(h, {
116
- position: M,
117
- onValue: L,
118
- date: k,
119
- max: v,
120
- min: b,
121
- onOpen: F,
170
+ }), R && I && l(/* @__PURE__ */ s(y, {
171
+ position: I,
172
+ onValue: V,
173
+ date: N,
174
+ max: S,
175
+ min: w,
176
+ onOpen: z,
122
177
  className: p
123
178
  }, "elcrm-date-popup"), document.body)] });
124
179
  }
125
- m.displayName = "DateField";
126
- var h = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpen: m }) => {
180
+ v.displayName = "DateField";
181
+ var y = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpen: m }) => {
127
182
  let h = /* @__PURE__ */ new Date(), g = new Date(e);
128
183
  Number.isNaN(g.getTime()) && (g = /* @__PURE__ */ new Date());
129
- let y = {
184
+ let _ = {
130
185
  y: h.getFullYear(),
131
186
  d: h.getDate(),
132
187
  m: h.getMonth() + 1
133
- }, b = {
188
+ }, v = {
134
189
  y: g.getFullYear(),
135
190
  d: g.getDate(),
136
191
  m: g.getMonth() + 1
137
- }, [x, S] = a.useState({
138
- y: b.y,
139
- m: b.m
140
- }), [C, w] = a.useState("days"), [T, E] = a.useState(() => p(b.y - 5, l, r)), D = (e) => {
192
+ }, [y, b] = a.useState({
193
+ y: v.y,
194
+ m: v.m
195
+ }), [C, w] = a.useState("days"), [T, E] = a.useState(() => p(v.y - 5, l, r)), D = (e) => {
141
196
  let t = e.getDay();
142
197
  return t === 0 && (t = 7), t - 1;
143
198
  }, O = [
@@ -148,41 +203,41 @@ var h = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpe
148
203
  "пт",
149
204
  "сб",
150
205
  "вс"
151
- ], k = x.m - 1, A = new Date(x.y, k), j = [];
206
+ ], k = y.m - 1, A = new Date(y.y, k), j = [];
152
207
  for (let e = 0; e < D(A); e++) j.push(0);
153
208
  for (; A.getMonth() === k;) j.push(A.getDate()), A.setDate(A.getDate() + 1);
154
209
  let M = () => {
155
210
  m(!1);
156
211
  }, N = () => {
157
- V(x.m + 1, x.y);
212
+ V(y.m + 1, y.y);
158
213
  }, P = () => {
159
- V(x.m - 1, x.y);
214
+ V(y.m - 1, y.y);
160
215
  }, F = () => {
161
- C === "days" ? P() : C === "months" ? V(x.m, x.y - 1) : E((e) => p(e - 12, l, r));
216
+ C === "days" ? P() : C === "months" ? V(y.m, y.y - 1) : E((e) => p(e - 12, l, r));
162
217
  }, I = () => {
163
- C === "days" ? N() : C === "months" ? V(x.m, x.y + 1) : E((e) => p(e + 12, l, r));
218
+ C === "days" ? N() : C === "months" ? V(y.m, y.y + 1) : E((e) => p(e + 12, l, r));
164
219
  }, L = (e) => {
165
- e.stopPropagation(), E(p(x.y - 5, l, r)), w("years");
220
+ e.stopPropagation(), E(p(y.y - 5, l, r)), w("years");
166
221
  }, R = (e) => {
167
- d(x.y, e, l, r) && (S({
168
- y: x.y,
222
+ d(y.y, e, l, r) && (b({
223
+ y: y.y,
169
224
  m: e
170
225
  }), w("days"));
171
226
  }, z = (e) => {
172
- f(e, l, r) && (S({
227
+ f(e, l, r) && (b({
173
228
  y: e,
174
- m: x.m
229
+ m: y.m
175
230
  }), w("days"));
176
231
  }, B = (e) => {
177
- t(x.y + "-" + v(2, x.m) + "-" + v(2, e)), M();
232
+ t(y.y + "-" + S(2, y.m) + "-" + S(2, e)), M();
178
233
  }, V = (e, t) => {
179
- t = e > 12 ? t + 1 : e < 1 ? t - 1 : t, e = e > 12 ? 1 : e < 1 ? 12 : e, S({
234
+ t = e > 12 ? t + 1 : e < 1 ? t - 1 : t, e = e > 12 ? 1 : e < 1 ? 12 : e, b({
180
235
  y: t,
181
236
  m: e
182
237
  });
183
- }, H = (e) => y.y === x.y && y.m === x.m && y.d === e ? { "data-active": "true" } : {}, U = (e) => b.y === x.y && b.m === x.m && b.d === e ? { "data-current": "true" } : {}, W = (e) => {
238
+ }, H = (e) => _.y === y.y && _.m === y.m && _.d === e ? { "data-active": "true" } : {}, U = (e) => v.y === y.y && v.m === y.m && v.d === e ? { "data-current": "true" } : {}, W = (e) => {
184
239
  let t = !0;
185
- return r && r.getTime() < new Date(x.y, x.m - 1, e).getTime() && (t = !1), l && l.getTime() > new Date(x.y, x.m - 1, e).getTime() && (t = !1), t;
240
+ return r && r.getTime() < new Date(y.y, y.m - 1, e).getTime() && (t = !1), l && l.getTime() > new Date(y.y, y.m - 1, e).getTime() && (t = !1), t;
186
241
  }, G = window.innerHeight - n.b < 360 ? Math.max(8, n.y - 360) : n.b;
187
242
  G = Math.min(G, window.innerHeight - 360 - 8), G = Math.max(8, G);
188
243
  let K = window.innerWidth - n.x < 270 ? n.x - 246 : n.x;
@@ -217,14 +272,14 @@ var h = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpe
217
272
  e.stopPropagation(), w(C === "years" ? "months" : C === "months" ? "days" : "months");
218
273
  },
219
274
  title: C === "years" ? "К списку месяцев" : C === "months" ? "К календарю" : "Выбрать месяц",
220
- children: _(x.m).name
275
+ children: x(y.m).name
221
276
  }), /* @__PURE__ */ s("span", {
222
277
  className: i.dateHeaderYear,
223
278
  onClick: (e) => {
224
279
  e.stopPropagation(), C === "years" ? w("days") : L(e);
225
280
  },
226
281
  title: C === "years" ? "К календарю" : "Выбрать год",
227
- children: x.y
282
+ children: y.y
228
283
  })] }),
229
284
  /* @__PURE__ */ s("i", {
230
285
  onClick: (e) => {
@@ -256,20 +311,20 @@ var h = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpe
256
311
  C === "months" && /* @__PURE__ */ s("div", {
257
312
  "grid-month": "",
258
313
  children: Array.from({ length: 12 }, (e, t) => {
259
- let n = t + 1, a = d(x.y, n, l, r), o = y.y === x.y && y.m === n ? { "data-active": "true" } : {}, c = b.y === x.y && b.m === n ? { "data-current": "true" } : {};
314
+ let n = t + 1, a = d(y.y, n, l, r), o = _.y === y.y && _.m === n ? { "data-active": "true" } : {}, c = v.y === y.y && v.m === n ? { "data-current": "true" } : {};
260
315
  return /* @__PURE__ */ s("b", {
261
316
  className: a ? "" : i.dateHeaderDisabled,
262
317
  ...o,
263
318
  ...c,
264
319
  onClick: () => a && R(n),
265
- children: _(n).abc
320
+ children: x(n).abc
266
321
  }, n);
267
322
  })
268
323
  }),
269
324
  C === "years" && /* @__PURE__ */ s("div", {
270
325
  "grid-month": "",
271
326
  children: Array.from({ length: 12 }, (e, t) => {
272
- let n = T + t, a = f(n, l, r), o = y.y === n ? { "data-active": "true" } : {}, c = b.y === n ? { "data-current": "true" } : {};
327
+ let n = T + t, a = f(n, l, r), o = _.y === n ? { "data-active": "true" } : {}, c = v.y === n ? { "data-current": "true" } : {};
273
328
  return /* @__PURE__ */ s("b", {
274
329
  className: a ? "" : i.dateHeaderDisabled,
275
330
  ...o,
@@ -281,13 +336,13 @@ var h = ({ date: e, onValue: t, position: n, max: r, min: l, className: u, onOpe
281
336
  })
282
337
  ]
283
338
  })] });
284
- }, g = {
339
+ }, b = {
285
340
  val: "01",
286
341
  name: "—",
287
342
  names: "—",
288
343
  abc: "—"
289
344
  };
290
- function _(e) {
345
+ function x(e) {
291
346
  let t = typeof e == "number" ? e : new Date(e).getMonth() + 1;
292
347
  return (!Number.isFinite(t) || t < 1 || t > 12) && (t = (/* @__PURE__ */ new Date()).getMonth() + 1), {
293
348
  1: {
@@ -362,14 +417,14 @@ function _(e) {
362
417
  names: "Декабря",
363
418
  abc: "Дек"
364
419
  }
365
- }[t] ?? g;
420
+ }[t] ?? b;
366
421
  }
367
- function v(e, t) {
422
+ function S(e, t) {
368
423
  let n = t + "";
369
424
  for (; n.length < e;) n = "0" + n;
370
425
  return n;
371
426
  }
372
- function y(e, t) {
427
+ function C(e, t) {
373
428
  let n, r;
374
429
  t === void 0 ? (r = String(e), n = /* @__PURE__ */ new Date()) : (r = t, n = new Date(e)), Number.isNaN(n.getTime()) && (n = /* @__PURE__ */ new Date());
375
430
  let i = r, a = {
@@ -387,4 +442,4 @@ function y(e, t) {
387
442
  return i;
388
443
  }
389
444
  //#endregion
390
- export { m as default };
445
+ export { v as default };
@@ -0,0 +1,17 @@
1
+ import { TInput } from './type';
2
+ /**
3
+ * DisplayField (Readonly) — только отображение значения в layout поля.
4
+ * Не принимает ввод; удобно для превью / рассчитанных полей.
5
+ */
6
+ export type TDisplay = TInput & {
7
+ /** Форматтер отображаемого текста */
8
+ format?: (value: unknown) => string;
9
+ emptyText?: string;
10
+ };
11
+ declare function DisplayField({ value, form, name, placeholder, label, error, hidden, className, after, before, format, emptyText, }: TDisplay): import("react/jsx-runtime").JSX.Element | null;
12
+ declare namespace DisplayField {
13
+ var displayName: string;
14
+ }
15
+ /** @deprecated используйте `DisplayField` */
16
+ export { DisplayField as ReadonlyField };
17
+ export default DisplayField;
@@ -0,0 +1,49 @@
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 "react";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ //#region src/lib/fields/Display.tsx
8
+ function o(e) {
9
+ if (e == null) return "";
10
+ if (typeof e == "string") return e;
11
+ if (typeof e == "number" || typeof e == "boolean") return String(e);
12
+ if (Array.isArray(e)) return e.map(String).join(", ");
13
+ try {
14
+ return JSON.stringify(e);
15
+ } catch {
16
+ return String(e);
17
+ }
18
+ }
19
+ function s({ value: s = "", form: c, name: l = "", placeholder: u = "", label: d = "", error: f = "", hidden: p = !1, className: m = "", after: h = "", before: g = "", format: _ = o, emptyText: v }) {
20
+ let { value: y } = n(c, l, s), b = _(y), x = !b.trim(), S = x ? v || u || "—" : b;
21
+ return p && r(y) ? null : /* @__PURE__ */ a(t, {
22
+ type: "display",
23
+ label: d,
24
+ error: f,
25
+ element_blok: { className: [m || ""] },
26
+ element_input: {
27
+ className: [e.w, e.display],
28
+ props: { "data-readonly": "true" }
29
+ },
30
+ children: [
31
+ g ? /* @__PURE__ */ i("span", {
32
+ className: e.affix,
33
+ children: g
34
+ }) : null,
35
+ /* @__PURE__ */ i("div", {
36
+ className: x ? e.displayEmpty : void 0,
37
+ "aria-label": d || "Значение",
38
+ children: S
39
+ }),
40
+ h ? /* @__PURE__ */ i("span", {
41
+ className: e.affix,
42
+ children: h
43
+ }) : null
44
+ ]
45
+ });
46
+ }
47
+ s.displayName = "DisplayField";
48
+ //#endregion
49
+ export { s as default };
@@ -0,0 +1,26 @@
1
+ import { TInput } from './type';
2
+ /** DragDropField — зона перетаскивания файлов (+ клик для выбора). */
3
+ export type TDragDrop = TInput & {
4
+ accept?: string;
5
+ multiple?: boolean;
6
+ /** Макс. размер одного файла, байт */
7
+ maxSize?: number;
8
+ /** Лимит числа файлов при `multiple` */
9
+ maxFiles?: number;
10
+ /**
11
+ * Если true — в форму пишутся `File` / `File[]`.
12
+ * Иначе — метаданные `TFileMeta` / `TFileMeta[]`.
13
+ */
14
+ keepFile?: boolean;
15
+ /** Подсказка в зоне (по умолчанию — placeholder) */
16
+ hint?: string;
17
+ /** Дописывать к уже выбранным при multiple (по умолчанию true) */
18
+ append?: boolean;
19
+ };
20
+ declare function DragDropField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, accept, multiple, maxSize, maxFiles, keepFile, hint, append, }: TDragDrop): import("react/jsx-runtime").JSX.Element | null;
21
+ declare namespace DragDropField {
22
+ var displayName: string;
23
+ }
24
+ /** Алиас на случай опечатки «DragonDrop» */
25
+ export { DragDropField as DragonDropField };
26
+ export default DragDropField;
@@ -0,0 +1,189 @@
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 from "react";
5
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ //#region src/lib/fields/DragDrop.tsx
7
+ function o(e) {
8
+ return {
9
+ name: e.name,
10
+ size: e.size,
11
+ type: e.type,
12
+ lastModified: e.lastModified
13
+ };
14
+ }
15
+ function s(e) {
16
+ return typeof File < "u" && e instanceof File ? o(e) : e;
17
+ }
18
+ function c(e) {
19
+ return e ? Array.isArray(e) ? e : typeof File < "u" && e instanceof File || typeof e == "object" && e && "name" in e ? [e] : [] : [];
20
+ }
21
+ function l(e) {
22
+ return e < 1024 ? `${e} Б` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} КБ` : `${(e / (1024 * 1024)).toFixed(1)} МБ`;
23
+ }
24
+ function u(e, t) {
25
+ if (!t || !t.trim()) return !0;
26
+ let n = t.split(",").map((e) => e.trim().toLowerCase()).filter(Boolean);
27
+ if (n.length === 0) return !0;
28
+ let r = e.name.toLowerCase(), i = (e.type || "").toLowerCase();
29
+ return n.some((e) => {
30
+ if (e.startsWith(".")) return r.endsWith(e);
31
+ if (e.endsWith("/*")) {
32
+ let t = e.slice(0, -1);
33
+ return i.startsWith(t);
34
+ }
35
+ return i === e;
36
+ });
37
+ }
38
+ function d(e) {
39
+ return `${e.name}:${e.size}`;
40
+ }
41
+ function f({ value: f, form: p, onValue: m, onBlur: h, name: g = "", placeholder: _ = "Перетащите файлы сюда или нажмите", label: v = "", error: y = "", hidden: b = !1, disabled: x = !1, className: S = "", after: C = "", before: w = "", accept: T, multiple: E = !0, maxSize: D, maxFiles: O, keepFile: k = !0, hint: A, append: j = !0 }) {
42
+ let { value: M } = n(p, g, f), N = c(M), P = !x, F = r.useRef(null), [I, L] = r.useState(""), [R, z] = r.useState(!1), B = r.useRef(0), V = (e) => {
43
+ let t = {
44
+ value: e,
45
+ name: g
46
+ };
47
+ p && g && p.setValue(t), m && m !== p?.onValue && m(t);
48
+ }, H = (e) => {
49
+ if (e.length === 0) return;
50
+ let t = e.filter((e) => !u(e, T));
51
+ if (t.length > 0) {
52
+ L(`Тип файла не подходит: ${t.map((e) => e.name).join(", ")}`);
53
+ return;
54
+ }
55
+ if (D !== void 0) {
56
+ let t = e.find((e) => e.size > D);
57
+ if (t) {
58
+ L(`Файл «${t.name}» больше ${l(D)}`);
59
+ return;
60
+ }
61
+ }
62
+ let n;
63
+ if (!E) n = [e[0]];
64
+ else if (j && N.length > 0) {
65
+ let t = new Set(N.map((e) => d(e))), r = e.filter((e) => !t.has(d(e))), i = N.filter((e) => typeof File < "u" && e instanceof File);
66
+ n = k && i.length === N.length ? [...i, ...r] : [...e];
67
+ } else n = e;
68
+ if (O !== void 0 && n.length > O) {
69
+ L(`Не больше ${O} файлов`);
70
+ return;
71
+ }
72
+ L("");
73
+ let r = k ? E ? n : n[0] : E ? n.map(o) : o(n[0]);
74
+ V(r), h?.({
75
+ value: r,
76
+ name: g
77
+ });
78
+ }, U = () => {
79
+ P && (V(E ? [] : null), F.current && (F.current.value = ""), L(""));
80
+ }, W = (e) => {
81
+ if (!P) return;
82
+ if (!E) {
83
+ U();
84
+ return;
85
+ }
86
+ let t = N.filter((t, n) => n !== e);
87
+ V(k ? t : t.map(s)), F.current && (F.current.value = "");
88
+ }, G = (e) => {
89
+ e.preventDefault(), e.stopPropagation(), P && (B.current += 1, z(!0));
90
+ }, K = (e) => {
91
+ e.preventDefault(), e.stopPropagation(), --B.current, B.current <= 0 && (B.current = 0, z(!1));
92
+ }, q = (e) => {
93
+ e.preventDefault(), e.stopPropagation(), e.dataTransfer && (e.dataTransfer.dropEffect = P ? "copy" : "none");
94
+ }, J = (e) => {
95
+ e.preventDefault(), e.stopPropagation(), B.current = 0, z(!1), P && H(Array.from(e.dataTransfer.files || []));
96
+ }, Y = N.length === 0;
97
+ if (b && Y) return null;
98
+ let X = y || I, Z = A || _;
99
+ return /* @__PURE__ */ a(t, {
100
+ type: "dragdrop",
101
+ label: v,
102
+ error: X,
103
+ element_blok: { className: [S || ""] },
104
+ element_input: {
105
+ className: [e.dragDrop],
106
+ props: {
107
+ "data-disabled": x || !P ? "true" : void 0,
108
+ "data-dragging": R ? "true" : void 0
109
+ }
110
+ },
111
+ children: [
112
+ w ? /* @__PURE__ */ i("span", {
113
+ className: e.affix,
114
+ children: w
115
+ }) : null,
116
+ /* @__PURE__ */ a("div", {
117
+ className: e.dragDropInner,
118
+ children: [
119
+ /* @__PURE__ */ i("input", {
120
+ ref: F,
121
+ type: "file",
122
+ className: e.fileInput,
123
+ accept: T,
124
+ multiple: E,
125
+ disabled: x || !P,
126
+ "aria-label": v || _ || "Файлы",
127
+ onChange: (e) => {
128
+ H(Array.from(e.target.files || [])), e.target.value = "";
129
+ }
130
+ }),
131
+ /* @__PURE__ */ a("button", {
132
+ type: "button",
133
+ className: e.dragDropZone,
134
+ disabled: !P,
135
+ "data-dragging": R ? "true" : void 0,
136
+ onClick: () => F.current?.click(),
137
+ onDragEnter: G,
138
+ onDragLeave: K,
139
+ onDragOver: q,
140
+ onDrop: J,
141
+ children: [/* @__PURE__ */ i("span", {
142
+ className: e.dragDropHint,
143
+ children: Z
144
+ }), T ? /* @__PURE__ */ i("span", {
145
+ className: e.dragDropAccept,
146
+ children: T
147
+ }) : null]
148
+ }),
149
+ Y ? null : /* @__PURE__ */ i("ul", {
150
+ className: e.dragDropList,
151
+ children: N.map((t, n) => /* @__PURE__ */ a("li", {
152
+ className: e.dragDropItem,
153
+ children: [/* @__PURE__ */ a("div", {
154
+ className: e.dragDropMeta,
155
+ children: [/* @__PURE__ */ i("span", {
156
+ className: e.dragDropName,
157
+ title: t.name,
158
+ children: t.name
159
+ }), /* @__PURE__ */ i("span", {
160
+ className: e.dragDropSize,
161
+ children: l(t.size)
162
+ })]
163
+ }), P ? /* @__PURE__ */ i("button", {
164
+ type: "button",
165
+ className: e.dragDropRemove,
166
+ "aria-label": `Удалить ${t.name}`,
167
+ onClick: () => W(n),
168
+ children: "×"
169
+ }) : null]
170
+ }, `${t.name}-${n}`))
171
+ }),
172
+ !Y && P ? /* @__PURE__ */ i("button", {
173
+ type: "button",
174
+ className: e.dragDropClearAll,
175
+ onClick: U,
176
+ children: "Очистить всё"
177
+ }) : null
178
+ ]
179
+ }),
180
+ C ? /* @__PURE__ */ i("span", {
181
+ className: e.affix,
182
+ children: C
183
+ }) : null
184
+ ]
185
+ });
186
+ }
187
+ f.displayName = "DragDropField";
188
+ //#endregion
189
+ export { f as default };
@@ -0,0 +1,8 @@
1
+ import { TInput } from './type';
2
+ /** EmailField — нативный input type=email (автозаполнение, мобильная клавиатура). */
3
+ export type TEmail = TInput;
4
+ declare function EmailField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxLength, autoComplete, id, }: TEmail): import("react/jsx-runtime").JSX.Element | null;
5
+ declare namespace EmailField {
6
+ var displayName: string;
7
+ }
8
+ export default EmailField;