@widergy/energy-ui 3.141.4 → 3.142.1

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [3.142.1](https://github.com/widergy/energy-ui/compare/v3.142.0...v3.142.1) (2026-04-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * [DEV-766] remove --cache flag from eslint lint scripts ([#776](https://github.com/widergy/energy-ui/issues/776)) ([06d63d0](https://github.com/widergy/energy-ui/commit/06d63d06b96893c05b7a031d26f254dda5c3e613))
7
+
8
+ # [3.142.0](https://github.com/widergy/energy-ui/compare/v3.141.4...v3.142.0) (2026-04-14)
9
+
10
+
11
+ ### Features
12
+
13
+ * [AXCH-1428] wrapper observation component ([#773](https://github.com/widergy/energy-ui/issues/773)) ([afb9df4](https://github.com/widergy/energy-ui/commit/afb9df458b74a543254473724644e79662f37d6b))
14
+
1
15
  ## [3.141.4](https://github.com/widergy/energy-ui/compare/v3.141.3...v3.141.4) (2026-04-14)
2
16
 
3
17
 
@@ -0,0 +1,91 @@
1
+ # UTWrapperObservation
2
+
3
+ Wrapper que agrega acciones (ícono + tooltip) a un campo de formulario. Muestra todos los botones configurados en `observationWrapperConfiguration`, cambiando el layout según si hay observaciones activas en `field`. Soporta N acciones simultáneas.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `children` | `node` | Required | Contenido del campo a envolver. |
10
+ | `dataTestId` | `string` | `undefined` | ID para testing. El container recibe `dataTestId` y cada action icon recibe `${dataTestId}.actionIcon.${config.key}`. |
11
+ | `field` | `objectOf(bool)` | `undefined` | Objeto del campo. Las claves con valor `true` que coincidan con algún `key` en `observationWrapperConfiguration` renderizarán su acción correspondiente. |
12
+ | `observationWrapperConfiguration` | `arrayOf(shape)` | `undefined` | Array de configuraciones para el wrapper. Ver estructura abajo. |
13
+
14
+ ### Estructura de `observationWrapperConfiguration`
15
+
16
+ Cada objeto del array puede contener:
17
+
18
+ | Campo | Type | Description |
19
+ |-------|------|-------------|
20
+ | `key` | `string` | Identificador de la acción. Si coincide con una clave `true` en `field`, determina que hay observaciones activas y cambia el layout a gap inline. |
21
+ | `buttonProps` | `object` | Props pasados directamente al componente `UTButton` que se renderiza como ícono de acción. |
22
+ | `action` | `func` | Callback ejecutado al hacer click sobre el botón de acción. |
23
+ | `textTooltip` | `string` | Texto que se muestra en el tooltip al hacer hover sobre el botón. |
24
+
25
+ ## Lógica de renderizado
26
+
27
+ ```
28
+ observationWrapperConfiguration vacío o undefined → retorna children sin wrapping
29
+ sin coincidencias en field → renderiza wrapper con todos los botones en position:absolute (se revelan en hover)
30
+ con al menos una coincidencia en field → renderiza wrapper con gap + todos los botones (se revelan en hover)
31
+ ```
32
+
33
+ ## Ejemplos
34
+
35
+ ### Uso básico (con observación activa)
36
+
37
+ ```jsx
38
+ const observationConfig = [
39
+ {
40
+ key: 'observation',
41
+ buttonProps: {
42
+ children: '2',
43
+ colorTheme: 'negative',
44
+ Icon: 'IconMessagePlus',
45
+ size: 'small'
46
+ },
47
+ action: () => console.log('Observación ejecutada'),
48
+ textTooltip: 'Observar campo'
49
+ }
50
+ ];
51
+
52
+ <UTWrapperObservation
53
+ field={{ observation: true }}
54
+ observationWrapperConfiguration={observationConfig}
55
+ >
56
+ <UTLabel variant="body1">0112 4567890</UTLabel>
57
+ </UTWrapperObservation>
58
+ ```
59
+
60
+ ### Sin observación activa (field.observation false)
61
+
62
+ ```jsx
63
+ <UTWrapperObservation
64
+ field={{ observation: false }}
65
+ observationWrapperConfiguration={observationConfig}
66
+ >
67
+ <UTLabel variant="body1">0112 4567890</UTLabel>
68
+ </UTWrapperObservation>
69
+ // → renderiza el wrapper con los botones en position:absolute encima del children
70
+ // los botones se revelan al hacer hover
71
+ ```
72
+
73
+ ### Múltiples acciones
74
+
75
+ ```jsx
76
+ <UTWrapperObservation
77
+ field={{ observation: true, review: true }}
78
+ observationWrapperConfiguration={[
79
+ { key: 'observation', ... },
80
+ { key: 'review', ... }
81
+ ]}
82
+ >
83
+ <UTLabel variant="body1">0112 4567890</UTLabel>
84
+ </UTWrapperObservation>
85
+ // → renderiza children + 2 botones con tooltip
86
+ ```
87
+
88
+ ## Componentes relacionados
89
+
90
+ - **UTButton**: Usado internamente para el botón de acción.
91
+ - **UTTooltip**: Usado para mostrar el `textTooltip` al hacer hover sobre el botón.
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.SinObservacionEnField = exports.SinConfiguracion = exports.Playground = exports.ConObservacion = exports.ConMultiplesAcciones = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _UTLabel = _interopRequireDefault(require("../UTLabel"));
9
+ var _ = _interopRequireDefault(require("."));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /* eslint-disable no-alert */
12
+ const observationConfig = [{
13
+ buttonProps: {
14
+ colorTheme: 'negative',
15
+ Icon: 'IconMessagePlus',
16
+ size: 'small'
17
+ },
18
+ action: () => alert('Acción de observación ejecutada'),
19
+ key: 'observation',
20
+ textTooltip: 'Observar campo'
21
+ }];
22
+ const multipleActionsConfig = [{
23
+ buttonProps: {
24
+ colorTheme: 'negative',
25
+ Icon: 'IconMessagePlus',
26
+ size: 'small'
27
+ },
28
+ action: () => alert('Acción de observación ejecutada'),
29
+ key: 'observation',
30
+ textTooltip: 'Observar campo'
31
+ }, {
32
+ buttonProps: {
33
+ colorTheme: 'blue',
34
+ Icon: 'IconFlag',
35
+ size: 'small'
36
+ },
37
+ action: () => alert('Acción de revisión ejecutada'),
38
+ key: 'review',
39
+ textTooltip: 'Revisar campo'
40
+ }];
41
+ const FieldContent = () => /*#__PURE__*/_react.default.createElement("div", {
42
+ style: {
43
+ display: 'flex',
44
+ flexDirection: 'column',
45
+ gap: '4px'
46
+ }
47
+ }, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
48
+ colorTheme: "gray",
49
+ variant: "caption"
50
+ }, "Tel\xE9fono *"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
51
+ variant: "body1"
52
+ }, "0112 4567890"));
53
+ var _default = exports.default = {
54
+ args: {
55
+ field: {
56
+ observation: true
57
+ },
58
+ observationWrapperConfiguration: observationConfig
59
+ },
60
+ argTypes: {
61
+ field: {
62
+ control: 'object',
63
+ description: 'Objeto del campo. Las claves con valor `true` que coincidan con algún `key` en `observationWrapperConfiguration` renderizarán su acción correspondiente.',
64
+ table: {
65
+ defaultValue: {
66
+ summary: 'undefined'
67
+ },
68
+ type: {
69
+ summary: 'objectOf(bool)'
70
+ }
71
+ }
72
+ },
73
+ observationWrapperConfiguration: {
74
+ control: false,
75
+ description: 'Array de acciones disponibles para el wrapper. Cada objeto debe tener `key`, `buttonProps`, `action` y `textTooltip`. Todos los botones se muestran siempre; el `key` se usa para detectar si hay observaciones activas en `field` y cambiar el layout.',
76
+ table: {
77
+ defaultValue: {
78
+ summary: 'undefined'
79
+ },
80
+ type: {
81
+ summary: 'arrayOf(shape({ key, buttonProps, action, textTooltip }))'
82
+ }
83
+ }
84
+ },
85
+ children: {
86
+ control: false,
87
+ description: 'Contenido del campo a envolver.',
88
+ table: {
89
+ defaultValue: {
90
+ summary: 'undefined'
91
+ },
92
+ type: {
93
+ summary: 'ReactNode'
94
+ }
95
+ }
96
+ },
97
+ dataTestId: {
98
+ control: 'text',
99
+ description: 'ID para testing. El container recibe `dataTestId` y cada action icon recibe `${dataTestId}.actionIcon.${config.key}`.',
100
+ table: {
101
+ defaultValue: {
102
+ summary: 'undefined'
103
+ },
104
+ type: {
105
+ summary: 'string'
106
+ }
107
+ }
108
+ }
109
+ },
110
+ component: _.default,
111
+ parameters: {
112
+ backgrounds: {
113
+ default: 'light03',
114
+ values: [{
115
+ name: 'light03',
116
+ value: '#F4F5F7'
117
+ }]
118
+ },
119
+ docs: {
120
+ description: {
121
+ component: 'Wrapper que agrega acciones (ícono + tooltip) a un campo de formulario. ' + 'Muestra todos los botones de `observationWrapperConfiguration` siempre que haya al menos uno configurado. ' + 'Si algún `key` de la configuración coincide con una clave `true` en `field`, aplica un gap entre el children y los botones; ' + 'si no hay coincidencias, los botones se posicionan encima del children y se revelan en hover.'
122
+ }
123
+ }
124
+ },
125
+ title: 'Energy-UI/UTWrapperObservation'
126
+ };
127
+ const ConObservacion = exports.ConObservacion = {
128
+ args: {
129
+ children: /*#__PURE__*/_react.default.createElement(FieldContent, null),
130
+ field: {
131
+ observation: true
132
+ },
133
+ observationWrapperConfiguration: observationConfig
134
+ },
135
+ name: 'Con observación activa',
136
+ parameters: {
137
+ docs: {
138
+ description: {
139
+ story: 'Campo con `field.observation: true` y configuración válida. Se muestra el ícono de observación ' + 'a la derecha del campo. Al hacer hover sobre el ícono aparece el tooltip; al hacer click se ejecuta la acción.'
140
+ }
141
+ }
142
+ }
143
+ };
144
+ const SinObservacionEnField = exports.SinObservacionEnField = {
145
+ args: {
146
+ children: /*#__PURE__*/_react.default.createElement(FieldContent, null),
147
+ field: {
148
+ observation: false
149
+ },
150
+ observationWrapperConfiguration: observationConfig
151
+ },
152
+ name: 'Sin observación activa',
153
+ parameters: {
154
+ docs: {
155
+ description: {
156
+ story: '`field.observation` es `false`. El componente renderiza el wrapper con los botones posicionados encima del children (`position: absolute`). Los botones se revelan al hacer hover.'
157
+ }
158
+ }
159
+ }
160
+ };
161
+ const SinConfiguracion = exports.SinConfiguracion = {
162
+ args: {
163
+ children: /*#__PURE__*/_react.default.createElement(FieldContent, null),
164
+ field: {
165
+ observation: true
166
+ },
167
+ observationWrapperConfiguration: []
168
+ },
169
+ name: 'Sin configuración (fallback)',
170
+ parameters: {
171
+ docs: {
172
+ description: {
173
+ story: '`field.observation: true` pero sin acciones en `observationWrapperConfiguration`. ' + 'El componente devuelve los `children` sin wrapping.'
174
+ }
175
+ }
176
+ }
177
+ };
178
+ const ConMultiplesAcciones = exports.ConMultiplesAcciones = {
179
+ args: {
180
+ children: /*#__PURE__*/_react.default.createElement(FieldContent, null),
181
+ field: {
182
+ observation: true,
183
+ review: true
184
+ },
185
+ observationWrapperConfiguration: multipleActionsConfig
186
+ },
187
+ name: 'Múltiples acciones',
188
+ parameters: {
189
+ docs: {
190
+ description: {
191
+ story: 'Campo con dos acciones activas (`field.observation: true` y `field.review: true`). ' + 'Se renderiza un botón por cada entrada de `observationWrapperConfiguration` cuya `key` coincida con un valor `true` en `field`.'
192
+ }
193
+ }
194
+ }
195
+ };
196
+ const Playground = exports.Playground = {
197
+ args: {
198
+ children: /*#__PURE__*/_react.default.createElement(FieldContent, null),
199
+ field: {
200
+ observation: true
201
+ },
202
+ configJSON: [{
203
+ key: 'observation',
204
+ textTooltip: '2 Campos observados',
205
+ buttonProps: {
206
+ colorTheme: 'gray',
207
+ Icon: 'IconMessagePlus',
208
+ size: 'small',
209
+ children: 2,
210
+ variant: 'semitransparent'
211
+ }
212
+ }]
213
+ },
214
+ argTypes: {
215
+ field: {
216
+ control: {
217
+ type: 'object'
218
+ }
219
+ },
220
+ configJSON: {
221
+ control: {
222
+ type: 'object'
223
+ },
224
+ description: 'Array de acciones para el wrapper. Editá el JSON para agregar o quitar botones. El `action` se inyecta automáticamente.',
225
+ name: 'observationWrapperConfiguration',
226
+ table: {
227
+ type: {
228
+ summary: 'arrayOf(shape({ key, buttonProps, textTooltip }))'
229
+ }
230
+ }
231
+ },
232
+ observationWrapperConfiguration: {
233
+ table: {
234
+ disable: true
235
+ }
236
+ }
237
+ },
238
+ name: 'Playground',
239
+ render: _ref => {
240
+ let {
241
+ configJSON,
242
+ ...args
243
+ } = _ref;
244
+ return /*#__PURE__*/_react.default.createElement(_.default, _extends({}, args, {
245
+ observationWrapperConfiguration: configJSON === null || configJSON === void 0 ? void 0 : configJSON.map(config => ({
246
+ ...config,
247
+ action: () => alert("Acci\xF3n ejecutada: ".concat(config.key)) // eslint-disable-line no-alert
248
+ }))
249
+ }), args.children);
250
+ }
251
+ };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _propTypes = require("prop-types");
9
+ var _UTTooltip = _interopRequireDefault(require("../UTTooltip"));
10
+ var _UTButton = _interopRequireDefault(require("../UTButton"));
11
+ var _lodash = require("lodash");
12
+ var _stylesModule = _interopRequireDefault(require("./styles.module.scss"));
13
+ var _utils = require("./utils");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ const UTWrapperObservation = _ref => {
16
+ let {
17
+ field,
18
+ observationWrapperConfiguration,
19
+ children,
20
+ dataTestId
21
+ } = _ref;
22
+ const matchingConfigs = (0, _utils.getMatchingConfigs)(observationWrapperConfiguration, field);
23
+ const hasObservation = !(0, _lodash.isEmpty)(matchingConfigs);
24
+ if (!(observationWrapperConfiguration !== null && observationWrapperConfiguration !== void 0 && observationWrapperConfiguration.length)) {
25
+ return children;
26
+ }
27
+ return /*#__PURE__*/_react.default.createElement("div", {
28
+ className: "".concat(_stylesModule.default.container, " ").concat(hasObservation ? _stylesModule.default.withObservation : ''),
29
+ "data-testid": dataTestId
30
+ }, children, /*#__PURE__*/_react.default.createElement("div", {
31
+ className: _stylesModule.default.actionButtons
32
+ }, observationWrapperConfiguration.map(config => /*#__PURE__*/_react.default.createElement(_UTTooltip.default, {
33
+ key: config.key,
34
+ arrow: false,
35
+ content: config.textTooltip,
36
+ tippyProps: {
37
+ appendTo: () => document.body,
38
+ interactive: false
39
+ }
40
+ }, /*#__PURE__*/_react.default.createElement("div", {
41
+ className: _stylesModule.default.iconButton,
42
+ onClick: config.action,
43
+ role: "button",
44
+ tabIndex: 0,
45
+ "data-testid": dataTestId ? "".concat(dataTestId, ".actionIcon.").concat(config.key) : undefined
46
+ }, /*#__PURE__*/_react.default.createElement(_UTButton.default, config.buttonProps))))));
47
+ };
48
+ UTWrapperObservation.propTypes = {
49
+ children: _propTypes.node.isRequired,
50
+ dataTestId: _propTypes.string,
51
+ field: (0, _propTypes.objectOf)(_propTypes.bool),
52
+ observationWrapperConfiguration: (0, _propTypes.arrayOf)((0, _propTypes.shape)({
53
+ action: _propTypes.func,
54
+ buttonProps: _propTypes.object,
55
+ key: _propTypes.string,
56
+ textTooltip: _propTypes.string
57
+ }))
58
+ };
59
+ var _default = exports.default = UTWrapperObservation;
@@ -0,0 +1,37 @@
1
+ .actionButtons {
2
+ align-items: center;
3
+ display: flex;
4
+ gap: var(--gap-sm);
5
+ position: absolute;
6
+ right: 0;
7
+ }
8
+
9
+ .container {
10
+ align-items: center;
11
+ display: flex;
12
+ flex-direction: row;
13
+ position: relative;
14
+ width: max-content;
15
+
16
+ &:hover .iconButton {
17
+ opacity: 1;
18
+ }
19
+ }
20
+
21
+ .iconButton {
22
+ align-items: center;
23
+ cursor: pointer;
24
+ display: flex;
25
+ flex-shrink: 0;
26
+ justify-content: center;
27
+ opacity: 0;
28
+ transition: opacity 0.2s ease;
29
+ }
30
+
31
+ .withObservation {
32
+ gap: var(--gap-sm);
33
+
34
+ .actionButtons {
35
+ position: static;
36
+ }
37
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getMatchingConfigs = void 0;
7
+ const getMatchingConfigs = (observationWrapperConfiguration, field) => {
8
+ var _observationWrapperCo;
9
+ return (_observationWrapperCo = observationWrapperConfiguration === null || observationWrapperConfiguration === void 0 ? void 0 : observationWrapperConfiguration.filter(config => (field === null || field === void 0 ? void 0 : field[config.key]) === true)) !== null && _observationWrapperCo !== void 0 ? _observationWrapperCo : [];
10
+ };
11
+ exports.getMatchingConfigs = getMatchingConfigs;
@@ -162,6 +162,9 @@ const TEST_IDS = exports.TEST_IDS = {
162
162
  tabs: {
163
163
  tab: 'tabs.tab.'
164
164
  },
165
+ wrapperObservation: {
166
+ actionIcon: 'wrapperObservation.actionIcon.'
167
+ },
165
168
  workflowContainer: {
166
169
  bottomNav: {
167
170
  backButton: "".concat(ID_CONSTANTS.WORKFLOW_CONTAINER, ".").concat(ID_CONSTANTS.BOTTOM_NAV, ".backButton"),
package/dist/index.js CHANGED
@@ -489,6 +489,12 @@ Object.defineProperty(exports, "UTWorkflowContainer", {
489
489
  return _UTWorkflowContainer.default;
490
490
  }
491
491
  });
492
+ Object.defineProperty(exports, "UTWrapperObservation", {
493
+ enumerable: true,
494
+ get: function () {
495
+ return _UTWrapperObservation.default;
496
+ }
497
+ });
492
498
  Object.defineProperty(exports, "WithLoading", {
493
499
  enumerable: true,
494
500
  get: function () {
@@ -613,6 +619,7 @@ var _UTValidation = _interopRequireDefault(require("./components/UTValidation"))
613
619
  var _UTVirtualizedList = _interopRequireDefault(require("./components/UTVirtualizedList"));
614
620
  var _UTVirtualKeyboard = _interopRequireDefault(require("./components/UTVirtualKeyboard"));
615
621
  var _UTWorkflowContainer = _interopRequireDefault(require("./components/UTWorkflowContainer"));
622
+ var _UTWrapperObservation = _interopRequireDefault(require("./components/UTWrapperObservation"));
616
623
  var _WithLoading = _interopRequireDefault(require("./components/WithLoading"));
617
624
  var _WithTouch = _interopRequireDefault(require("./components/WithTouch"));
618
625
  var _stylesDeduplicationUtils = _interopRequireDefault(require("./utils/stylesDeduplicationUtils"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@widergy/energy-ui",
3
- "version": "3.141.4",
3
+ "version": "3.142.1",
4
4
  "description": "Widergy Web Components",
5
5
  "author": "widergy",
6
6
  "license": "MIT",
@@ -13,8 +13,8 @@
13
13
  "scripts": {
14
14
  "start": "SKIP_PREFLIGHT_CHECK=true DISABLE_ESLINT_PLUGIN=true cross-env GENERATE_SOURCEMAP=false react-scripts --openssl-legacy-provider start",
15
15
  "build-examples": "cross-env GENERATE_SOURCEMAP=false react-scripts --openssl-legacy-provider build",
16
- "lint": "./node_modules/eslint/bin/eslint.js src --cache --prune-suppressions",
17
- "lint-suppress": "./node_modules/eslint/bin/eslint.js src --cache --suppress-all",
16
+ "lint": "./node_modules/eslint/bin/eslint.js src --prune-suppressions",
17
+ "lint-suppress": "./node_modules/eslint/bin/eslint.js src --suppress-all",
18
18
  "test": "SKIP_PREFLIGHT_CHECK=true DISABLE_ESLINT_PLUGIN=true react-scripts test --env=jsdom",
19
19
  "eject": "react-scripts eject",
20
20
  "prebuild": "rimraf dist",