@soyfri/shared-library 4.0.1 → 4.0.4

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 (88) hide show
  1. package/{ActionMenu-wNWkDZWh.cjs → ActionMenu-D81Xb35f.cjs} +3 -3
  2. package/ActionMenu-D81Xb35f.cjs.map +1 -0
  3. package/{ActionMenu-BXRVKopM.js → ActionMenu-DYPA_tYk.js} +3 -3
  4. package/ActionMenu-DYPA_tYk.js.map +1 -0
  5. package/{Autocomplete-Bd3bN4Cw.cjs → Autocomplete-Baqwboth.cjs} +59 -38
  6. package/Autocomplete-Baqwboth.cjs.map +1 -0
  7. package/{Autocomplete-E5aSUGVK.js → Autocomplete-Cvf16lFk.js} +59 -38
  8. package/Autocomplete-Cvf16lFk.js.map +1 -0
  9. package/{DatePicker-D__RSgs-.js → DatePicker-D5BH4v1p.js} +3 -2
  10. package/{DatePicker-D__RSgs-.js.map → DatePicker-D5BH4v1p.js.map} +1 -1
  11. package/{DatePicker-CMcQddi1.cjs → DatePicker-mz7CYtVw.cjs} +3 -2
  12. package/{DatePicker-CMcQddi1.cjs.map → DatePicker-mz7CYtVw.cjs.map} +1 -1
  13. package/{DateTimePicker-LeaE716a.js → DateTimePicker-ZCf0Wh4r.js} +6 -2
  14. package/DateTimePicker-ZCf0Wh4r.js.map +1 -0
  15. package/{DateTimePicker-BVJGq1A0.cjs → DateTimePicker-ejQDpjgX.cjs} +6 -2
  16. package/DateTimePicker-ejQDpjgX.cjs.map +1 -0
  17. package/{Input-BibHlnGN.js → Input-CmvuMwXZ.js} +3 -2
  18. package/{Input-BibHlnGN.js.map → Input-CmvuMwXZ.js.map} +1 -1
  19. package/{Input-Bpjw7qwq.cjs → Input-hnQ7g6b7.cjs} +3 -2
  20. package/{Input-Bpjw7qwq.cjs.map → Input-hnQ7g6b7.cjs.map} +1 -1
  21. package/{Select-BaY3zJhq.js → Select-CZ0BiKVN.js} +10 -4
  22. package/Select-CZ0BiKVN.js.map +1 -0
  23. package/{Select-WpHNCHHz.cjs → Select-ZhFf4SBp.cjs} +10 -4
  24. package/Select-ZhFf4SBp.cjs.map +1 -0
  25. package/{StatusMessage-B3nXpuRl.cjs → StatusMessageContext-BMsbLKRq.cjs} +19 -1
  26. package/StatusMessageContext-BMsbLKRq.cjs.map +1 -0
  27. package/{StatusMessage-D0WgSBx7.js → StatusMessageContext-DgYiObYE.js} +21 -3
  28. package/StatusMessageContext-DgYiObYE.js.map +1 -0
  29. package/components/ActionMenu/ActionMenu.cjs +1 -1
  30. package/components/ActionMenu/ActionMenu.js +1 -1
  31. package/components/Autocomplete/Autocomplete.cjs +1 -1
  32. package/components/Autocomplete/Autocomplete.d.ts +30 -13
  33. package/components/Autocomplete/Autocomplete.helpers.d.ts +4 -4
  34. package/components/Autocomplete/Autocomplete.js +1 -1
  35. package/components/Autocomplete/_parts/AutocompleteChips.d.ts +7 -6
  36. package/components/Autocomplete/_parts/AutocompleteOption.d.ts +5 -5
  37. package/components/Autocomplete/index.d.ts +1 -1
  38. package/components/DatePicker/DatePicker.cjs +1 -1
  39. package/components/DatePicker/DatePicker.js +1 -1
  40. package/components/DateTimePicker/DateTimePicker.cjs +1 -1
  41. package/components/DateTimePicker/DateTimePicker.d.ts +9 -0
  42. package/components/DateTimePicker/DateTimePicker.js +1 -1
  43. package/components/Input/Input.cjs +1 -1
  44. package/components/Input/Input.js +1 -1
  45. package/components/Select/Select.cjs +1 -1
  46. package/components/Select/Select.js +1 -1
  47. package/components/StatusMessage/StatusMessage.cjs +5 -3
  48. package/components/StatusMessage/StatusMessage.cjs.map +1 -1
  49. package/components/StatusMessage/StatusMessage.js +4 -2
  50. package/components/StatusMessage/StatusMessageContext.d.ts +16 -0
  51. package/components/StatusMessage/index.d.ts +2 -0
  52. package/components/_shared/resolvePreset.d.ts +9 -5
  53. package/hooks/ClipBoard/ClipBoard.cjs +43 -24
  54. package/hooks/ClipBoard/ClipBoard.cjs.map +1 -1
  55. package/hooks/ClipBoard/ClipBoard.d.ts +1 -1
  56. package/hooks/ClipBoard/ClipBoard.js +43 -24
  57. package/hooks/ClipBoard/ClipBoard.js.map +1 -1
  58. package/index.cjs +58 -10
  59. package/index.cjs.map +1 -1
  60. package/index.d.ts +4 -4
  61. package/index.js +22 -10
  62. package/mui.d.ts +2 -1
  63. package/package.json +2 -3
  64. package/resolvePreset-CxTI6_Ln.cjs.map +1 -1
  65. package/resolvePreset-K6_BfWHD.js.map +1 -1
  66. package/ActionMenu-BXRVKopM.js.map +0 -1
  67. package/ActionMenu-wNWkDZWh.cjs.map +0 -1
  68. package/Autocomplete-Bd3bN4Cw.cjs.map +0 -1
  69. package/Autocomplete-E5aSUGVK.js.map +0 -1
  70. package/DateTimePicker-BVJGq1A0.cjs.map +0 -1
  71. package/DateTimePicker-LeaE716a.js.map +0 -1
  72. package/README.md +0 -251
  73. package/Select-BaY3zJhq.js.map +0 -1
  74. package/Select-WpHNCHHz.cjs.map +0 -1
  75. package/StatusMessage-B3nXpuRl.cjs.map +0 -1
  76. package/StatusMessage-D0WgSBx7.js.map +0 -1
  77. package/local/affiliations/affiliations.dev.soyfri.com-key.pem +0 -28
  78. package/local/affiliations/affiliations.dev.soyfri.com.pem +0 -27
  79. package/local/aficiliaciones/afiliaciones.dev.soyfri.com-key.pem +0 -28
  80. package/local/aficiliaciones/afiliaciones.dev.soyfri.com.pem +0 -27
  81. package/local/afiliaciones/afiliaciones.dev.soyfri.com-key.pem +0 -28
  82. package/local/afiliaciones/afiliaciones.dev.soyfri.com.pem +0 -27
  83. package/local/root/rootCA-key.pem +0 -40
  84. package/local/root/rootCA.pem +0 -30
  85. package/local/soporte/supportweb.dev.soyfri.com-key.pem +0 -28
  86. package/local/soporte/supportweb.dev.soyfri.com.pem +0 -27
  87. package/local/support/supportweb.dev.soyfri.com-key.pem +0 -28
  88. package/local/support/supportweb.dev.soyfri.com.pem +0 -27
@@ -2,8 +2,10 @@ import { ReactNode, SyntheticEvent } from 'react';
2
2
  import { TextFieldProps } from '@mui/material';
3
3
  import { SxProps, Theme } from '@mui/material/styles';
4
4
  import { RegisterOptions } from 'react-hook-form';
