siam-ui-utils 3.0.32 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/CustomBootstrap.js +9 -9
  2. package/dist/CustomBootstrap.js.map +1 -1
  3. package/dist/_virtual/_commonjsHelpers.js +7 -7
  4. package/dist/_virtual/events.js +6 -6
  5. package/dist/_virtual/events2.js +5 -5
  6. package/dist/_virtual/index.js +8 -8
  7. package/dist/_virtual/index2.js +5 -5
  8. package/dist/assets/img/copiar.png.js +5 -5
  9. package/dist/assets/img/take-photo.jpg.js +5 -5
  10. package/dist/constants.js +9 -9
  11. package/dist/copy-link/index.js +60 -60
  12. package/dist/copy-link/index.js.map +1 -1
  13. package/dist/copy-link/styles.css +37 -37
  14. package/dist/custom-input/CustomInputCheckbox.js +37 -35
  15. package/dist/custom-input/CustomInputCheckbox.js.map +1 -1
  16. package/dist/custom-input/CustomInputCurrency.js +84 -84
  17. package/dist/custom-input/CustomInputCurrency.js.map +1 -1
  18. package/dist/custom-input/CustomInputFile.js +47 -45
  19. package/dist/custom-input/CustomInputFile.js.map +1 -1
  20. package/dist/custom-input/CustomInputRadio.js +68 -66
  21. package/dist/custom-input/CustomInputRadio.js.map +1 -1
  22. package/dist/custom-input/constant.js +5 -5
  23. package/dist/custom-input/index.js +12 -12
  24. package/dist/drag-and-dropzone/DropzoneComponent.js +83 -0
  25. package/dist/drag-and-dropzone/DropzoneComponent.js.map +1 -0
  26. package/dist/drag-and-dropzone/config.js +59 -59
  27. package/dist/drag-and-dropzone/index.js +39 -39
  28. package/dist/drag-and-dropzone/index.js.map +1 -1
  29. package/dist/dropzone/Input.js +77 -77
  30. package/dist/dropzone/Layout.js +50 -50
  31. package/dist/dropzone/Preview.js +117 -117
  32. package/dist/dropzone/SubmitButton.js +34 -34
  33. package/dist/dropzone/assets/cancel.svg.js +5 -5
  34. package/dist/dropzone/assets/remove.svg.js +5 -5
  35. package/dist/dropzone/assets/restart.svg.js +5 -5
  36. package/dist/dropzone/index.js +514 -514
  37. package/dist/dropzone/utils.js +93 -93
  38. package/dist/dropzone-uploader/base/index.js +135 -135
  39. package/dist/dropzone-uploader/index.js +7 -7
  40. package/dist/dropzone-uploader/styled/index.js +148 -148
  41. package/dist/dropzone-uploader/styled/index.js.map +1 -1
  42. package/dist/iconos/constants-svg.js +666 -666
  43. package/dist/iconos/icon-button-svg.js +50 -50
  44. package/dist/iconos/index.js +24 -24
  45. package/dist/iconos/styled-icon.js +26 -26
  46. package/dist/index.js +4 -4
  47. package/dist/intl-messages/index.js +11 -11
  48. package/dist/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +8 -8
  49. package/dist/node_modules/@babel/runtime/helpers/esm/extends.js +13 -13
  50. package/dist/node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +8 -8
  51. package/dist/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +13 -13
  52. package/dist/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +9 -9
  53. package/dist/node_modules/@neolution-ch/reactstrap/esm/Button.js +111 -0
  54. package/dist/node_modules/@neolution-ch/reactstrap/esm/Button.js.map +1 -0
  55. package/dist/node_modules/@neolution-ch/reactstrap/esm/CloseButton.js +106 -0
  56. package/dist/node_modules/@neolution-ch/reactstrap/esm/CloseButton.js.map +1 -0
  57. package/dist/node_modules/@neolution-ch/reactstrap/esm/Col.js +125 -0
  58. package/dist/node_modules/@neolution-ch/reactstrap/esm/Col.js.map +1 -0
  59. package/dist/node_modules/@neolution-ch/reactstrap/esm/FormGroup.js +75 -0
  60. package/dist/node_modules/@neolution-ch/reactstrap/esm/FormGroup.js.map +1 -0
  61. package/dist/node_modules/@neolution-ch/reactstrap/esm/Input.js +225 -0
  62. package/dist/node_modules/@neolution-ch/reactstrap/esm/Input.js.map +1 -0
  63. package/dist/node_modules/@neolution-ch/reactstrap/esm/Label.js +122 -0
  64. package/dist/node_modules/@neolution-ch/reactstrap/esm/Label.js.map +1 -0
  65. package/dist/node_modules/@neolution-ch/reactstrap/esm/Row.js +83 -0
  66. package/dist/node_modules/@neolution-ch/reactstrap/esm/Row.js.map +1 -0
  67. package/dist/node_modules/@neolution-ch/reactstrap/esm/utils.js +68 -0
  68. package/dist/node_modules/@neolution-ch/reactstrap/esm/utils.js.map +1 -0
  69. package/dist/node_modules/classnames/index.js +62 -62
  70. package/dist/node_modules/dom-helpers/esm/addClass.js +10 -10
  71. package/dist/node_modules/dom-helpers/esm/hasClass.js +8 -8
  72. package/dist/node_modules/dom-helpers/esm/removeClass.js +16 -16
  73. package/dist/node_modules/dropzone/dist/dropzone.js +1968 -0
  74. package/dist/node_modules/dropzone/dist/dropzone.js.map +1 -0
  75. package/dist/node_modules/events/events.js +372 -372
  76. package/dist/node_modules/just-extend/index.esm.js +43 -0
  77. package/dist/node_modules/just-extend/index.esm.js.map +1 -0
  78. package/dist/node_modules/react-transition-group/esm/CSSTransition.js +275 -275
  79. package/dist/node_modules/react-transition-group/esm/Transition.js +441 -441
  80. package/dist/node_modules/react-transition-group/esm/TransitionGroup.js +146 -146
  81. package/dist/node_modules/react-transition-group/esm/TransitionGroupContext.js +6 -6
  82. package/dist/node_modules/react-transition-group/esm/config.js +7 -7
  83. package/dist/node_modules/react-transition-group/esm/utils/ChildMapping.js +100 -100
  84. package/dist/node_modules/react-transition-group/esm/utils/PropTypes.js +24 -24
  85. package/dist/node_modules/react-transition-group/esm/utils/reflow.js +7 -7
  86. package/dist/react-notifications/Notification.js +73 -73
  87. package/dist/react-notifications/NotificationContainer.js +59 -59
  88. package/dist/react-notifications/NotificationManager.js +174 -174
  89. package/dist/react-notifications/Notifications.js +72 -72
  90. package/dist/react-notifications/constants.js +26 -26
  91. package/dist/react-notifications/index.js +11 -11
  92. package/dist/select/custom-select/constants.js +8 -8
  93. package/dist/select/custom-select/index.js +89 -90
  94. package/dist/select/custom-select/index.js.map +1 -1
  95. package/dist/select/custom-select-input/index.js +12 -12
  96. package/dist/select/index.js +9 -9
  97. package/dist/select/multi-select/badge-label-multi-select.js +29 -29
  98. package/dist/select/multi-select/index.css +36 -23
  99. package/dist/select/multi-select/index.js +171 -62
  100. package/dist/select/multi-select/index.js.map +1 -1
  101. package/dist/select/multi-select/styled-component.js +23 -24
  102. package/dist/select/multi-select/styled-component.js.map +1 -1
  103. package/dist/timer/index.js +60 -60
  104. package/dist/timer/styles.css +58 -58
  105. package/dist/tomar-foto/index.js +62 -62
  106. package/dist/tomar-foto/index.js.map +1 -1
  107. package/dist/view-layout/button-editor.js +14 -14
  108. package/dist/view-layout/constants.js +11 -11
  109. package/dist/view-layout/editor-layer.js +28 -28
  110. package/dist/view-layout/index.js +53 -53
  111. package/dist/view-layout/slot-wrapper.js +39 -39
  112. package/dist/view-layout/styles.css +126 -126
  113. package/dist/where-by-room/index.js +20 -20
  114. package/dist/where-by-room/room.js +78 -78
  115. package/index.d.ts +1 -1
  116. package/package.json +12 -10
  117. package/dist/_virtual/react-dropzone.js +0 -8
  118. package/dist/_virtual/react-dropzone.js.map +0 -1
  119. package/dist/_virtual/react-dropzone2.js +0 -5
  120. package/dist/_virtual/react-dropzone2.js.map +0 -1
  121. package/dist/node_modules/react-dropzone-component/dist/react-dropzone.js +0 -1023
  122. package/dist/node_modules/react-dropzone-component/dist/react-dropzone.js.map +0 -1
  123. package/dist/node_modules/react-multi-select-component/dist/esm/index.js +0 -178
  124. package/dist/node_modules/react-multi-select-component/dist/esm/index.js.map +0 -1
