@envisiongroup/porygon 1.0.0-rc.36 → 1.0.0-rc.37

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/react-components/commons/valueNormalization.d.ts +17 -0
  2. package/dist/react-components/commons/valueNormalization.js +7 -0
  3. package/dist/react-components/fields/Attachments/EFWAttachments.js +105 -79
  4. package/dist/react-components/fields/Attachments/EFWAttachments.types.d.ts +8 -1
  5. package/dist/react-components/fields/Attachments/EFWAttachmentsField.js +15 -13
  6. package/dist/react-components/fields/Attachments/index.d.ts +1 -1
  7. package/dist/react-components/fields/DatePicker/EFWDatePicker.js +69 -59
  8. package/dist/react-components/fields/DatePicker/EFWDatePicker.types.d.ts +11 -0
  9. package/dist/react-components/fields/DatePicker/EFWDatePickerField.js +152 -148
  10. package/dist/react-components/fields/DatePicker/index.d.ts +1 -1
  11. package/dist/react-components/fields/Input/EFWInput.js +92 -84
  12. package/dist/react-components/fields/Input/EFWInput.types.d.ts +15 -2
  13. package/dist/react-components/fields/Input/EFWInputField.js +28 -26
  14. package/dist/react-components/fields/Input/index.d.ts +1 -1
  15. package/dist/react-components/fields/NumberInput/EFWNumberInput.js +132 -124
  16. package/dist/react-components/fields/NumberInput/EFWNumberInput.types.d.ts +9 -2
  17. package/dist/react-components/fields/NumberInput/EFWNumberInputField.js +20 -18
  18. package/dist/react-components/fields/NumberInput/index.d.ts +1 -1
  19. package/dist/react-components/fields/Switch/EFWSwitch.js +45 -37
  20. package/dist/react-components/fields/Switch/EFWSwitch.types.d.ts +9 -1
  21. package/dist/react-components/fields/Switch/EFWSwitchField.js +21 -19
  22. package/dist/react-components/fields/Switch/EFWSwitchField.types.d.ts +4 -0
  23. package/dist/react-components/fields/Switch/index.d.ts +1 -1
  24. package/dist/react-components/fields/TagPicker/EFWTagPicker.js +115 -102
  25. package/dist/react-components/fields/TagPicker/EFWTagPicker.types.d.ts +7 -1
  26. package/dist/react-components/fields/TagPicker/EFWTagPickerField.js +22 -20
  27. package/dist/react-components/fields/TagPicker/index.d.ts +1 -1
  28. package/dist/react-components/fields/TextArea/EFWTextArea.js +89 -81
  29. package/dist/react-components/fields/TextArea/EFWTextArea.types.d.ts +15 -2
  30. package/dist/react-components/fields/TextArea/EFWTextAreaField.js +23 -21
  31. package/dist/react-components/fields/TextArea/index.d.ts +1 -1
  32. package/dist/react-components/fields/_shared/EFWField/EFWField.js +49 -49
  33. package/dist/react-components/forms/EFWForm/EFWForm.js +391 -293
  34. package/dist/react-components/forms/EFWForm/EFWForm.utils.js +154 -141
  35. package/dist/react-components/i18n/defaultLocaleText.js +23 -12
  36. package/dist/react-components/i18n/localePresets.js +55 -35
  37. package/dist/react-components/i18n/porygonI18n.types.d.ts +5 -3
  38. package/dist/react-components/tables/EFWTable/EFWTable.js +1 -1
  39. package/dist/react-components/tables/EFWTable/hooks/useDefaultFilterButton/useDefaultFilterButton.js +66 -60
  40. package/package.json +1 -1
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Normaliza valores textuales para mantener un contrato estable de render y callbacks.
3
+ */
4
+ export declare const normalizeTextValue: (value: string | null | undefined) => string;
5
+ /**
6
+ * Determina si un valor debe considerarse vacío para validaciones semánticas.
7
+ * Los strings compuestos solo por whitespace se consideran vacíos.
8
+ */
9
+ export declare const isSemanticallyEmptyValue: (value: unknown) => boolean;
10
+ /**
11
+ * Normaliza listas opcionales a arrays para evitar null checks repetidos.
12
+ */
13
+ export declare const normalizeArrayValue: <T>(value: T[] | null | undefined) => T[];
14
+ /**
15
+ * Normaliza booleanos opcionales a un fallback explícito.
16
+ */
17
+ export declare const normalizeBooleanValue: (value: boolean | null | undefined, fallback?: boolean) => boolean;
@@ -0,0 +1,7 @@
1
+ const n = (r) => r ?? "", e = (r) => r == null ? !0 : typeof r == "string" ? r.trim() === "" : Array.isArray(r) ? r.length === 0 : !1, i = (r) => Array.isArray(r) ? r : [], o = (r, t = !1) => r ?? t;
2
+ export {
3
+ e as isSemanticallyEmptyValue,
4
+ i as normalizeArrayValue,
5
+ o as normalizeBooleanValue,
6
+ n as normalizeTextValue
7
+ };
@@ -1,12 +1,14 @@
1
- import { jsxs as T, jsx as u } from "react/jsx-runtime";
2
- import { makeStyles as Q, mergeClasses as X, CardFooter as Y, Button as Z, Text as _ } from "@fluentui/react-components";
3
- import { useMemo as D, useId as ee, useRef as te, useState as ae, useEffect as $, useCallback as f } from "react";
4
- import { EFWAttachmentsContainer as ne } from "./EFWAttachmentsCard.js";
5
- import { Attach20Regular as oe } from "@fluentui/react-icons";
6
- import { formatFileSize as se } from "../../commons/utils.js";
7
- import { v4 as le } from "uuid";
8
- import { useFieldsLocaleText as ce } from "../../i18n/PorygonI18nProvider.js";
9
- const ie = Q({
1
+ import { jsx as s, jsxs as V } from "react/jsx-runtime";
2
+ import { makeStyles as _, mergeClasses as ee, Text as te, CardFooter as ae, Button as ne } from "@fluentui/react-components";
3
+ import { useMemo as $, useId as oe, useRef as se, useState as le, useEffect as j, useCallback as f } from "react";
4
+ import { EFWAttachmentsContainer as q } from "./EFWAttachmentsCard.js";
5
+ import { Attach20Regular as ce } from "@fluentui/react-icons";
6
+ import { formatFileSize as me } from "../../commons/utils.js";
7
+ import { v4 as re } from "uuid";
8
+ import { getAttachmentsFormattedValue as v } from "./EFWAttachments.utils.js";
9
+ import { normalizeArrayValue as O } from "../../commons/valueNormalization.js";
10
+ import { useFieldsLocaleText as ie } from "../../i18n/PorygonI18nProvider.js";
11
+ const de = _({
10
12
  efwAttachmentError: {
11
13
  //...
12
14
  },
@@ -19,76 +21,80 @@ const ie = Q({
19
21
  efwAttachmentsContainer: {
20
22
  display: "flex"
21
23
  }
22
- }), xe = (j) => {
24
+ }), Ae = (P) => {
23
25
  const {
24
- editable: h = !0,
25
- disabled: l = !1,
26
- files: F,
27
- defaultFiles: p,
28
- className: q = "",
29
- validationState: P = "none",
30
- setParentComponentState: M,
31
- multiple: b = !0,
32
- acceptedTypes: U = "*/*",
33
- maxFileSize: c = 100 * 1024 * 1024,
26
+ editable: U = !0,
27
+ disabled: c = !1,
28
+ files: L,
29
+ defaultFiles: h,
30
+ className: G = "",
31
+ validationState: H = "none",
32
+ setParentComponentState: p,
33
+ multiple: M = !0,
34
+ acceptedTypes: J = "*/*",
35
+ maxFileSize: m = 100 * 1024 * 1024,
34
36
  // 100MB por defecto
35
- labels: i,
36
- onChange: r,
37
- onRemoveAttachment: x
38
- } = j, m = ce().attachments.labels, A = m.attachButtonLabel, L = m.emptyMessage, v = m.downloadMenuItemLabel, E = m.removeMenuItemLabel, w = m.maxFileSizeExceededMessage, z = i?.attachButtonLabel, S = i?.emptyMessage, I = i?.downloadMenuItemLabel, C = i?.removeMenuItemLabel, R = i?.maxFileSizeExceededMessage, o = D(() => ({
39
- attachButtonLabel: z ?? A,
40
- emptyMessage: S ?? L,
41
- downloadMenuItemLabel: I ?? v,
37
+ labels: r,
38
+ onChange: i,
39
+ onRemoveAttachment: b,
40
+ readOnlyRenderer: K
41
+ } = P, d = ie().attachments.labels, A = d.attachButtonLabel, F = d.emptyMessage, w = d.downloadMenuItemLabel, E = d.removeMenuItemLabel, z = d.maxFileSizeExceededMessage, I = r?.attachButtonLabel, S = r?.emptyMessage, R = r?.downloadMenuItemLabel, C = r?.removeMenuItemLabel, B = r?.maxFileSizeExceededMessage, o = $(() => ({
42
+ attachButtonLabel: I ?? A,
43
+ emptyMessage: S ?? F,
44
+ downloadMenuItemLabel: R ?? w,
42
45
  removeMenuItemLabel: C ?? E,
43
- maxFileSizeExceededMessage: R ?? w
46
+ maxFileSizeExceededMessage: B ?? z
44
47
  }), [
45
- z,
46
- S,
47
48
  I,
48
- C,
49
+ S,
49
50
  R,
51
+ C,
52
+ B,
50
53
  A,
51
- L,
52
- v,
54
+ F,
55
+ w,
53
56
  E,
54
- w
55
- ]), V = ee(), g = ie(), d = te(null), s = F !== void 0, B = D(() => p ?? [], [p]), [G, y] = ae(() => p ?? []), n = s ? F ?? [] : G;
56
- $(() => {
57
- s || y(B);
58
- }, [s, B]);
57
+ z
58
+ ]), Q = oe(), g = de(), u = se(null), l = L !== void 0, N = $(() => h ?? [], [h]), [X, x] = le(() => h ?? []), n = l ? L ?? [] : X;
59
+ j(() => {
60
+ l || x(N);
61
+ }, [l, N]);
59
62
  const W = f((a) => {
60
63
  for (const e of a)
61
- if (e.size !== void 0 && e.size > c)
64
+ if (e.size !== void 0 && e.size > m)
62
65
  return !1;
63
66
  return !0;
64
- }, [c]), k = f(() => {
65
- const a = se(c), e = o.maxFileSizeExceededMessage;
66
- return typeof e == "function" ? e(c, a) : typeof e == "string" && e.trim().length > 0 ? e : `Existe un adjunto que excede el peso máximo de ${a}.`;
67
- }, [c, o.maxFileSizeExceededMessage]);
68
- $(() => {
69
- n.length > 0 && !W(n) ? M?.("error", k()) : M?.("none");
70
- }, [n, W, M, k]);
71
- const H = f(() => {
72
- d.current && !l && d.current.click();
73
- }, [l]), J = f(async (a) => {
67
+ }, [m]), k = f(() => {
68
+ const a = me(m), e = o.maxFileSizeExceededMessage;
69
+ return typeof e == "function" ? e(m, a) : typeof e == "string" && e.trim().length > 0 ? e : `Existe un adjunto que excede el peso máximo de ${a}.`;
70
+ }, [m, o.maxFileSizeExceededMessage]);
71
+ j(() => {
72
+ n.length > 0 && !W(n) ? p?.("error", k()) : p?.("none");
73
+ }, [n, W, p, k]);
74
+ const Y = f(() => {
75
+ u.current && !c && u.current.click();
76
+ }, [c]), T = f(async (a) => {
74
77
  const e = n.find((t) => t.id === a);
75
78
  if (!e) {
76
79
  console.warn(`[EFWAttachment]: Attachment with id ${a} not found`);
77
80
  return;
78
81
  }
79
82
  try {
80
- if (x && !await x(e)) {
83
+ if (b && !await b(e)) {
81
84
  console.log(`[EFWAttachment]: Removal of file ${a} was cancelled`);
82
85
  return;
83
86
  }
84
- const t = n.filter((N) => N.id !== a);
85
- s || y(t), r && r(t), console.log(`[EFWAttachment]: File ${a} removed successfully`);
87
+ const t = n.filter((D) => D.id !== a);
88
+ l || x(t), i && i(
89
+ t,
90
+ v(O(t))
91
+ ), console.log(`[EFWAttachment]: File ${a} removed successfully`);
86
92
  } catch (t) {
87
93
  console.error("[EFWAttachment]: Detele file error:", t);
88
94
  }
89
- }, [n, x, r, s]), K = f((a) => {
95
+ }, [n, b, i, l]), Z = f((a) => {
90
96
  const e = Array.from(a.target.files || []).map((t) => ({
91
- id: le(),
97
+ id: re(),
92
98
  name: t.name,
93
99
  size: t.size,
94
100
  type: t.type,
@@ -96,46 +102,66 @@ const ie = Q({
96
102
  file: t
97
103
  }));
98
104
  if (e.length > 0) {
99
- const t = b ? [...n, ...e] : e;
100
- s || y(t), r?.(t);
105
+ const t = M ? [...n, ...e] : e;
106
+ l || x(t), i?.(
107
+ t,
108
+ v(O(t))
109
+ );
101
110
  }
102
- d.current && (d.current.value = "");
103
- }, [n, b, r, s]), O = X(
104
- q,
105
- P === "error" && g.efwAttachmentError
111
+ u.current && (u.current.value = "");
112
+ }, [n, M, i, l]), y = ee(
113
+ G,
114
+ H === "error" && g.efwAttachmentError
106
115
  );
107
- return /* @__PURE__ */ T("div", { className: O, children: [
108
- h && /* @__PURE__ */ T(Y, { style: { display: "disabled" }, children: [
109
- /* @__PURE__ */ u(
116
+ if (!U) {
117
+ const a = v(n) || o.emptyMessage, e = K?.(
118
+ n,
119
+ a
120
+ );
121
+ return e != null ? /* @__PURE__ */ s("div", { className: y, children: e }) : /* @__PURE__ */ s("div", { className: y, children: n.length === 0 ? /* @__PURE__ */ s(te, { style: { opacity: 0.7 }, children: o.emptyMessage }) : /* @__PURE__ */ s(
122
+ q,
123
+ {
124
+ enableRemoveButtons: !1,
125
+ onRemoveAttachment: T,
126
+ attachments: n,
127
+ emptyMessage: o.emptyMessage,
128
+ downloadMenuItemLabel: o.downloadMenuItemLabel,
129
+ removeMenuItemLabel: o.removeMenuItemLabel
130
+ }
131
+ ) });
132
+ }
133
+ return /* @__PURE__ */ V("div", { className: y, children: [
134
+ /* @__PURE__ */ V(ae, { style: { display: "disabled" }, children: [
135
+ /* @__PURE__ */ s(
110
136
  "input",
111
137
  {
112
- ref: d,
113
- id: V,
138
+ ref: u,
139
+ id: Q,
114
140
  type: "file",
115
141
  className: g.efwAttachmentInput,
116
- accept: U,
117
- multiple: b,
118
- onChange: K,
119
- disabled: l
142
+ accept: J,
143
+ multiple: M,
144
+ onChange: Z,
145
+ disabled: c
120
146
  }
121
147
  ),
122
- /* @__PURE__ */ u(
123
- Z,
148
+ /* @__PURE__ */ s(
149
+ ne,
124
150
  {
125
151
  size: "medium",
126
- onClick: H,
127
- icon: /* @__PURE__ */ u(oe, {}),
128
- disabled: l,
152
+ onClick: Y,
153
+ icon: /* @__PURE__ */ s(ce, {}),
154
+ disabled: c,
129
155
  className: g.efwAttachmentsButton,
130
156
  children: o.attachButtonLabel
131
157
  }
132
158
  )
133
159
  ] }),
134
- !h && n.length === 0 ? /* @__PURE__ */ u(_, { style: { opacity: 0.7 }, children: o.emptyMessage }) : /* @__PURE__ */ u(
135
- ne,
160
+ /* @__PURE__ */ s(
161
+ q,
136
162
  {
137
- enableRemoveButtons: h && !l,
138
- onRemoveAttachment: J,
163
+ enableRemoveButtons: !c,
164
+ onRemoveAttachment: T,
139
165
  attachments: n,
140
166
  emptyMessage: o.emptyMessage,
141
167
  downloadMenuItemLabel: o.downloadMenuItemLabel,
@@ -145,5 +171,5 @@ const ie = Q({
145
171
  ] });
146
172
  };
147
173
  export {
148
- xe as EFWAttachment
174
+ Ae as EFWAttachment
149
175
  };
@@ -1,4 +1,5 @@
1
1
  import { EFWFieldChildrenProps } from '../_shared/EFWField/EFWField.types';
2
+ import { ReactNode } from 'react';
2
3
 
3
4
  /**
4
5
  * Valor que representa un archivo adjunto en el componente EFWAttachments.
@@ -25,9 +26,10 @@ export type EFWAttachmentsValue = {
25
26
  /**
26
27
  * Función callback ejecutada cuando cambia la lista de archivos adjuntos.
27
28
  * @param values - Array de archivos adjuntos actualizados
28
- * @param displayValue - Valor de visualización opcional
29
+ * @param displayValue - Texto formateado de la lista de adjuntos
29
30
  */
30
31
  export type EFWAttachmentsOnChange = (values: EFWAttachmentsValue[], displayValue?: string) => void;
32
+ export type EFWAttachmentsNonEditableRenderer = (value: EFWAttachmentsValue[], displayValue: string) => ReactNode;
31
33
  /**
32
34
  * Textos de la UI del componente EFWAttachments.
33
35
  */
@@ -104,4 +106,9 @@ export interface EFWAttachmentsProps extends EFWFieldChildrenProps {
104
106
  * @param displayValue - Valor de visualización opcional
105
107
  */
106
108
  onChange?: EFWAttachmentsOnChange;
109
+ /**
110
+ * Renderiza contenido custom cuando `editable={false}`.
111
+ * Si retorna `null` o `undefined`, se utiliza el render no editable por defecto.
112
+ */
113
+ readOnlyRenderer?: EFWAttachmentsNonEditableRenderer;
107
114
  }
@@ -1,8 +1,8 @@
1
1
  import { jsx as a } from "react/jsx-runtime";
2
- import { EFWField as L } from "../_shared/EFWField/EFWField.js";
3
- import { EFWAttachment as M } from "./EFWAttachments.js";
2
+ import { EFWField as M } from "../_shared/EFWField/EFWField.js";
3
+ import { EFWAttachment as R } from "./EFWAttachments.js";
4
4
  import { mergeClasses as S } from "@griffel/react";
5
- const P = (t) => {
5
+ const O = (t) => {
6
6
  const {
7
7
  title: l,
8
8
  infoLabel: s,
@@ -10,8 +10,8 @@ const P = (t) => {
10
10
  className: n,
11
11
  style: o = {},
12
12
  required: r = !1,
13
- validationState: m,
14
- validationMessage: d,
13
+ validationState: d,
14
+ validationMessage: m,
15
15
  validationMessageIcon: c,
16
16
  disabled: f = !1,
17
17
  editable: e = !0,
@@ -24,13 +24,14 @@ const P = (t) => {
24
24
  labels: C,
25
25
  onRemoveAttachment: v,
26
26
  onChange: x,
27
+ readOnlyRenderer: y,
27
28
  onValidationChange: A,
28
29
  ...E
29
- } = t, N = (w, y) => {
30
- x?.(w, y);
30
+ } = t, N = (w, L) => {
31
+ x?.(w, L);
31
32
  }, W = S(n, "efw-attachments-field");
32
33
  return /* @__PURE__ */ a(
33
- L,
34
+ M,
34
35
  {
35
36
  className: W,
36
37
  style: o,
@@ -40,13 +41,13 @@ const P = (t) => {
40
41
  hint: i,
41
42
  hidden: h,
42
43
  required: r,
43
- validationState: m,
44
- validationMessage: d,
44
+ validationState: d,
45
+ validationMessage: m,
45
46
  validationMessageIcon: c,
46
47
  onValidationChange: A,
47
48
  ...E,
48
49
  children: /* @__PURE__ */ a(
49
- M,
50
+ R,
50
51
  {
51
52
  files: g,
52
53
  defaultFiles: p,
@@ -57,12 +58,13 @@ const P = (t) => {
57
58
  acceptedTypes: F,
58
59
  maxFileSize: b,
59
60
  labels: C,
60
- onRemoveAttachment: v
61
+ onRemoveAttachment: v,
62
+ readOnlyRenderer: y
61
63
  }
62
64
  )
63
65
  }
64
66
  );
65
67
  };
66
68
  export {
67
- P as EFWAttachmentsField
69
+ O as EFWAttachmentsField
68
70
  };
@@ -1,5 +1,5 @@
1
1
  export { EFWAttachment } from './EFWAttachments';
2
2
  export { getAttachmentsFormattedValue } from './EFWAttachments.utils';
3
- export type { EFWAttachmentsProps, EFWAttachmentsValue, EFWAttachmentsOnChange } from './EFWAttachments.types';
3
+ export type { EFWAttachmentsProps, EFWAttachmentsValue, EFWAttachmentsOnChange, EFWAttachmentsNonEditableRenderer } from './EFWAttachments.types';
4
4
  export { EFWAttachmentsField } from './EFWAttachmentsField';
5
5
  export type { EFWAttachmentsFieldProps, EFWAttachmentsFieldValue, EFWAttachmentsFieldOnChange } from './EFWAttachmentsField.types';
@@ -1,10 +1,10 @@
1
- import { jsx as g, Fragment as oe } from "react/jsx-runtime";
2
- import { makeStyles as ae, tokens as n, mergeClasses as re, Text as le } from "@fluentui/react-components";
3
- import { useId as ne, useMemo as p, useState as se, useRef as I, useCallback as D, useEffect as ce } from "react";
4
- import { DatePicker as ie } from "@fluentui/react-datepicker-compat";
5
- import { mapToValidDates as S, getDatePickerFormattedValue as de } from "./EFWDatePicker.utils.js";
6
- import { useFieldsLocaleText as ue } from "../../i18n/PorygonI18nProvider.js";
7
- const C = [], me = ae({
1
+ import { jsx as g, Fragment as ae } from "react/jsx-runtime";
2
+ import { makeStyles as re, tokens as n, mergeClasses as le, Text as ne } from "@fluentui/react-components";
3
+ import { useId as se, useMemo as p, useState as ce, useRef as R, useCallback as D, useEffect as ie } from "react";
4
+ import { DatePicker as de } from "@fluentui/react-datepicker-compat";
5
+ import { mapToValidDates as S, getDatePickerFormattedValue as ue } from "./EFWDatePicker.utils.js";
6
+ import { useFieldsLocaleText as me } from "../../i18n/PorygonI18nProvider.js";
7
+ const C = [], fe = re({
8
8
  efwDatePickerControl: {
9
9
  "& [disabled]": {
10
10
  backgroundColor: n.colorNeutralBackground3,
@@ -26,78 +26,88 @@ const C = [], me = ae({
26
26
  borderBottomWidth: "2px"
27
27
  }
28
28
  }
29
- }), Ce = (k) => {
29
+ }), ke = (k) => {
30
30
  const {
31
- editable: N = !0,
32
- disabled: R = !1,
31
+ editable: w = !0,
32
+ disabled: I = !1,
33
33
  className: Y = "",
34
- selectedDates: P = C,
34
+ selectedDates: y = C,
35
35
  defaultSelectedDates: d = C,
36
36
  allowTextInput: L = !0,
37
37
  localizedStrings: z,
38
38
  minDate: A,
39
- maxDate: W,
40
- showGoToToday: j = !0,
41
- showCloseButton: G = !0,
42
- restrictedDates: O = C,
43
- friendlyDateFormat: y = !1,
39
+ maxDate: O,
40
+ showGoToToday: W = !0,
41
+ showCloseButton: j = !0,
42
+ restrictedDates: G = C,
43
+ friendlyDateFormat: P = !1,
44
44
  onSelectDate: s,
45
45
  onFormatDate: U,
46
46
  onChange: u,
47
47
  labels: b,
48
- validationState: _ = "none",
48
+ readOnlyRenderer: _,
49
+ validationState: q = "none",
49
50
  setParentComponentState: m
50
- } = k, F = ne(), x = me(), r = k.selectedDates !== void 0, q = p(() => S(P ?? []), [P]), M = p(() => S(d), [d]), T = ue(), H = T.datePicker.calendarStrings, f = z ?? H, V = T.datePicker.labels, B = V.placeholder, E = V.emptyState, $ = b?.placeholder, v = b?.emptyState, w = p(() => ({
51
- placeholder: $ ?? B,
52
- emptyState: v ?? E
51
+ } = k, F = se(), x = fe(), r = k.selectedDates !== void 0, H = p(() => S(y ?? []), [y]), M = p(() => S(d), [d]), T = me(), J = T.datePicker.calendarStrings, f = z ?? J, V = T.datePicker.labels, v = V.placeholder, E = V.emptyState, B = b?.placeholder, $ = b?.emptyState, N = p(() => ({
52
+ placeholder: B ?? v,
53
+ emptyState: $ ?? E
53
54
  }), [
55
+ B,
54
56
  $,
55
57
  v,
56
- B,
57
58
  E
58
- ]), [J, h] = se(() => S(d)), t = r ? q : J, K = I(null), Q = I(null), X = D((o) => {
59
- if (!o) return "";
60
- const a = o.getDate(), e = o.getMonth(), c = o.getFullYear();
61
- if (y)
62
- return `${f.months[e]} ${a}, ${c}`;
59
+ ]), [K, h] = ce(() => S(d)), o = r ? H : K, Q = R(null), X = R(null), Z = D((e) => {
60
+ if (!e) return "";
61
+ const t = e.getDate(), a = e.getMonth(), c = e.getFullYear();
62
+ if (P)
63
+ return `${f.months[a]} ${t}, ${c}`;
63
64
  {
64
- const i = a < 10 ? `0${a}` : a, l = e + 1 < 10 ? `0${e + 1}` : e + 1;
65
+ const i = t < 10 ? `0${t}` : t, l = a + 1 < 10 ? `0${a + 1}` : a + 1;
65
66
  return `${i}/${l}/${c}`;
66
67
  }
67
- }, [y, f]), Z = D((o) => {
68
- const a = t.length && t[0] instanceof Date ? t[0] : /* @__PURE__ */ new Date(), e = (o || "").trim().split("/"), c = e.length > 0 ? Math.max(1, Math.min(31, parseInt(e[0], 10))) : a.getDate(), i = e.length > 1 ? Math.max(1, Math.min(12, parseInt(e[1], 10))) - 1 : a.getMonth();
69
- let l = e.length > 2 ? parseInt(e[2], 10) : a.getFullYear();
70
- return l < 100 && (l += a.getFullYear() - a.getFullYear() % 100), new Date(l, i, c);
71
- }, [t]), ee = D((o) => {
72
- if (!(o instanceof Date)) {
73
- !r && t.length > 0 && h([]), s?.(null), u?.([]), m?.("none", "");
68
+ }, [P, f]), ee = D((e) => {
69
+ const t = o.length && o[0] instanceof Date ? o[0] : /* @__PURE__ */ new Date(), a = (e || "").trim().split("/"), c = a.length > 0 ? Math.max(1, Math.min(31, parseInt(a[0], 10))) : t.getDate(), i = a.length > 1 ? Math.max(1, Math.min(12, parseInt(a[1], 10))) - 1 : t.getMonth();
70
+ let l = a.length > 2 ? parseInt(a[2], 10) : t.getFullYear();
71
+ return l < 100 && (l += t.getFullYear() - t.getFullYear() % 100), new Date(l, i, c);
72
+ }, [o]), te = D((e) => {
73
+ if (!(e instanceof Date)) {
74
+ !r && o.length > 0 && h([]), s?.(null), u?.([]), m?.("none", "");
74
75
  return;
75
76
  }
76
- if (t.length > 0 && t[0] instanceof Date ? t[0].getTime() === o.getTime() : !1) {
77
- s?.(o);
77
+ if (o.length > 0 && o[0] instanceof Date ? o[0].getTime() === e.getTime() : !1) {
78
+ s?.(e);
78
79
  return;
79
80
  }
80
- const e = [o];
81
- r || h(e), s?.(o), u?.(e), m?.("none", "");
82
- }, [t, r, s, u, m]);
83
- ce(() => {
81
+ const a = [e];
82
+ r || h(a), s?.(e), u?.(a), m?.("none", "");
83
+ }, [o, r, s, u, m]);
84
+ ie(() => {
84
85
  r || h(M);
85
86
  }, [r, M]);
86
- const te = re(
87
+ const oe = le(
87
88
  Y,
88
89
  x.efwDatePickerControl,
89
- _ === "error" && x.efwDatePickerControlError
90
+ q === "error" && x.efwDatePickerControlError
90
91
  );
91
- return /* @__PURE__ */ g(oe, { children: N ? /* @__PURE__ */ g(
92
- ie,
92
+ if (!w) {
93
+ const e = ue(o[0]) || N.emptyState, t = _?.(
94
+ o,
95
+ e,
96
+ !1,
97
+ void 0
98
+ );
99
+ return t != null ? /* @__PURE__ */ g(ae, { children: t }) : /* @__PURE__ */ g(ne, { style: o.length ? void 0 : { opacity: 0.7 }, children: e });
100
+ }
101
+ return /* @__PURE__ */ g(
102
+ de,
93
103
  {
94
104
  calendar: {
95
- componentRef: Q,
96
- restrictedDates: O
105
+ componentRef: X,
106
+ restrictedDates: G
97
107
  },
98
108
  strings: f,
99
- className: te,
100
- ref: K,
109
+ className: oe,
110
+ ref: Q,
101
111
  id: F,
102
112
  name: F,
103
113
  autoComplete: "off",
@@ -106,19 +116,19 @@ const C = [], me = ae({
106
116
  spellCheck: "false",
107
117
  allowTextInput: L,
108
118
  disableAutoFocus: !0,
109
- value: t.length > 0 ? t[0] : null,
119
+ value: o.length > 0 ? o[0] : null,
110
120
  minDate: A,
111
- maxDate: W,
112
- disabled: R,
113
- onSelectDate: ee,
114
- formatDate: U ?? X,
115
- parseDateFromString: Z,
116
- placeholder: w.placeholder,
117
- showGoToToday: j,
118
- showCloseButton: G
121
+ maxDate: O,
122
+ disabled: I,
123
+ onSelectDate: te,
124
+ formatDate: U ?? Z,
125
+ parseDateFromString: ee,
126
+ placeholder: N.placeholder,
127
+ showGoToToday: W,
128
+ showCloseButton: j
119
129
  }
120
- ) : /* @__PURE__ */ g(le, { style: t.length ? void 0 : { opacity: 0.7 }, children: de(t[0]) || w.emptyState }) });
130
+ );
121
131
  };
122
132
  export {
123
- Ce as EFWDatePicker
133
+ ke as EFWDatePicker
124
134
  };
@@ -1,9 +1,15 @@
1
1
  import { EFWFieldChildrenProps } from '../_shared/EFWField/EFWField.types';
2
2
  import { DatePickerProps, CalendarStrings } from '@fluentui/react-datepicker-compat';
3
+ import { ReactNode } from 'react';
3
4
 
4
5
  export type { CalendarStrings } from '@fluentui/react-datepicker-compat';
6
+ /**
7
+ * Valor de fecha individual. La ausencia de valor se representa con
8
+ * `selectedDates?: []` o `selectedDates: []`, no con elementos `undefined`.
9
+ */
5
10
  export type EFWDatePickerValue = (Date | string);
6
11
  export type EFWDatePickerOnChange = (value: EFWDatePickerValue[]) => void;
12
+ export type EFWDatePickerNonEditableRenderer = (value: EFWDatePickerValue[], displayValue: string, includeTime?: boolean, timeValue?: string) => ReactNode;
7
13
  export interface EFWDatePickerLabels {
8
14
  placeholder?: string;
9
15
  emptyState?: string;
@@ -84,4 +90,9 @@ export interface EFWDatePickerProps extends Omit<Partial<DatePickerProps>, 'onCh
84
90
  */
85
91
  onChange?: EFWDatePickerOnChange;
86
92
  labels?: EFWDatePickerLabels;
93
+ /**
94
+ * Renderiza contenido custom cuando `editable={false}`.
95
+ * Si retorna `null` o `undefined`, se utiliza el render no editable por defecto.
96
+ */
97
+ readOnlyRenderer?: EFWDatePickerNonEditableRenderer;
87
98
  }