5
- export interface SelectOption {
6
- value: string | number;
5
+ /** Key estable usada para comparar values, indexar caches y como React key. */
6
+ export type AutocompleteValueKey = string | number;
7
+ export interface SelectOption<TValue = AutocompleteValueKey> {
8
+ value: TValue;
7
9
  label: string;
8
10
  img?: string;
9
11
  disabled?: boolean;
@@ -12,11 +14,12 @@ export interface SelectOption {
12
14
  }
13
15
  export type LabelPosition = 'outside' | 'floating';
14
16
  export type AutocompleteSize = 'small' | 'medium';
15
- export type RenderOptionItem = (item: SelectOption) => ReactNode;
16
- export type RenderChipLabel = (item: SelectOption) => ReactNode;
17
- export type BaseAutocompleteProps<_TValue extends SelectOption['value'] = SelectOption['value']> = {
17
+ export type RenderOptionItem<TValue = AutocompleteValueKey> = (item: SelectOption<TValue>) => ReactNode;
18
+ export type RenderChipLabel<TValue = AutocompleteValueKey> = (item: SelectOption<TValue>) => ReactNode;
19
+ export type RenderSingleValue<TValue = AutocompleteValueKey> = (item: SelectOption<TValue>) => ReactNode;
20
+ export type BaseAutocompleteProps<TValue = AutocompleteValueKey> = {
18
21
  label?: string;
19
- options: SelectOption[];
22
+ options: SelectOption<TValue>[];
20
23
  placeholder?: string;
21
24
  multiple?: boolean;
22
25
  disabled?: boolean;
@@ -25,8 +28,22 @@ export type BaseAutocompleteProps<_TValue extends SelectOption['value'] = Select
25
28
  error?: boolean;
26
29
  helperText?: string;
27
30
  maxChipsToShow?: number;
28
- renderOptionItem?: RenderOptionItem;
29
- renderChipLabel?: RenderChipLabel;
31
+ renderOptionItem?: RenderOptionItem<TValue>;
32
+ renderChipLabel?: RenderChipLabel<TValue>;
33
+ /**
34
+ * Renderiza JSX custom como `startAdornment` del input en single mode.
35
+ * Recibe la `SelectOption` seleccionada. Útil para mostrar avatars, iconos,
36
+ * etc. junto al texto del label. En `multiple` no aplica (se usa `renderChipLabel`).
37
+ */
38
+ renderSingleValue?: RenderSingleValue<TValue>;
39
+ /**
40
+ * Extrae una key estable (string | number) desde el `value`. Obligatorio
41
+ * cuando `TValue` es un objeto: se usa para comparar values (`isOptionEqualToValue`,
42
+ * resolución desde el value del form), indexar el cache interno de opciones
43
+ * vistas y como React key en chips/options del dropdown. Para primitivos se
44
+ * puede omitir (default: identidad, o sea `===`).
45
+ */
46
+ getOptionKey?: (value: TValue) => AutocompleteValueKey;
30
47
  /** Border radius del input. Default: 10. */
31
48
  borderRadius?: number | string;
32
49
  /** "outside" (default) = label arriba del input; "floating" = comportamiento nativo MUI. */
@@ -52,21 +69,21 @@ export type BaseAutocompleteProps<_TValue extends SelectOption['value'] = Select
52
69
  /** Valor controlado del texto de búsqueda. */
53
70
  inputValue?: string;
54
71
  /** Filtro custom. Para búsqueda remota pasar `(x) => x` y confiar sólo en el servicio. */
55
- filterOptions?: (options: SelectOption[], state: any) => SelectOption[];
72
+ filterOptions?: (options: SelectOption<TValue>[], state: any) => SelectOption<TValue>[];
56
73
  /** Permite valores arbitrarios (no solo de la lista). */
57
74
  freeSolo?: boolean;
58
75
  open?: boolean;
59
76
  onOpen?: (event: SyntheticEvent) => void;
60
77
  onClose?: (event: SyntheticEvent, reason: string) => void;
61
78
  };
62
- export interface ControlledAutocompleteProps<TValue extends SelectOption['value'] = SelectOption['value']> extends BaseAutocompleteProps<TValue> {
79
+ export interface ControlledAutocompleteProps<TValue = AutocompleteValueKey> extends BaseAutocompleteProps<TValue> {
63
80
  value: TValue | TValue[] | null;
64
81
  onChange: (val: TValue | TValue[] | null) => void;
65
82
  name?: string;
66
83
  control?: never;
67
84
  validation?: never;
68
85
  }
69
- export interface RHFAutocompleteProps<TValue extends SelectOption['value'] = SelectOption['value']> extends BaseAutocompleteProps<TValue> {
86
+ export interface RHFAutocompleteProps<TValue = AutocompleteValueKey> extends BaseAutocompleteProps<TValue> {
70
87
  name: string;
71
88
  control: any;
72
89
  validation?: RegisterOptions;
@@ -78,8 +95,8 @@ export interface RHFAutocompleteProps<TValue extends SelectOption['value'] = Sel
78
95
  value?: never;
79
96
  onChange?: never;
80
97
  }
81
- export type AutocompleteProps<TValue extends SelectOption['value'] = SelectOption['value']> = ControlledAutocompleteProps<TValue> | RHFAutocompleteProps<TValue>;
82
- export declare function Autocomplete<TValue extends SelectOption['value'] = SelectOption['value']>(props: AutocompleteProps<TValue>): import("react/jsx-runtime").JSX.Element;
98
+ export type AutocompleteProps<TValue = AutocompleteValueKey> = ControlledAutocompleteProps<TValue> | RHFAutocompleteProps<TValue>;
99
+ export declare function Autocomplete<TValue = AutocompleteValueKey>(props: AutocompleteProps<TValue>): import("react/jsx-runtime").JSX.Element;
83
100
  /** Alias de `Autocomplete`. Ambos nombres son equivalentes. */
84
101
  export declare const AutocompleteSelect: typeof Autocomplete;
85
102
  export default Autocomplete;
@@ -1,9 +1,9 @@
1
1
  import { SxProps, Theme } from '@mui/material/styles';
2
- import { SelectOption } from './Autocomplete';
2
+ import { AutocompleteValueKey, SelectOption } from './Autocomplete';
3
3
  /** Resuelve un value único a su SelectOption dentro del pool. */
4
- export declare const resolveSingleValue: (options: SelectOption[], value: SelectOption["value"] | null | undefined) => SelectOption | null;
4
+ export declare const resolveSingleValue: <TValue>(options: SelectOption<TValue>[], value: TValue | null | undefined, getKey: (v: TValue) => AutocompleteValueKey) => SelectOption<TValue> | null;
5
5
  /** Resuelve un array de values a sus SelectOption dentro del pool. */
6
- export declare const resolveMultipleValue: (options: SelectOption[], value: SelectOption["value"][] | null | undefined) => SelectOption[];
6
+ export declare const resolveMultipleValue: <TValue>(options: SelectOption<TValue>[], value: TValue[] | null | undefined, getKey: (v: TValue) => AutocompleteValueKey) => SelectOption<TValue>[];
7
7
  /** Merge de sx base + extra del consumer, respetando el contrato de MUI. */
8
8
  export declare const mergeSx: (base: SxProps<Theme>, extra?: SxProps<Theme>) => SxProps<Theme>;
9
9
  /**
@@ -17,6 +17,6 @@ export declare const mergeSx: (base: SxProps<Theme>, extra?: SxProps<Theme>) =>
17
17
  * refresh de metadata (label/img/etc.) invalide la referencia estabilizada
18
18
  * y la UI muestre los datos actualizados.
19
19
  */
20
- export declare const areResolvedValuesEqual: (prev: SelectOption | SelectOption[] | null, next: SelectOption | SelectOption[] | null, multiple: boolean) => boolean;
20
+ export declare const areResolvedValuesEqual: <TValue>(prev: SelectOption<TValue> | SelectOption<TValue>[] | null, next: SelectOption<TValue> | SelectOption<TValue>[] | null, multiple: boolean, getKey: (v: TValue) => AutocompleteValueKey) => boolean;
21
21
  /** Determina si un valor resuelto está vacío (para placeholder/shrink). */
22
22
  export declare const isResolvedValueEmpty: (resolvedValue: unknown, multiple: boolean) => boolean;
@@ -1,4 +1,4 @@
1
- import { A, a, A as A2 } from "../../Autocomplete-E5aSUGVK.js";
1
+ import { A, a, A as A2 } from "../../Autocomplete-Cvf16lFk.js";
2
2
  export {
3
3
  A as Autocomplete,
4
4
  a as AutocompleteSelect,
@@ -1,13 +1,14 @@
1
- import { default as React } from 'react';
2
- import { SelectOption, RenderChipLabel, AutocompleteSize } from '../Autocomplete';
3
- interface AutocompleteChipsProps {
4
- value: SelectOption[];
1
+ import { AutocompleteValueKey, SelectOption, RenderChipLabel, AutocompleteSize } from '../Autocomplete';
2
+ interface AutocompleteChipsProps<TValue = AutocompleteValueKey> {
3
+ value: SelectOption<TValue>[];
5
4
  getTagProps: (args: {
6
5
  index: number;
7
6
  }) => Record<string, any>;
8
7
  size: AutocompleteSize;
9
8
  maxChipsToShow: number;
10
- renderChipLabel?: RenderChipLabel;
9
+ renderChipLabel?: RenderChipLabel<TValue>;
10
+ /** Key estable del value: React key del chip. Ver `getOptionKey`. */
11
+ getKey: (value: TValue) => AutocompleteValueKey;
11
12
  }
12
13
  /**
13
14
  * Render de los chips del Autocomplete en modo multiple.
@@ -15,5 +16,5 @@ interface AutocompleteChipsProps {
15
16
  * El `getTagProps({ index })` viene de MUI y contiene el handler de delete,
16
17
  * la key, etc. — se spreadea tal cual al Chip.
17
18
  */
18
- export declare const AutocompleteChips: React.FC<AutocompleteChipsProps>;
19
+ export declare const AutocompleteChips: <TValue>({ value, getTagProps, size, maxChipsToShow, renderChipLabel, getKey, }: AutocompleteChipsProps<TValue>) => import("react/jsx-runtime").JSX.Element;
19
20
  export default AutocompleteChips;
@@ -1,9 +1,9 @@
1
1
  import { default as React } from 'react';
2
- import { SelectOption, RenderOptionItem } from '../Autocomplete';
3
- interface AutocompleteOptionProps {
2
+ import { AutocompleteValueKey, SelectOption, RenderOptionItem } from '../Autocomplete';
3
+ interface AutocompleteOptionProps<TValue = AutocompleteValueKey> {
4
4
  liProps: React.HTMLAttributes<HTMLLIElement>;
5
- option: SelectOption;
6
- customRender?: RenderOptionItem;
5
+ option: SelectOption<TValue>;
6
+ customRender?: RenderOptionItem<TValue>;
7
7
  }
8
8
  /**
9
9
  * Render por defecto de un `<li>` del dropdown del Autocomplete.
@@ -12,5 +12,5 @@ interface AutocompleteOptionProps {
12
12
  * La `key` la maneja el padre (`renderOption` en Autocomplete.tsx). Este
13
13
  * componente solo recibe los props restantes del `<li>` para spread.
14
14
  */
15
- export declare const AutocompleteOption: React.FC<AutocompleteOptionProps>;
15
+ export declare const AutocompleteOption: <TValue>({ liProps, option, customRender, }: AutocompleteOptionProps<TValue>) => import("react/jsx-runtime").JSX.Element;
16
16
  export default AutocompleteOption;
@@ -1,2 +1,2 @@
1
1
  export { Autocomplete, AutocompleteSelect, default } from './Autocomplete';
2
- export type { AutocompleteProps, SelectOption, BaseAutocompleteProps, ControlledAutocompleteProps, RHFAutocompleteProps, RenderOptionItem, RenderChipLabel, LabelPosition, AutocompleteSize, } from './Autocomplete';
2
+ export type { AutocompleteProps, SelectOption, BaseAutocompleteProps, ControlledAutocompleteProps, RHFAutocompleteProps, RenderOptionItem, RenderChipLabel, RenderSingleValue, LabelPosition, AutocompleteSize, AutocompleteValueKey, } from './Autocomplete';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const DatePicker = require("../../DatePicker-CMcQddi1.cjs");
3
+ const DatePicker = require("../../DatePicker-mz7CYtVw.cjs");
4
4
  exports.DatePicker = DatePicker.DatePicker;
5
5
  exports.default = DatePicker.DatePicker;
6
6
  //# sourceMappingURL=DatePicker.cjs.map
@@ -1,4 +1,4 @@
1
- import { D, D as D2 } from "../../DatePicker-D__RSgs-.js";
1
+ import { D, D as D2 } from "../../DatePicker-D5BH4v1p.js";
2
2
  export {
3
3
  D as DatePicker,
4
4
  D2 as default
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const DateTimePicker = require("../../DateTimePicker-BVJGq1A0.cjs");
3
+ const DateTimePicker = require("../../DateTimePicker-ejQDpjgX.cjs");
4
4
  exports.DateTimePicker = DateTimePicker.DateTimePicker;
5
5
  exports.default = DateTimePicker.DateTimePicker;
6
6
  //# sourceMappingURL=DateTimePicker.cjs.map
@@ -41,6 +41,15 @@ export interface BaseDateTimePickerProps extends Omit<MuiDateTimePickerProps, 'v
41
41
  ampm?: boolean;
42
42
  viewRenderers?: MuiDateTimePickerProps['viewRenderers'];
43
43
  timeSteps?: MuiDateTimePickerProps['timeSteps'];
44
+ /**
45
+ * Vistas a mostrar en el popover. Default: todas (year, month, day, hours, minutes).
46
+ * Ej: `['hours']` solo permite elegir la hora. `['hours','minutes']` oculta el calendar.
47
+ *
48
+ * Va declarado explícito (y no se hereda del `Omit<MuiDateTimePickerProps>`)
49
+ * porque se desestructura del `props` y se pasa a mano al picker: si sólo
50
+ * viviera en el tipo base caería en el `...rest` y quedaría duplicado.
51
+ */
52
+ views?: MuiDateTimePickerProps['views'];
44
53
  textFieldProps?: Record<string, any>;
45
54
  /** Passthrough completo a slotProps del MuiDateTimePicker. */
46
55
  slotProps?: MuiDateTimePickerProps['slotProps'];
@@ -1,4 +1,4 @@
1
- import { D, D as D2 } from "../../DateTimePicker-LeaE716a.js";
1
+ import { D, D as D2 } from "../../DateTimePicker-ZCf0Wh4r.js";
2
2
  export {
3
3
  D as DateTimePicker,
4
4
  D2 as default
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const Input = require("../../Input-Bpjw7qwq.cjs");
3
+ const Input = require("../../Input-hnQ7g6b7.cjs");
4
4
  exports.Input = Input.Input;
5
5
  exports.default = Input.Input;
6
6
  //# sourceMappingURL=Input.cjs.map
@@ -1,4 +1,4 @@
1
- import { I, I as I2 } from "../../Input-BibHlnGN.js";
1
+ import { I, I as I2 } from "../../Input-CmvuMwXZ.js";
2
2
  export {
3
3
  I as Input,
4
4
  I2 as default
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const Select = require("../../Select-WpHNCHHz.cjs");
3
+ const Select = require("../../Select-ZhFf4SBp.cjs");
4
4
  exports.Option = Select.Option;
5
5
  exports.Select = Select.Select;
6
6
  exports.default = Select.Select;
@@ -1,4 +1,4 @@
1
- import { O, S, S as S2 } from "../../Select-BaY3zJhq.js";
1
+ import { O, S, S as S2 } from "../../Select-CZ0BiKVN.js";
2
2
  export {
3
3
  O as Option,
4
4
  S as Select,
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const StatusMessage = require("../../StatusMessage-B3nXpuRl.cjs");
4
- exports.StatusMessage = StatusMessage.StatusMessage;
5
- exports.default = StatusMessage.StatusMessage;
3
+ const StatusMessageContext = require("../../StatusMessageContext-BMsbLKRq.cjs");
4
+ exports.StatusMessage = StatusMessageContext.StatusMessage;
5
+ exports.StatusMessageProvider = StatusMessageContext.StatusMessageProvider;
6
+ exports.default = StatusMessageContext.StatusMessage;
7
+ exports.useStatusMessageContext = StatusMessageContext.useStatusMessageContext;
6
8
  //# sourceMappingURL=StatusMessage.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatusMessage.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
1
+ {"version":3,"file":"StatusMessage.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
@@ -1,6 +1,8 @@
1
- import { S, S as S2 } from "../../StatusMessage-D0WgSBx7.js";
1
+ import { S, a, S as S2, u } from "../../StatusMessageContext-DgYiObYE.js";
2
2
  export {
3
3
  S as StatusMessage,
4
- S2 as default
4
+ a as StatusMessageProvider,
5
+ S2 as default,
6
+ u as useStatusMessageContext
5
7
  };
6
8
  //# sourceMappingURL=StatusMessage.js.map
@@ -0,0 +1,16 @@
1
+ import { Dispatch, SetStateAction, ReactNode } from 'react';
2
+ import { StatusMessageProps } from './StatusMessage';
3
+ export type StatusMessageState = {
4
+ [K in 'title' | 'description' | 'messageType']: StatusMessageProps[K] | undefined;
5
+ } & Pick<StatusMessageProps, 'displayType'>;
6
+ interface StatusMessageContextValue {
7
+ state: StatusMessageState | undefined;
8
+ setMessage: Dispatch<SetStateAction<StatusMessageState | undefined>>;
9
+ cleanMessage: () => void;
10
+ }
11
+ export declare const useStatusMessageContext: () => StatusMessageContextValue;
12
+ interface StatusMessageProviderProps {
13
+ children: ReactNode;
14
+ }
15
+ export declare const StatusMessageProvider: ({ children }: StatusMessageProviderProps) => import("react/jsx-runtime").JSX.Element;
16
+ export {};
@@ -1,2 +1,4 @@
1
1
  export { StatusMessage, default } from './StatusMessage';
2
2
  export type { StatusMessageProps } from './StatusMessage';
3
+ export { StatusMessageProvider, useStatusMessageContext, } from './StatusMessageContext';
4
+ export type { StatusMessageState } from './StatusMessageContext';
@@ -1,18 +1,22 @@
1
1
  import { SxProps, Theme } from '@mui/material/styles';
2
2
  import { LibraryComponentName } from '../../theme/componentStyles';
3
3
  /**
4
- * Nombre del preset built-in del paquete. No se registra en el theme: si un
5
- * componente recibe `preset="default"` (o no recibe preset), sólo aplica el
6
- * estilo base de fábrica.
4
+ * Nombre del preset que se resuelve cuando el componente no recibe `preset`.
5
+ * El paquete no lo registra: si el consumer no puso `theme.styles[X].default`,
6
+ * no hay preset y el componente queda con su estilo base de fábrica.
7
7
  */
8
8
  export declare const DEFAULT_PRESET_NAME = "default";
9
9
  /**
10
10
  * Resuelve el sx de un preset registrado en `theme.styles[componentName]`.
11
11
  *
12
- * - Si `presetName` es `"default"` o `undefined`, devuelve `undefined`
13
- * (caller sólo aplicará el estilo base del paquete).
12
+ * - Si `presetName` es `undefined`, se busca la entrada `"default"` del theme.
13
+ * Así el consumer registra estilos globales una vez y no pasa `preset` en
14
+ * cada instancia (lo usa `sop` para el `DataRow`).
14
15
  * - Si la entrada en el theme es una función `(theme) => sx`, se ejecuta.
15
16
  * - Si la entrada no existe, devuelve `undefined` silenciosamente (no se
16
17
  * rompe el componente — la responsabilidad de registrarlo es del consumer).
18
+ *
19
+ * El resultado es **aditivo**: el caller aplica siempre su sx built-in y mergea
20
+ * esto encima. Nunca es un reemplazo del estilo base.
17
21
  */
18
22
  export declare function resolvePreset(componentName: LibraryComponentName, presetName: string | undefined, theme: Theme): SxProps<Theme> | undefined;
@@ -17,37 +17,56 @@ function useClipboard(options) {
17
17
  }
18
18
  setSnackbarOpen(false);
19
19
  }, []);
20
- const executeCopy = React.useCallback((text) => {
21
- var _a2, _b;
22
- try {
23
- if (navigator.clipboard && window.isSecureContext) {
24
- navigator.clipboard.writeText(text);
25
- } else {
26
- const textarea = document.createElement("textarea");
27
- textarea.value = text;
28
- document.body.appendChild(textarea);
29
- textarea.select();
30
- document.execCommand("copy");
31
- document.body.removeChild(textarea);
32
- }
33
- setSnackbarMessage((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!");
34
- setSnackbarSeverity((options == null ? void 0 : options.severity) || "success");
20
+ const mostrarSnackbar = React.useCallback(
21
+ (mensaje, severidad) => {
22
+ var _a2;
23
+ setSnackbarMessage(mensaje);
24
+ setSnackbarSeverity(severidad);
35
25
  setSnackbarPosition((options == null ? void 0 : options.position) || { vertical: "bottom", horizontal: "center" });
36
26
  setSnackbarDuration((_a2 = options == null ? void 0 : options.duration) != null ? _a2 : 3e3);
37
27
  setSnackbarOpen(true);
38
- } catch (err) {
39
- console.error("Error al copiar al portapapeles:", err);
40
- setSnackbarMessage("Error al copiar.");
41
- setSnackbarSeverity("error");
42
- setSnackbarPosition((options == null ? void 0 : options.position) || { vertical: "bottom", horizontal: "center" });
43
- setSnackbarDuration((_b = options == null ? void 0 : options.duration) != null ? _b : 3e3);
44
- setSnackbarOpen(true);
28
+ },
29
+ [options]
30
+ );
31
+ const copiarConTextarea = React.useCallback((text) => {
32
+ const textarea = document.createElement("textarea");
33
+ textarea.value = text;
34
+ textarea.style.position = "fixed";
35
+ textarea.style.top = "0";
36
+ textarea.style.opacity = "0";
37
+ document.body.appendChild(textarea);
38
+ textarea.select();
39
+ try {
40
+ return document.execCommand("copy");
41
+ } catch (e) {
42
+ return false;
43
+ } finally {
44
+ document.body.removeChild(textarea);
45
45
  }
46
- }, [options]);
46
+ }, []);
47
+ const executeCopy = React.useCallback(
48
+ async (text) => {
49
+ if (navigator.clipboard && window.isSecureContext) {
50
+ try {
51
+ await navigator.clipboard.writeText(text);
52
+ mostrarSnackbar((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!", (options == null ? void 0 : options.severity) || "success");
53
+ return true;
54
+ } catch (e) {
55
+ }
56
+ }
57
+ if (copiarConTextarea(text)) {
58
+ mostrarSnackbar((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!", (options == null ? void 0 : options.severity) || "success");
59
+ return true;
60
+ }
61
+ mostrarSnackbar("No se pudo copiar al portapapeles.", "error");
62
+ return false;
63
+ },
64
+ [copiarConTextarea, mostrarSnackbar, options]
65
+ );
47
66
  const copyFromRef = React.useCallback(() => {
48
67
  if (elementRef.current) {
49
68
  const textToCopy = elementRef.current.innerText || "";
50
- executeCopy(textToCopy);
69
+ void executeCopy(textToCopy);
51
70
  }
52
71
  }, [executeCopy]);
53
72
  React.useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"ClipBoard.cjs","sources":["../../../src/hooks/ClipBoard/ClipBoard.tsx"],"sourcesContent":["// useClipboard.tsx (Versión Unificada)\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { Snackbar, Alert } from '@mui/material';\nimport { AlertProps } from '@mui/material/Alert';\n\n// Tipo para las opciones del Snackbar\ninterface SnackbarOptions {\n message?: string;\n duration?: number;\n severity?: AlertProps['severity'];\n position?: { vertical: 'top' | 'bottom'; horizontal: 'left' | 'center' | 'right' };\n}\n\n/**\n * Hook 'useClipboard'.\n * Proporciona funcionalidad de copiado de texto y feedback visual (Snackbar).\n * Permite dos modos de uso:\n * 1. Uso por Referencia (ref): Se adjunta a un elemento, copia su innerText al hacer clic.\n * 2. Uso por Función (copy): Recibe el texto a copiar directamente como argumento.\n *\n * @param options Opciones de configuración para el Snackbar de feedback.\n * @returns Un objeto que contiene:\n * - 'ref': Una React Ref para adjuntar a un elemento (Modo Ref).\n * - 'copy': Una función (text: string) => void para copiar texto (Modo Función).\n * - 'CopyMessage': El componente Snackbar para renderizar el feedback.\n */\nexport function useClipboard(options?: SnackbarOptions) {\n // --- Elementos de Copiado por Referencia ---\n const elementRef = useRef<HTMLElement>(null);\n\n // --- Estados y Opciones del Snackbar ---\n const [snackbarOpen, setSnackbarOpen] = useState(false);\n const [snackbarMessage, setSnackbarMessage] = useState(options?.message || '¡Copiado al portapapeles!');\n const [snackbarSeverity, setSnackbarSeverity] = useState<AlertProps['severity']>(options?.severity || 'success');\n const [snackbarPosition, setSnackbarPosition] = useState<import('@mui/material').SnackbarOrigin>(options?.position || { vertical: 'bottom', horizontal: 'center' });\n const [snackbarDuration, setSnackbarDuration] = useState(options?.duration ?? 3000);\n\n // Función para cerrar el Snackbar\n const handleSnackbarClose = useCallback((event?: React.SyntheticEvent | Event, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n setSnackbarOpen(false);\n }, []);\n\n /**\n * FUNCIÓN PRINCIPAL DE COPIADO.\n * Se usa internamente para 'ref' y se expone para 'copy(text)'.\n * @param text El texto exacto a copiar.\n */\n const executeCopy = useCallback((text: string) => {\n try {\n if (navigator.clipboard && window.isSecureContext) {\n // 1. API moderna\n navigator.clipboard.writeText(text);\n } else {\n // 2. Fallback usando textarea\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n }\n \n // Mostrar éxito\n setSnackbarMessage(options?.message || '¡Copiado al portapapeles!');\n setSnackbarSeverity(options?.severity || 'success');\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n\n } catch (err) {\n // Mostrar error\n console.error('Error al copiar al portapapeles:', err);\n setSnackbarMessage('Error al copiar.');\n setSnackbarSeverity('error');\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n }\n }, [options]); \n\n // --- Lógica del Modo Ref ---\n const copyFromRef = useCallback(() => {\n if (elementRef.current) {\n const textToCopy = elementRef.current.innerText || '';\n executeCopy(textToCopy);\n }\n }, [executeCopy]);\n\n // Adjunta un event listener de clic al elemento referenciado (Modo Ref)\n useEffect(() => {\n const currentElement = elementRef.current;\n if (currentElement) {\n currentElement.style.cursor = 'pointer';\n // Adjuntamos la función que copia el texto del ref\n currentElement.addEventListener('click', copyFromRef);\n }\n\n return () => {\n if (currentElement) {\n currentElement.removeEventListener('click', copyFromRef);\n }\n };\n }, [copyFromRef]);\n\n\n // Componente Snackbar encapsulado. Solo se renderiza si duration es > 0.\n const CopyMessage = () => {\n if (snackbarDuration <= 0) return null; // No renderizar si la duración es 0\n\n return (\n <Snackbar\n open={snackbarOpen}\n autoHideDuration={snackbarDuration}\n onClose={handleSnackbarClose}\n anchorOrigin={snackbarPosition}\n >\n <Alert onClose={handleSnackbarClose} severity={snackbarSeverity} sx={{ width: '100%' }}>\n {snackbarMessage}\n </Alert>\n </Snackbar>\n );\n };\n\n // Retorna ambas funcionalidades para que el usuario elija\n return { ref: elementRef, copy: executeCopy, CopyMessage };\n}\n\nexport default useClipboard;"],"names":["useRef","useState","useCallback","_a","useEffect","jsx","Snackbar","Alert"],"mappings":";;;;;AA0BO,SAAS,aAAa,SAA2B;;AAEtD,QAAM,aAAaA,MAAAA,OAAoB,IAAI;AAG3C,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA,SAAS,KAAK;AACtD,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,UAAS,mCAAS,YAAW,2BAA2B;AACtG,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,MAAAA,UAAiC,mCAAS,aAAY,SAAS;AAC/G,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,MAAAA,UAAiD,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,SAAA,CAAU;AAClK,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,MAAAA,UAAS,wCAAS,aAAT,YAAqB,GAAI;AAGlF,QAAM,sBAAsBC,MAAAA,YAAY,CAAC,OAAsC,WAAoB;AACjG,QAAI,WAAW,aAAa;AAC1B;AAAA,IACF;AACA,oBAAgB,KAAK;AAAA,EACvB,GAAG,CAAA,CAAE;AAOL,QAAM,cAAcA,kBAAY,CAAC,SAAiB;;AAChD,QAAI;AACF,UAAI,UAAU,aAAa,OAAO,iBAAiB;AAEjD,kBAAU,UAAU,UAAU,IAAI;AAAA,MACpC,OAAO;AAEL,cAAM,WAAW,SAAS,cAAc,UAAU;AAClD,iBAAS,QAAQ;AACjB,iBAAS,KAAK,YAAY,QAAQ;AAClC,iBAAS,OAAA;AACT,iBAAS,YAAY,MAAM;AAC3B,iBAAS,KAAK,YAAY,QAAQ;AAAA,MACpC;AAGA,0BAAmB,mCAAS,YAAW,2BAA2B;AAClE,2BAAoB,mCAAS,aAAY,SAAS;AAClD,2BAAoB,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,UAAU;AACrF,2BAAoBC,MAAA,mCAAS,aAAT,OAAAA,MAAqB,GAAI;AAC7C,sBAAgB,IAAI;AAAA,IAEtB,SAAS,KAAK;AAEZ,cAAQ,MAAM,oCAAoC,GAAG;AACrD,yBAAmB,kBAAkB;AACrC,0BAAoB,OAAO;AAC3B,2BAAoB,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,UAAU;AACrF,2BAAoB,wCAAS,aAAT,YAAqB,GAAI;AAC7C,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAGZ,QAAM,cAAcD,MAAAA,YAAY,MAAM;AACpC,QAAI,WAAW,SAAS;AACpB,YAAM,aAAa,WAAW,QAAQ,aAAa;AACnD,kBAAY,UAAU;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAGhBE,QAAAA,UAAU,MAAM;AACd,UAAM,iBAAiB,WAAW;AAClC,QAAI,gBAAgB;AAClB,qBAAe,MAAM,SAAS;AAE9B,qBAAe,iBAAiB,SAAS,WAAW;AAAA,IACtD;AAEA,WAAO,MAAM;AACX,UAAI,gBAAgB;AAClB,uBAAe,oBAAoB,SAAS,WAAW;AAAA,MACzD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAIhB,QAAM,cAAc,MAAM;AACxB,QAAI,oBAAoB,EAAG,QAAO;AAElC,WACEC,2BAAAA;AAAAA,MAACC,SAAAA;AAAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,kBAAkB;AAAA,QAClB,SAAS;AAAA,QACT,cAAc;AAAA,QAEd,UAAAD,2BAAAA,IAACE,SAAAA,OAAA,EAAM,SAAS,qBAAqB,UAAU,kBAAkB,IAAI,EAAE,OAAO,OAAA,GAC3E,UAAA,gBAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAGA,SAAO,EAAE,KAAK,YAAY,MAAM,aAAa,YAAA;AAC/C;;"}
1
+ {"version":3,"file":"ClipBoard.cjs","sources":["../../../src/hooks/ClipBoard/ClipBoard.tsx"],"sourcesContent":["// useClipboard.tsx (Versión Unificada)\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { Snackbar, Alert } from '@mui/material';\nimport { AlertProps } from '@mui/material/Alert';\n\n// Tipo para las opciones del Snackbar\ninterface SnackbarOptions {\n message?: string;\n duration?: number;\n severity?: AlertProps['severity'];\n position?: { vertical: 'top' | 'bottom'; horizontal: 'left' | 'center' | 'right' };\n}\n\n/**\n * Hook 'useClipboard'.\n * Proporciona funcionalidad de copiado de texto y feedback visual (Snackbar).\n * Permite dos modos de uso:\n * 1. Uso por Referencia (ref): Se adjunta a un elemento, copia su innerText al hacer clic.\n * 2. Uso por Función (copy): Recibe el texto a copiar directamente como argumento.\n *\n * @param options Opciones de configuración para el Snackbar de feedback.\n * @returns Un objeto que contiene:\n * - 'ref': Una React Ref para adjuntar a un elemento (Modo Ref).\n * - 'copy': Una función (text: string) => void para copiar texto (Modo Función).\n * - 'CopyMessage': El componente Snackbar para renderizar el feedback.\n */\nexport function useClipboard(options?: SnackbarOptions) {\n // --- Elementos de Copiado por Referencia ---\n const elementRef = useRef<HTMLElement>(null);\n\n // --- Estados y Opciones del Snackbar ---\n const [snackbarOpen, setSnackbarOpen] = useState(false);\n const [snackbarMessage, setSnackbarMessage] = useState(options?.message || '¡Copiado al portapapeles!');\n const [snackbarSeverity, setSnackbarSeverity] = useState<AlertProps['severity']>(options?.severity || 'success');\n const [snackbarPosition, setSnackbarPosition] = useState<import('@mui/material').SnackbarOrigin>(options?.position || { vertical: 'bottom', horizontal: 'center' });\n const [snackbarDuration, setSnackbarDuration] = useState(options?.duration ?? 3000);\n\n // Función para cerrar el Snackbar\n const handleSnackbarClose = useCallback((event?: React.SyntheticEvent | Event, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n setSnackbarOpen(false);\n }, []);\n\n /**\n * FUNCIÓN PRINCIPAL DE COPIADO.\n * Se usa internamente para 'ref' y se expone para 'copy(text)'.\n * @param text El texto exacto a copiar.\n */\n const mostrarSnackbar = useCallback(\n (mensaje: string, severidad: AlertProps['severity']) => {\n setSnackbarMessage(mensaje);\n setSnackbarSeverity(severidad);\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n },\n [options],\n );\n\n /** Fallback legacy. `execCommand` devuelve `false` en vez de tirar cuando falla. */\n const copiarConTextarea = useCallback((text: string): boolean => {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n // Fuera de la vista pero seleccionable: sin esto la página salta al final.\n textarea.style.position = 'fixed';\n textarea.style.top = '0';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand('copy');\n } catch {\n return false;\n } finally {\n document.body.removeChild(textarea);\n }\n }, []);\n\n const executeCopy = useCallback(\n async (text: string): Promise<boolean> => {\n // `writeText` es ASÍNCRONA: llamarla sin await/catch dejaba la promesa\n // suelta, y cuando el navegador la rechaza —documento sin foco, permiso\n // denegado, contexto no seguro— la rejection escapaba al `window` de la\n // app que consume la librería. El try/catch de antes sólo atrapaba\n // errores síncronos, así que no cubría nada de eso.\n if (navigator.clipboard && window.isSecureContext) {\n try {\n await navigator.clipboard.writeText(text);\n mostrarSnackbar(options?.message || '¡Copiado al portapapeles!', options?.severity || 'success');\n return true;\n } catch {\n // Puede ser sólo falta de foco: se intenta el fallback antes de rendirse.\n }\n }\n\n if (copiarConTextarea(text)) {\n mostrarSnackbar(options?.message || '¡Copiado al portapapeles!', options?.severity || 'success');\n return true;\n }\n\n mostrarSnackbar('No se pudo copiar al portapapeles.', 'error');\n return false;\n },\n [copiarConTextarea, mostrarSnackbar, options],\n );\n\n // --- Lógica del Modo Ref ---\n const copyFromRef = useCallback(() => {\n if (elementRef.current) {\n const textToCopy = elementRef.current.innerText || '';\n // `void`: el listener del DOM no puede esperar la promesa, y ésta ya\n // maneja sus propios errores adentro.\n void executeCopy(textToCopy);\n }\n }, [executeCopy]);\n\n // Adjunta un event listener de clic al elemento referenciado (Modo Ref)\n useEffect(() => {\n const currentElement = elementRef.current;\n if (currentElement) {\n currentElement.style.cursor = 'pointer';\n // Adjuntamos la función que copia el texto del ref\n currentElement.addEventListener('click', copyFromRef);\n }\n\n return () => {\n if (currentElement) {\n currentElement.removeEventListener('click', copyFromRef);\n }\n };\n }, [copyFromRef]);\n\n\n // Componente Snackbar encapsulado. Solo se renderiza si duration es > 0.\n const CopyMessage = () => {\n if (snackbarDuration <= 0) return null; // No renderizar si la duración es 0\n\n return (\n <Snackbar\n open={snackbarOpen}\n autoHideDuration={snackbarDuration}\n onClose={handleSnackbarClose}\n anchorOrigin={snackbarPosition}\n >\n <Alert onClose={handleSnackbarClose} severity={snackbarSeverity} sx={{ width: '100%' }}>\n {snackbarMessage}\n </Alert>\n </Snackbar>\n );\n };\n\n // Retorna ambas funcionalidades para que el usuario elija\n return { ref: elementRef, copy: executeCopy, CopyMessage };\n}\n\nexport default useClipboard;"],"names":["useRef","useState","useCallback","_a","useEffect","jsx","Snackbar","Alert"],"mappings":"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"}
@@ -24,7 +24,7 @@ interface SnackbarOptions {
24
24
  */
25
25
  export declare function useClipboard(options?: SnackbarOptions): {
26
26
  ref: React.RefObject<HTMLElement | null>;
27
- copy: (text: string) => void;
27
+ copy: (text: string) => Promise<boolean>;
28
28
  CopyMessage: () => import("react/jsx-runtime").JSX.Element | null;
29
29
  };
30
30
  export default useClipboard;
@@ -15,37 +15,56 @@ function useClipboard(options) {
15
15
  }
16
16
  setSnackbarOpen(false);
17
17
  }, []);
18
- const executeCopy = useCallback((text) => {
19
- var _a2, _b;
20
- try {
21
- if (navigator.clipboard && window.isSecureContext) {
22
- navigator.clipboard.writeText(text);
23
- } else {
24
- const textarea = document.createElement("textarea");
25
- textarea.value = text;
26
- document.body.appendChild(textarea);
27
- textarea.select();
28
- document.execCommand("copy");
29
- document.body.removeChild(textarea);
30
- }
31
- setSnackbarMessage((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!");
32
- setSnackbarSeverity((options == null ? void 0 : options.severity) || "success");
18
+ const mostrarSnackbar = useCallback(
19
+ (mensaje, severidad) => {
20
+ var _a2;
21
+ setSnackbarMessage(mensaje);
22
+ setSnackbarSeverity(severidad);
33
23
  setSnackbarPosition((options == null ? void 0 : options.position) || { vertical: "bottom", horizontal: "center" });
34
24
  setSnackbarDuration((_a2 = options == null ? void 0 : options.duration) != null ? _a2 : 3e3);
35
25
  setSnackbarOpen(true);
36
- } catch (err) {
37
- console.error("Error al copiar al portapapeles:", err);
38
- setSnackbarMessage("Error al copiar.");
39
- setSnackbarSeverity("error");
40
- setSnackbarPosition((options == null ? void 0 : options.position) || { vertical: "bottom", horizontal: "center" });
41
- setSnackbarDuration((_b = options == null ? void 0 : options.duration) != null ? _b : 3e3);
42
- setSnackbarOpen(true);
26
+ },
27
+ [options]
28
+ );
29
+ const copiarConTextarea = useCallback((text) => {
30
+ const textarea = document.createElement("textarea");
31
+ textarea.value = text;
32
+ textarea.style.position = "fixed";
33
+ textarea.style.top = "0";
34
+ textarea.style.opacity = "0";
35
+ document.body.appendChild(textarea);
36
+ textarea.select();
37
+ try {
38
+ return document.execCommand("copy");
39
+ } catch (e) {
40
+ return false;
41
+ } finally {
42
+ document.body.removeChild(textarea);
43
43
  }
44
- }, [options]);
44
+ }, []);
45
+ const executeCopy = useCallback(
46
+ async (text) => {
47
+ if (navigator.clipboard && window.isSecureContext) {
48
+ try {
49
+ await navigator.clipboard.writeText(text);
50
+ mostrarSnackbar((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!", (options == null ? void 0 : options.severity) || "success");
51
+ return true;
52
+ } catch (e) {
53
+ }
54
+ }
55
+ if (copiarConTextarea(text)) {
56
+ mostrarSnackbar((options == null ? void 0 : options.message) || "¡Copiado al portapapeles!", (options == null ? void 0 : options.severity) || "success");
57
+ return true;
58
+ }
59
+ mostrarSnackbar("No se pudo copiar al portapapeles.", "error");
60
+ return false;
61
+ },
62
+ [copiarConTextarea, mostrarSnackbar, options]
63
+ );
45
64
  const copyFromRef = useCallback(() => {
46
65
  if (elementRef.current) {
47
66
  const textToCopy = elementRef.current.innerText || "";
48
- executeCopy(textToCopy);
67
+ void executeCopy(textToCopy);
49
68
  }
50
69
  }, [executeCopy]);
51
70
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"ClipBoard.js","sources":["../../../src/hooks/ClipBoard/ClipBoard.tsx"],"sourcesContent":["// useClipboard.tsx (Versión Unificada)\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { Snackbar, Alert } from '@mui/material';\nimport { AlertProps } from '@mui/material/Alert';\n\n// Tipo para las opciones del Snackbar\ninterface SnackbarOptions {\n message?: string;\n duration?: number;\n severity?: AlertProps['severity'];\n position?: { vertical: 'top' | 'bottom'; horizontal: 'left' | 'center' | 'right' };\n}\n\n/**\n * Hook 'useClipboard'.\n * Proporciona funcionalidad de copiado de texto y feedback visual (Snackbar).\n * Permite dos modos de uso:\n * 1. Uso por Referencia (ref): Se adjunta a un elemento, copia su innerText al hacer clic.\n * 2. Uso por Función (copy): Recibe el texto a copiar directamente como argumento.\n *\n * @param options Opciones de configuración para el Snackbar de feedback.\n * @returns Un objeto que contiene:\n * - 'ref': Una React Ref para adjuntar a un elemento (Modo Ref).\n * - 'copy': Una función (text: string) => void para copiar texto (Modo Función).\n * - 'CopyMessage': El componente Snackbar para renderizar el feedback.\n */\nexport function useClipboard(options?: SnackbarOptions) {\n // --- Elementos de Copiado por Referencia ---\n const elementRef = useRef<HTMLElement>(null);\n\n // --- Estados y Opciones del Snackbar ---\n const [snackbarOpen, setSnackbarOpen] = useState(false);\n const [snackbarMessage, setSnackbarMessage] = useState(options?.message || '¡Copiado al portapapeles!');\n const [snackbarSeverity, setSnackbarSeverity] = useState<AlertProps['severity']>(options?.severity || 'success');\n const [snackbarPosition, setSnackbarPosition] = useState<import('@mui/material').SnackbarOrigin>(options?.position || { vertical: 'bottom', horizontal: 'center' });\n const [snackbarDuration, setSnackbarDuration] = useState(options?.duration ?? 3000);\n\n // Función para cerrar el Snackbar\n const handleSnackbarClose = useCallback((event?: React.SyntheticEvent | Event, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n setSnackbarOpen(false);\n }, []);\n\n /**\n * FUNCIÓN PRINCIPAL DE COPIADO.\n * Se usa internamente para 'ref' y se expone para 'copy(text)'.\n * @param text El texto exacto a copiar.\n */\n const executeCopy = useCallback((text: string) => {\n try {\n if (navigator.clipboard && window.isSecureContext) {\n // 1. API moderna\n navigator.clipboard.writeText(text);\n } else {\n // 2. Fallback usando textarea\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n }\n \n // Mostrar éxito\n setSnackbarMessage(options?.message || '¡Copiado al portapapeles!');\n setSnackbarSeverity(options?.severity || 'success');\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n\n } catch (err) {\n // Mostrar error\n console.error('Error al copiar al portapapeles:', err);\n setSnackbarMessage('Error al copiar.');\n setSnackbarSeverity('error');\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n }\n }, [options]); \n\n // --- Lógica del Modo Ref ---\n const copyFromRef = useCallback(() => {\n if (elementRef.current) {\n const textToCopy = elementRef.current.innerText || '';\n executeCopy(textToCopy);\n }\n }, [executeCopy]);\n\n // Adjunta un event listener de clic al elemento referenciado (Modo Ref)\n useEffect(() => {\n const currentElement = elementRef.current;\n if (currentElement) {\n currentElement.style.cursor = 'pointer';\n // Adjuntamos la función que copia el texto del ref\n currentElement.addEventListener('click', copyFromRef);\n }\n\n return () => {\n if (currentElement) {\n currentElement.removeEventListener('click', copyFromRef);\n }\n };\n }, [copyFromRef]);\n\n\n // Componente Snackbar encapsulado. Solo se renderiza si duration es > 0.\n const CopyMessage = () => {\n if (snackbarDuration <= 0) return null; // No renderizar si la duración es 0\n\n return (\n <Snackbar\n open={snackbarOpen}\n autoHideDuration={snackbarDuration}\n onClose={handleSnackbarClose}\n anchorOrigin={snackbarPosition}\n >\n <Alert onClose={handleSnackbarClose} severity={snackbarSeverity} sx={{ width: '100%' }}>\n {snackbarMessage}\n </Alert>\n </Snackbar>\n );\n };\n\n // Retorna ambas funcionalidades para que el usuario elija\n return { ref: elementRef, copy: executeCopy, CopyMessage };\n}\n\nexport default useClipboard;"],"names":["_a"],"mappings":";;;AA0BO,SAAS,aAAa,SAA2B;;AAEtD,QAAM,aAAa,OAAoB,IAAI;AAG3C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,UAAS,mCAAS,YAAW,2BAA2B;AACtG,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,UAAiC,mCAAS,aAAY,SAAS;AAC/G,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,UAAiD,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,SAAA,CAAU;AAClK,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,UAAS,wCAAS,aAAT,YAAqB,GAAI;AAGlF,QAAM,sBAAsB,YAAY,CAAC,OAAsC,WAAoB;AACjG,QAAI,WAAW,aAAa;AAC1B;AAAA,IACF;AACA,oBAAgB,KAAK;AAAA,EACvB,GAAG,CAAA,CAAE;AAOL,QAAM,cAAc,YAAY,CAAC,SAAiB;;AAChD,QAAI;AACF,UAAI,UAAU,aAAa,OAAO,iBAAiB;AAEjD,kBAAU,UAAU,UAAU,IAAI;AAAA,MACpC,OAAO;AAEL,cAAM,WAAW,SAAS,cAAc,UAAU;AAClD,iBAAS,QAAQ;AACjB,iBAAS,KAAK,YAAY,QAAQ;AAClC,iBAAS,OAAA;AACT,iBAAS,YAAY,MAAM;AAC3B,iBAAS,KAAK,YAAY,QAAQ;AAAA,MACpC;AAGA,0BAAmB,mCAAS,YAAW,2BAA2B;AAClE,2BAAoB,mCAAS,aAAY,SAAS;AAClD,2BAAoB,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,UAAU;AACrF,2BAAoBA,MAAA,mCAAS,aAAT,OAAAA,MAAqB,GAAI;AAC7C,sBAAgB,IAAI;AAAA,IAEtB,SAAS,KAAK;AAEZ,cAAQ,MAAM,oCAAoC,GAAG;AACrD,yBAAmB,kBAAkB;AACrC,0BAAoB,OAAO;AAC3B,2BAAoB,mCAAS,aAAY,EAAE,UAAU,UAAU,YAAY,UAAU;AACrF,2BAAoB,wCAAS,aAAT,YAAqB,GAAI;AAC7C,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAGZ,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI,WAAW,SAAS;AACpB,YAAM,aAAa,WAAW,QAAQ,aAAa;AACnD,kBAAY,UAAU;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAGhB,YAAU,MAAM;AACd,UAAM,iBAAiB,WAAW;AAClC,QAAI,gBAAgB;AAClB,qBAAe,MAAM,SAAS;AAE9B,qBAAe,iBAAiB,SAAS,WAAW;AAAA,IACtD;AAEA,WAAO,MAAM;AACX,UAAI,gBAAgB;AAClB,uBAAe,oBAAoB,SAAS,WAAW;AAAA,MACzD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAIhB,QAAM,cAAc,MAAM;AACxB,QAAI,oBAAoB,EAAG,QAAO;AAElC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,kBAAkB;AAAA,QAClB,SAAS;AAAA,QACT,cAAc;AAAA,QAEd,UAAA,oBAAC,OAAA,EAAM,SAAS,qBAAqB,UAAU,kBAAkB,IAAI,EAAE,OAAO,OAAA,GAC3E,UAAA,gBAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAGA,SAAO,EAAE,KAAK,YAAY,MAAM,aAAa,YAAA;AAC/C;"}
1
+ {"version":3,"file":"ClipBoard.js","sources":["../../../src/hooks/ClipBoard/ClipBoard.tsx"],"sourcesContent":["// useClipboard.tsx (Versión Unificada)\nimport React, { useRef, useEffect, useState, useCallback } from 'react';\nimport { Snackbar, Alert } from '@mui/material';\nimport { AlertProps } from '@mui/material/Alert';\n\n// Tipo para las opciones del Snackbar\ninterface SnackbarOptions {\n message?: string;\n duration?: number;\n severity?: AlertProps['severity'];\n position?: { vertical: 'top' | 'bottom'; horizontal: 'left' | 'center' | 'right' };\n}\n\n/**\n * Hook 'useClipboard'.\n * Proporciona funcionalidad de copiado de texto y feedback visual (Snackbar).\n * Permite dos modos de uso:\n * 1. Uso por Referencia (ref): Se adjunta a un elemento, copia su innerText al hacer clic.\n * 2. Uso por Función (copy): Recibe el texto a copiar directamente como argumento.\n *\n * @param options Opciones de configuración para el Snackbar de feedback.\n * @returns Un objeto que contiene:\n * - 'ref': Una React Ref para adjuntar a un elemento (Modo Ref).\n * - 'copy': Una función (text: string) => void para copiar texto (Modo Función).\n * - 'CopyMessage': El componente Snackbar para renderizar el feedback.\n */\nexport function useClipboard(options?: SnackbarOptions) {\n // --- Elementos de Copiado por Referencia ---\n const elementRef = useRef<HTMLElement>(null);\n\n // --- Estados y Opciones del Snackbar ---\n const [snackbarOpen, setSnackbarOpen] = useState(false);\n const [snackbarMessage, setSnackbarMessage] = useState(options?.message || '¡Copiado al portapapeles!');\n const [snackbarSeverity, setSnackbarSeverity] = useState<AlertProps['severity']>(options?.severity || 'success');\n const [snackbarPosition, setSnackbarPosition] = useState<import('@mui/material').SnackbarOrigin>(options?.position || { vertical: 'bottom', horizontal: 'center' });\n const [snackbarDuration, setSnackbarDuration] = useState(options?.duration ?? 3000);\n\n // Función para cerrar el Snackbar\n const handleSnackbarClose = useCallback((event?: React.SyntheticEvent | Event, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n setSnackbarOpen(false);\n }, []);\n\n /**\n * FUNCIÓN PRINCIPAL DE COPIADO.\n * Se usa internamente para 'ref' y se expone para 'copy(text)'.\n * @param text El texto exacto a copiar.\n */\n const mostrarSnackbar = useCallback(\n (mensaje: string, severidad: AlertProps['severity']) => {\n setSnackbarMessage(mensaje);\n setSnackbarSeverity(severidad);\n setSnackbarPosition(options?.position || { vertical: 'bottom', horizontal: 'center' });\n setSnackbarDuration(options?.duration ?? 3000);\n setSnackbarOpen(true);\n },\n [options],\n );\n\n /** Fallback legacy. `execCommand` devuelve `false` en vez de tirar cuando falla. */\n const copiarConTextarea = useCallback((text: string): boolean => {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n // Fuera de la vista pero seleccionable: sin esto la página salta al final.\n textarea.style.position = 'fixed';\n textarea.style.top = '0';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand('copy');\n } catch {\n return false;\n } finally {\n document.body.removeChild(textarea);\n }\n }, []);\n\n const executeCopy = useCallback(\n async (text: string): Promise<boolean> => {\n // `writeText` es ASÍNCRONA: llamarla sin await/catch dejaba la promesa\n // suelta, y cuando el navegador la rechaza —documento sin foco, permiso\n // denegado, contexto no seguro— la rejection escapaba al `window` de la\n // app que consume la librería. El try/catch de antes sólo atrapaba\n // errores síncronos, así que no cubría nada de eso.\n if (navigator.clipboard && window.isSecureContext) {\n try {\n await navigator.clipboard.writeText(text);\n mostrarSnackbar(options?.message || '¡Copiado al portapapeles!', options?.severity || 'success');\n return true;\n } catch {\n // Puede ser sólo falta de foco: se intenta el fallback antes de rendirse.\n }\n }\n\n if (copiarConTextarea(text)) {\n mostrarSnackbar(options?.message || '¡Copiado al portapapeles!', options?.severity || 'success');\n return true;\n }\n\n mostrarSnackbar('No se pudo copiar al portapapeles.', 'error');\n return false;\n },\n [copiarConTextarea, mostrarSnackbar, options],\n );\n\n // --- Lógica del Modo Ref ---\n const copyFromRef = useCallback(() => {\n if (elementRef.current) {\n const textToCopy = elementRef.current.innerText || '';\n // `void`: el listener del DOM no puede esperar la promesa, y ésta ya\n // maneja sus propios errores adentro.\n void executeCopy(textToCopy);\n }\n }, [executeCopy]);\n\n // Adjunta un event listener de clic al elemento referenciado (Modo Ref)\n useEffect(() => {\n const currentElement = elementRef.current;\n if (currentElement) {\n currentElement.style.cursor = 'pointer';\n // Adjuntamos la función que copia el texto del ref\n currentElement.addEventListener('click', copyFromRef);\n }\n\n return () => {\n if (currentElement) {\n currentElement.removeEventListener('click', copyFromRef);\n }\n };\n }, [copyFromRef]);\n\n\n // Componente Snackbar encapsulado. Solo se renderiza si duration es > 0.\n const CopyMessage = () => {\n if (snackbarDuration <= 0) return null; // No renderizar si la duración es 0\n\n return (\n <Snackbar\n open={snackbarOpen}\n autoHideDuration={snackbarDuration}\n onClose={handleSnackbarClose}\n anchorOrigin={snackbarPosition}\n >\n <Alert onClose={handleSnackbarClose} severity={snackbarSeverity} sx={{ width: '100%' }}>\n {snackbarMessage}\n </Alert>\n </Snackbar>\n );\n };\n\n // Retorna ambas funcionalidades para que el usuario elija\n return { ref: elementRef, copy: executeCopy, CopyMessage };\n}\n\nexport default useClipboard;"],"names":["_a"],"mappings":"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"}