@@ -1,62 +1,171 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
3
- import { MultiSelect as je } from "../../node_modules/react-multi-select-component/dist/esm/index.js";
4
- import { Row, Col } from "reactstrap";
5
- import BadgeLabelMultiSelect from "./badge-label-multi-select.js";
6
- import { BadgeWrapper, ClickableBadge } from "./styled-component.js";
7
- import "./index.css";
8
- const CustomMultiSelect = ({
9
- lista = [],
10
- onListaUpdate = () => {
11
- },
12
- value = [],
13
- styles = {}
14
- }) => {
15
- const [selected, setSelected] = useState([]);
16
- const overrideStringsCustom = {
17
- selectSomeItems: "Seleccionar Estado/s",
18
- allItemsAreSelected: "Todos Seleccionados",
19
- search: "Buscar...",
20
- selectAll: "SELECCIONAR TODOS"
21
- };
22
- useEffect(() => {
23
- if (value.length) {
24
- setSelected(value);
25
- }
26
- }, [value]);
27
- const handleCheckChange = (selectedOptions) => {
28
- if (selectedOptions) {
29
- setSelected(selectedOptions);
30
- onListaUpdate(selectedOptions);
31
- }
32
- };
33
- const handleRemoveBadge = (valueToRemove) => {
34
- const updated = selected.filter((item) => item.value !== valueToRemove);
35
- setSelected(updated);
36
- onListaUpdate(updated);
37
- };
38
- return /* @__PURE__ */ jsxs(Row, { className: "align-items-center", children: [
39
- /* @__PURE__ */ jsx(Col, { xs: 6, style: { ...styles }, children: /* @__PURE__ */ jsx(
40
- je,
41
- {
42
- options: lista,
43
- value: selected,
44
- onChange: handleCheckChange,
45
- labelledBy: "Seleccionar",
46
- className: "custom-multiselect",
47
- overrideStrings: overrideStringsCustom
48
- }
49
- ) }),
50
- /* @__PURE__ */ jsx(Col, { xs: 6, style: { marginTop: "0.5rem" }, children: selected.length > 0 && /* @__PURE__ */ jsx(BadgeWrapper, { children: selected.length === lista.length ? /* @__PURE__ */ jsx(ClickableBadge, { color: "info", pill: true, children: "Todos" }) : /* @__PURE__ */ jsx(
51
- BadgeLabelMultiSelect,
52
- {
53
- descripcionLabel: selected,
54
- onRemove: handleRemoveBadge
55
- }
56
- ) }) })
57
- ] });
58
- };
59
- export {
60
- CustomMultiSelect
61
- };
62
- //# sourceMappingURL=index.js.map
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect, useCallback } from "react";
3
+ import Select, { components } from "react-select";
4
+ import { Row, Col } from "reactstrap";
5
+ import { CustomInputCheckbox } from "../../custom-input/CustomInputCheckbox.js";
6
+ import BadgeLabelMultiSelect from "./badge-label-multi-select.js";
7
+ import { BadgeWrapper, ClickableBadge } from "./styled-component.js";
8
+ import "./index.css";
9
+ const SELECT_ALL_VALUE = "__select_all__";
10
+ const SELECT_ALL_OPTION = {
11
+ value: SELECT_ALL_VALUE,
12
+ label: "SELECCIONAR TODOS"
13
+ };
14
+ function CheckboxOption({
15
+ data,
16
+ isSelected,
17
+ isFocused,
18
+ innerRef,
19
+ selectProps
20
+ }) {
21
+ const isSelectAll = data.value === SELECT_ALL_VALUE;
22
+ const handleMouseDown = (e) => {
23
+ e.preventDefault();
24
+ e.stopPropagation();
25
+ if (isSelectAll) {
26
+ selectProps.onSelectAll?.();
27
+ } else {
28
+ selectProps.onOptionClick?.(data);
29
+ }
30
+ };
31
+ return /* @__PURE__ */ jsx(
32
+ "div",
33
+ {
34
+ ref: innerRef,
35
+ onMouseDown: handleMouseDown,
36
+ onTouchEnd: handleMouseDown,
37
+ className: "multiselect-checkbox-option",
38
+ style: {
39
+ backgroundColor: isFocused ? "#f8e1e1" : "white",
40
+ borderBottom: isSelectAll ? "1px solid #ccc" : "none",
41
+ padding: "6px 12px",
42
+ cursor: "pointer"
43
+ },
44
+ children: /* @__PURE__ */ jsx(
45
+ CustomInputCheckbox,
46
+ {
47
+ id: `opt_${data.value}`,
48
+ checked: isSelected,
49
+ onChange: () => {
50
+ },
51
+ label: /* @__PURE__ */ jsx("span", { style: { fontWeight: isSelectAll ? "bold" : "normal" }, children: data.label })
52
+ }
53
+ )
54
+ }
55
+ );
56
+ }
57
+ function CustomValueContainer({ children, getValue, ...props }) {
58
+ const selected = getValue();
59
+ const totalOptions = props.selectProps.options.length - 1;
60
+ const count = selected.length;
61
+ const isAll = count > 0 && count === totalOptions;
62
+ const text = isAll ? "Todos Seleccionados" : count > 0 ? selected.map((s) => s.label).join(", ") : null;
63
+ console.log("selected", selected, text);
64
+ return /* @__PURE__ */ jsxs(components.ValueContainer, { ...props, getValue, children: [
65
+ text ? /* @__PURE__ */ jsx("span", { style: { color: "#333" }, children: text }) : /* @__PURE__ */ jsx(
66
+ "span",
67
+ {
68
+ style: {
69
+ color: count ? "transparent" : "#999",
70
+ position: "absolute"
71
+ },
72
+ children: props.selectProps.placeholder
73
+ }
74
+ ),
75
+ children[children.length - 1]
76
+ ] });
77
+ }
78
+ const CUSTOM_COMPONENTS = {
79
+ Option: CheckboxOption,
80
+ ValueContainer: CustomValueContainer
81
+ };
82
+ const CustomMultiSelect = ({
83
+ lista = [],
84
+ onListaUpdate = () => {
85
+ },
86
+ value = [],
87
+ styles = {}
88
+ }) => {
89
+ const [selected, setSelected] = useState(value);
90
+ const isInternalChange = useRef(false);
91
+ useEffect(() => {
92
+ if (isInternalChange.current) {
93
+ isInternalChange.current = false;
94
+ return;
95
+ }
96
+ setSelected(value);
97
+ }, [JSON.stringify(value)]);
98
+ const update = useCallback(
99
+ (newSelected) => {
100
+ isInternalChange.current = true;
101
+ setSelected(newSelected);
102
+ onListaUpdate(newSelected);
103
+ },
104
+ [onListaUpdate]
105
+ );
106
+ const handleOptionClick = useCallback(
107
+ (data) => {
108
+ setSelected((prev) => {
109
+ const isAlreadySelected = prev.some((s) => s.value === data.value);
110
+ const next = isAlreadySelected ? prev.filter((s) => s.value !== data.value) : [...prev, data];
111
+ isInternalChange.current = true;
112
+ onListaUpdate(next);
113
+ return next;
114
+ });
115
+ },
116
+ [onListaUpdate]
117
+ );
118
+ const handleSelectAll = useCallback(() => {
119
+ setSelected((prev) => {
120
+ const next = prev.length === lista.length ? [] : [...lista];
121
+ isInternalChange.current = true;
122
+ onListaUpdate(next);
123
+ return next;
124
+ });
125
+ }, [lista, onListaUpdate]);
126
+ const handleRemoveBadge = useCallback(
127
+ (valueToRemove) => {
128
+ update(selected.filter((item) => item.value !== valueToRemove));
129
+ },
130
+ [selected, update]
131
+ );
132
+ const allSelected = lista.length > 0 && selected.length === lista.length;
133
+ const optionsWithSelectAll = [SELECT_ALL_OPTION, ...lista];
134
+ const isOptionSelected = useCallback(
135
+ (option) => option.value === SELECT_ALL_VALUE ? allSelected : selected.some((s) => s.value === option.value),
136
+ [allSelected, selected]
137
+ );
138
+ return /* @__PURE__ */ jsxs(Row, { className: "align-items-center", children: [
139
+ /* @__PURE__ */ jsx(Col, { xs: 6, style: styles, children: /* @__PURE__ */ jsx(
140
+ Select,
141
+ {
142
+ options: optionsWithSelectAll,
143
+ value: selected,
144
+ onChange: update,
145
+ isMulti: true,
146
+ placeholder: "Seleccione",
147
+ noOptionsMessage: () => "Sin opciones",
148
+ className: "custom-multiselect",
149
+ classNamePrefix: "custom-multiselect",
150
+ components: CUSTOM_COMPONENTS,
151
+ closeMenuOnSelect: false,
152
+ hideSelectedOptions: false,
153
+ isSearchable: false,
154
+ onSelectAll: handleSelectAll,
155
+ onOptionClick: handleOptionClick,
156
+ isOptionSelected
157
+ }
158
+ ) }),
159
+ /* @__PURE__ */ jsx(Col, { xs: 6, children: selected.length > 0 && /* @__PURE__ */ jsx(BadgeWrapper, { children: allSelected ? /* @__PURE__ */ jsx(ClickableBadge, { color: "info", pill: true, children: "Todos" }) : /* @__PURE__ */ jsx(
160
+ BadgeLabelMultiSelect,
161
+ {
162
+ descripcionLabel: selected,
163
+ onRemove: handleRemoveBadge
164
+ }
165
+ ) }) })
166
+ ] });
167
+ };
168
+ export {
169
+ CustomMultiSelect
170
+ };
171
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/select/multi-select/index.jsx"],"sourcesContent":["import { useEffect, useState } from 'react';\r\nimport { MultiSelect } from 'react-multi-select-component';\r\nimport { Col, Row } from 'reactstrap';\r\nimport BadgeLabelMultiSelect from './badge-label-multi-select';\r\nimport { BadgeWrapper, ClickableBadge } from './styled-component';\r\nimport './index.scss';\r\n\r\nexport const CustomMultiSelect = ({\r\n lista = [],\r\n onListaUpdate = () => { },\r\n value = [],\r\n styles = {},\r\n}) => {\r\n const [selected, setSelected] = useState([]);\r\n const overrideStringsCustom = {\r\n selectSomeItems: 'Seleccionar Estado/s',\r\n allItemsAreSelected: 'Todos Seleccionados',\r\n search: 'Buscar...',\r\n selectAll: 'SELECCIONAR TODOS',\r\n };\r\n\r\n useEffect(() => {\r\n if (value.length) {\r\n setSelected(value);\r\n }\r\n }, [value]);\r\n\r\n const handleCheckChange = (selectedOptions) => {\r\n if (selectedOptions) {\r\n setSelected(selectedOptions);\r\n onListaUpdate(selectedOptions);\r\n }\r\n };\r\n\r\n const handleRemoveBadge = (valueToRemove) => {\r\n const updated = selected.filter((item) => item.value !== valueToRemove);\r\n setSelected(updated);\r\n onListaUpdate(updated);\r\n };\r\n\r\n return (\r\n <Row className=\"align-items-center\" >\r\n <Col xs={6} style={{ ...styles }}>\r\n <MultiSelect\r\n options={lista}\r\n value={selected}\r\n onChange={handleCheckChange}\r\n labelledBy=\"Seleccionar\"\r\n className=\"custom-multiselect\"\r\n overrideStrings={overrideStringsCustom}\r\n />\r\n </Col>\r\n <Col xs={6} style={{ marginTop: '0.5rem' }}>\r\n {selected.length > 0 && (\r\n <BadgeWrapper>\r\n {selected.length === lista.length ? (\r\n <ClickableBadge color=\"info\" pill>\r\n Todos\r\n </ClickableBadge>\r\n ) : (\r\n <BadgeLabelMultiSelect\r\n descripcionLabel={selected}\r\n onRemove={handleRemoveBadge}\r\n />\r\n )}\r\n </BadgeWrapper>\r\n )}\r\n </Col>\r\n </Row>\r\n );\r\n};\r\n\r\nexport default CustomMultiSelect;\r\n"],"names":["MultiSelect"],"mappings":";;;;;;;AAOO,MAAM,oBAAoB,CAAC;AAAA,EAChC,QAAQ,CAAA;AAAA,EACR,gBAAgB,MAAM;AAAA,EAAE;AAAA,EACxB,QAAQ,CAAA;AAAA,EACR,SAAS,CAAA;AACX,MAAM;AACJ,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,CAAA,CAAE;AAC3C,QAAM,wBAAwB;AAAA,IAC5B,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,QAAQ;AAAA,IACR,WAAW;AAAA,EAAA;AAGb,YAAU,MAAM;AACd,QAAI,MAAM,QAAQ;AAChB,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,oBAAoB,CAAC,oBAAoB;AAC7C,QAAI,iBAAiB;AACnB,kBAAY,eAAe;AAC3B,oBAAc,eAAe;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,oBAAoB,CAAC,kBAAkB;AAC3C,UAAM,UAAU,SAAS,OAAO,CAAC,SAAS,KAAK,UAAU,aAAa;AACtE,gBAAY,OAAO;AACnB,kBAAc,OAAO;AAAA,EACvB;AAEA,SACE,qBAAC,KAAA,EAAI,WAAU,sBACb,UAAA;AAAA,IAAA,oBAAC,OAAI,IAAI,GAAG,OAAO,EAAE,GAAG,UACtB,UAAA;AAAA,MAACA;AAAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAW;AAAA,QACX,WAAU;AAAA,QACV,iBAAiB;AAAA,MAAA;AAAA,IAAA,GAErB;AAAA,IACA,oBAAC,KAAA,EAAI,IAAI,GAAG,OAAO,EAAE,WAAW,SAAA,GAC7B,UAAA,SAAS,SAAS,yBAChB,cAAA,EACE,UAAA,SAAS,WAAW,MAAM,SACzB,oBAAC,gBAAA,EAAe,OAAM,QAAO,MAAI,MAAC,UAAA,QAAA,CAElC,IAEA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,kBAAkB;AAAA,QAClB,UAAU;AAAA,MAAA;AAAA,IAAA,GAGhB,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/select/multi-select/index.jsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\r\nimport Select, { components } from 'react-select';\r\nimport { Col, Row } from 'reactstrap';\r\nimport { CustomInputCheckbox } from '../../custom-input/CustomInputCheckbox';\r\nimport BadgeLabelMultiSelect from './badge-label-multi-select';\r\nimport { BadgeWrapper, ClickableBadge } from './styled-component';\r\nimport './index.scss';\r\n\r\nconst SELECT_ALL_VALUE = '__select_all__';\r\nconst SELECT_ALL_OPTION = {\r\n value: SELECT_ALL_VALUE,\r\n label: 'SELECCIONAR TODOS',\r\n};\r\n\r\nfunction CheckboxOption({\r\n data,\r\n isSelected,\r\n isFocused,\r\n innerRef,\r\n selectProps,\r\n}) {\r\n const isSelectAll = data.value === SELECT_ALL_VALUE;\r\n\r\n const handleMouseDown = (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n if (isSelectAll) {\r\n selectProps.onSelectAll?.();\r\n } else {\r\n selectProps.onOptionClick?.(data);\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n ref={innerRef}\r\n onMouseDown={handleMouseDown}\r\n onTouchEnd={handleMouseDown}\r\n className=\"multiselect-checkbox-option\"\r\n style={{\r\n backgroundColor: isFocused ? '#f8e1e1' : 'white',\r\n borderBottom: isSelectAll ? '1px solid #ccc' : 'none',\r\n padding: '6px 12px',\r\n cursor: 'pointer',\r\n }}\r\n >\r\n <CustomInputCheckbox\r\n id={`opt_${data.value}`}\r\n checked={isSelected}\r\n onChange={() => {}}\r\n label={\r\n <span style={{ fontWeight: isSelectAll ? 'bold' : 'normal' }}>\r\n {data.label}\r\n </span>\r\n }\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nfunction CustomValueContainer({ children, getValue, ...props }) {\r\n const selected = getValue();\r\n const totalOptions = props.selectProps.options.length - 1;\r\n const count = selected.length;\r\n const isAll = count > 0 && count === totalOptions;\r\n\r\n const text = isAll\r\n ? 'Todos Seleccionados'\r\n : count > 0\r\n ? selected.map((s) => s.label).join(', ')\r\n : null;\r\n console.log('selected', selected, text);\r\n\r\n return (\r\n <components.ValueContainer {...props} getValue={getValue}>\r\n {text ? (\r\n <span style={{ color: '#333' }}>{text}</span>\r\n ) : (\r\n <span\r\n style={{\r\n color: count ? 'transparent' : '#999',\r\n position: 'absolute',\r\n }}\r\n >\r\n {props.selectProps.placeholder}\r\n </span>\r\n )}\r\n {children[children.length - 1]}\r\n </components.ValueContainer>\r\n );\r\n}\r\n\r\nconst CUSTOM_COMPONENTS = {\r\n Option: CheckboxOption,\r\n ValueContainer: CustomValueContainer,\r\n};\r\n\r\nexport const CustomMultiSelect = ({\r\n lista = [],\r\n onListaUpdate = () => {},\r\n value = [],\r\n styles = {},\r\n}) => {\r\n const [selected, setSelected] = useState(value);\r\n const isInternalChange = useRef(false);\r\n\r\n useEffect(() => {\r\n if (isInternalChange.current) {\r\n isInternalChange.current = false;\r\n return;\r\n }\r\n setSelected(value);\r\n }, [JSON.stringify(value)]); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n const update = useCallback(\r\n (newSelected) => {\r\n isInternalChange.current = true;\r\n setSelected(newSelected);\r\n onListaUpdate(newSelected);\r\n },\r\n [onListaUpdate]\r\n );\r\n\r\n const handleOptionClick = useCallback(\r\n (data) => {\r\n setSelected((prev) => {\r\n const isAlreadySelected = prev.some((s) => s.value === data.value);\r\n const next = isAlreadySelected\r\n ? prev.filter((s) => s.value !== data.value)\r\n : [...prev, data];\r\n isInternalChange.current = true;\r\n onListaUpdate(next);\r\n return next;\r\n });\r\n },\r\n [onListaUpdate]\r\n );\r\n\r\n const handleSelectAll = useCallback(() => {\r\n setSelected((prev) => {\r\n const next = prev.length === lista.length ? [] : [...lista];\r\n isInternalChange.current = true;\r\n onListaUpdate(next);\r\n return next;\r\n });\r\n }, [lista, onListaUpdate]);\r\n\r\n const handleRemoveBadge = useCallback(\r\n (valueToRemove) => {\r\n update(selected.filter((item) => item.value !== valueToRemove));\r\n },\r\n [selected, update]\r\n );\r\n\r\n const allSelected = lista.length > 0 && selected.length === lista.length;\r\n const optionsWithSelectAll = [SELECT_ALL_OPTION, ...lista];\r\n\r\n const isOptionSelected = useCallback(\r\n (option) =>\r\n option.value === SELECT_ALL_VALUE\r\n ? allSelected\r\n : selected.some((s) => s.value === option.value),\r\n [allSelected, selected]\r\n );\r\n\r\n return (\r\n <Row className=\"align-items-center\">\r\n <Col xs={6} style={styles}>\r\n <Select\r\n options={optionsWithSelectAll}\r\n value={selected}\r\n onChange={update}\r\n isMulti\r\n placeholder=\"Seleccione\"\r\n noOptionsMessage={() => 'Sin opciones'}\r\n className=\"custom-multiselect\"\r\n classNamePrefix=\"custom-multiselect\"\r\n components={CUSTOM_COMPONENTS}\r\n closeMenuOnSelect={false}\r\n hideSelectedOptions={false}\r\n isSearchable={false}\r\n onSelectAll={handleSelectAll}\r\n onOptionClick={handleOptionClick}\r\n isOptionSelected={isOptionSelected}\r\n />\r\n </Col>\r\n <Col xs={6}>\r\n {selected.length > 0 && (\r\n <BadgeWrapper>\r\n {allSelected ? (\r\n <ClickableBadge color=\"info\" pill>\r\n Todos\r\n </ClickableBadge>\r\n ) : (\r\n <BadgeLabelMultiSelect\r\n descripcionLabel={selected}\r\n onRemove={handleRemoveBadge}\r\n />\r\n )}\r\n </BadgeWrapper>\r\n )}\r\n </Col>\r\n </Row>\r\n );\r\n};\r\n\r\nexport default CustomMultiSelect;\r\n"],"names":[],"mappings":"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"}
@@ -1,24 +1,23 @@
1
- import { Badge } from "reactstrap";
2
- import styled from "styled-components";
3
- const ClickableBadge = styled(Badge)`
4
- cursor: pointer;
5
- width: fit-content;
6
- white-space: nowrap;
7
- `;
8
- const BadgeWrapper = styled.div`
9
- display: inline-flex;
10
- flex-wrap: nowrap;
11
- gap: 10px;
12
- padding: 0.5rem;
13
- border-radius: 0.5rem;
14
- background-color: #f1f1f1;
15
- border: 1px solid #ccc;
16
- margin-top: 2.8rem;
17
- max-width: 120%;
18
- overflow-x: auto;
19
- `;
20
- export {
21
- BadgeWrapper,
22
- ClickableBadge
23
- };
24
- //# sourceMappingURL=styled-component.js.map
1
+ import { Badge } from "reactstrap";
2
+ import styled from "styled-components";
3
+ const ClickableBadge = styled(Badge)`
4
+ cursor: pointer;
5
+ width: fit-content;
6
+ white-space: nowrap;
7
+ `;
8
+ const BadgeWrapper = styled.div`
9
+ display: inline-flex;
10
+ flex-wrap: wrap;
11
+ gap: 10px;
12
+ padding: 0.5rem;
13
+ border-radius: 0.5rem;
14
+ background-color: #f1f1f1;
15
+ border: 1px solid #ccc;
16
+ max-width: 100%;
17
+ overflow-x: auto;
18
+ `;
19
+ export {
20
+ BadgeWrapper,
21
+ ClickableBadge
22
+ };
23
+ //# sourceMappingURL=styled-component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styled-component.js","sources":["../../../src/select/multi-select/styled-component.js"],"sourcesContent":["import { Badge } from 'reactstrap';\r\nimport styled from 'styled-components';\r\n\r\nexport const ClickableBadge = styled(Badge)`\r\n cursor: pointer;\r\n width: fit-content;\r\n white-space: nowrap;\r\n`;\r\n\r\nexport const BadgeWrapper = styled.div`\r\n display: inline-flex;\r\n flex-wrap: nowrap;\r\n gap: 10px;\r\n padding: 0.5rem;\r\n border-radius: 0.5rem;\r\n background-color: #f1f1f1;\r\n border: 1px solid #ccc;\r\n margin-top: 2.8rem;\r\n max-width: 120%;\r\n overflow-x: auto;\r\n`;\r\n"],"names":[],"mappings":";;AAGY,MAAC,iBAAiB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAM9B,MAAC,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"styled-component.js","sources":["../../../src/select/multi-select/styled-component.js"],"sourcesContent":["import { Badge } from 'reactstrap';\r\nimport styled from 'styled-components';\r\n\r\nexport const ClickableBadge = styled(Badge)`\r\n cursor: pointer;\r\n width: fit-content;\r\n white-space: nowrap;\r\n`;\r\n\r\nexport const BadgeWrapper = styled.div`\r\n display: inline-flex;\r\n flex-wrap: wrap;\r\n gap: 10px;\r\n padding: 0.5rem;\r\n border-radius: 0.5rem;\r\n background-color: #f1f1f1;\r\n border: 1px solid #ccc;\r\n max-width: 100%;\r\n overflow-x: auto;\r\n`;\r\n"],"names":[],"mappings":";;AAGY,MAAC,iBAAiB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAM9B,MAAC,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
@@ -1,60 +1,60 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect } from "react";
3
- import "./styles.css";
4
- const formatTiempo = (ms) => {
5
- if (ms == null) return "--:--";
6
- const absMs = Math.abs(ms);
7
- const totalSec = Math.floor(absMs / 1e3);
8
- const min = Math.floor(totalSec / 60);
9
- const sec = totalSec % 60;
10
- const formatted = `${min.toString().padStart(2, "0")}:${sec.toString().padStart(2, "0")}`;
11
- return ms < 0 ? `-${formatted}` : formatted;
12
- };
13
- const getTimerColorClass = (ms, maxTime) => {
14
- if (!maxTime) return "";
15
- const percent = ms / maxTime;
16
- if (percent > 0.33) return "timer-green";
17
- if (percent > 0.15) return "timer-yellow";
18
- if (percent > 0) return "timer-red";
19
- if (ms === 0) return "timer-out";
20
- if (ms < 0) return "timer-over";
21
- return "";
22
- };
23
- const Timer = ({
24
- initialMinutes = 0,
25
- icon = true,
26
- className = "",
27
- active = true,
28
- style = {}
29
- }) => {
30
- const initialMs = initialMinutes * 60 * 1e3;
31
- const [ms, setMs] = useState(initialMs);
32
- const intervalRef = useRef();
33
- useEffect(() => {
34
- if (!active) return;
35
- intervalRef.current = setInterval(() => {
36
- setMs((prev) => prev - 1e3);
37
- }, 1e3);
38
- return () => clearInterval(intervalRef.current);
39
- }, [active]);
40
- useEffect(() => {
41
- setMs(initialMs);
42
- }, [initialMs]);
43
- const timerColorClass = getTimerColorClass(ms, initialMs);
44
- return /* @__PURE__ */ jsxs(
45
- "span",
46
- {
47
- className: `av-video-timer timer ${timerColorClass} ${className}`,
48
- style,
49
- children: [
50
- icon && /* @__PURE__ */ jsx("i", { className: "icon-clock timer" }),
51
- formatTiempo(ms)
52
- ]
53
- }
54
- );
55
- };
56
- export {
57
- Timer,
58
- formatTiempo
59
- };
60
- //# sourceMappingURL=index.js.map
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect } from "react";
3
+ import "./styles.css";
4
+ const formatTiempo = (ms) => {
5
+ if (ms == null) return "--:--";
6
+ const absMs = Math.abs(ms);
7
+ const totalSec = Math.floor(absMs / 1e3);
8
+ const min = Math.floor(totalSec / 60);
9
+ const sec = totalSec % 60;
10
+ const formatted = `${min.toString().padStart(2, "0")}:${sec.toString().padStart(2, "0")}`;
11
+ return ms < 0 ? `-${formatted}` : formatted;
12
+ };
13
+ const getTimerColorClass = (ms, maxTime) => {
14
+ if (!maxTime) return "";
15
+ const percent = ms / maxTime;
16
+ if (percent > 0.33) return "timer-green";
17
+ if (percent > 0.15) return "timer-yellow";
18
+ if (percent > 0) return "timer-red";
19
+ if (ms === 0) return "timer-out";
20
+ if (ms < 0) return "timer-over";
21
+ return "";
22
+ };
23
+ const Timer = ({
24
+ initialMinutes = 0,
25
+ icon = true,
26
+ className = "",
27
+ active = true,
28
+ style = {}
29
+ }) => {
30
+ const initialMs = initialMinutes * 60 * 1e3;
31
+ const [ms, setMs] = useState(initialMs);
32
+ const intervalRef = useRef();
33
+ useEffect(() => {
34
+ if (!active) return;
35
+ intervalRef.current = setInterval(() => {
36
+ setMs((prev) => prev - 1e3);
37
+ }, 1e3);
38
+ return () => clearInterval(intervalRef.current);
39
+ }, [active]);
40
+ useEffect(() => {
41
+ setMs(initialMs);
42
+ }, [initialMs]);
43
+ const timerColorClass = getTimerColorClass(ms, initialMs);
44
+ return /* @__PURE__ */ jsxs(
45
+ "span",
46
+ {
47
+ className: `av-video-timer timer ${timerColorClass} ${className}`,
48
+ style,
49
+ children: [
50
+ icon && /* @__PURE__ */ jsx("i", { className: "icon-clock timer" }),
51
+ formatTiempo(ms)
52
+ ]
53
+ }
54
+ );
55
+ };
56
+ export {
57
+ Timer,
58
+ formatTiempo
59
+ };
60
+ //# sourceMappingURL=index.js.map
@@ -1,59 +1,59 @@
1
- .av-video-timer {
2
- color: inherit;
3
- margin: 0 12px;
4
- flex: 1;
5
- text-align: center;
6
- display: flex;
7
- justify-content: center;
8
- font-weight: bold;
9
- align-items: center;
10
- font-size: 1.3em;
11
- width: 100%;
12
- margin: 8px 0;
13
- }
14
-
15
- .timer {
16
- font-size: clamp(5px, 2vw, 20px);
17
- margin-right: 4px;
18
- }
19
-
20
- .timer-green {
21
- color: #28a745;
22
- }
23
-
24
- .timer-yellow {
25
- color: #ffc107;
26
- }
27
-
28
- .timer-red {
29
- color: #bd0300;
30
- }
31
-
32
- @keyframes vibrate {
33
- 0% {
34
- transform: translateX(0);
35
- }
36
- 20% {
37
- transform: translateX(-3px);
38
- }
39
- 40% {
40
- transform: translateX(3px);
41
- }
42
- 60% {
43
- transform: translateX(-3px);
44
- }
45
- 80% {
46
- transform: translateX(3px);
47
- }
48
- 100% {
49
- transform: translateX(0);
50
- }
51
- }
52
- .timer-out {
53
- color: #000000;
54
- animation: vibrate 0.3s linear infinite;
55
- }
56
-
57
- .timer-over {
58
- color: #c00805;
1
+ .av-video-timer {
2
+ color: inherit;
3
+ margin: 0 12px;
4
+ flex: 1;
5
+ text-align: center;
6
+ display: flex;
7
+ justify-content: center;
8
+ font-weight: bold;
9
+ align-items: center;
10
+ font-size: 1.3em;
11
+ width: 100%;
12
+ margin: 8px 0;
13
+ }
14
+
15
+ .timer {
16
+ font-size: clamp(5px, 2vw, 20px);
17
+ margin-right: 4px;
18
+ }
19
+
20
+ .timer-green {
21
+ color: #28a745;
22
+ }
23
+
24
+ .timer-yellow {
25
+ color: #ffc107;
26
+ }
27
+
28
+ .timer-red {
29
+ color: #bd0300;
30
+ }
31
+
32
+ @keyframes vibrate {
33
+ 0% {
34
+ transform: translateX(0);
35
+ }
36
+ 20% {
37
+ transform: translateX(-3px);
38
+ }
39
+ 40% {
40
+ transform: translateX(3px);
41
+ }
42
+ 60% {
43
+ transform: translateX(-3px);
44
+ }
45
+ 80% {
46
+ transform: translateX(3px);
47
+ }
48
+ 100% {
49
+ transform: translateX(0);
50
+ }
51
+ }
52
+ .timer-out {
53
+ color: #000000;
54
+ animation: vibrate 0.3s linear infinite;
55
+ }
56
+
57
+ .timer-over {
58
+ color: #c00805;
59
59
  }