@widergy/energy-ui 3.172.2 → 3.173.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.
- package/CHANGELOG.md +20 -6
- package/dist/components/UTDataCategory/README.md +3 -1
- package/dist/components/UTDataCategory/UTDataCategory.stories.js +405 -0
- package/dist/components/UTDataCategory/components/MainAction/index.js +47 -0
- package/dist/components/UTDataCategory/constants.js +6 -2
- package/dist/components/UTDataCategory/index.js +46 -16
- package/dist/components/UTDataCategory/styles.module.scss +11 -0
- package/dist/components/UTDataElement/README.md +15 -2
- package/dist/components/UTDataElement/UTDataElement.stories.js +29 -1
- package/dist/components/UTDataElement/index.js +96 -49
- package/dist/components/UTDataElement/styles.module.scss +5 -0
- package/dist/components/UTDataElement/theme.js +11 -9
- package/dist/components/UTRadioGroup/UTRadioGroup.stories.js +124 -4
- package/dist/components/UTRadioGroup/versions/V1/components/Radio/index.js +12 -6
- package/dist/components/UTRadioGroup/versions/V1/constants.js +1 -0
- package/dist/components/UTRadioGroup/versions/V1/index.js +23 -7
- package/dist/components/UTRadioGroup/versions/V1/styles.module.scss +5 -0
- package/dist/components/UTRadioGroup/versions/V1/utils.js +40 -0
- package/dist/constants/Palette.js +18 -2
- package/dist/esm/components/UTDataCategory/README.md +3 -1
- package/dist/esm/components/UTDataCategory/UTDataCategory.stories.js +400 -0
- package/dist/esm/components/UTDataCategory/components/MainAction/index.js +40 -0
- package/dist/esm/components/UTDataCategory/constants.js +5 -1
- package/dist/esm/components/UTDataCategory/index.js +48 -18
- package/dist/esm/components/UTDataCategory/styles.module.scss +11 -0
- package/dist/esm/components/UTDataElement/README.md +15 -2
- package/dist/esm/components/UTDataElement/UTDataElement.stories.js +28 -0
- package/dist/esm/components/UTDataElement/index.js +98 -51
- package/dist/esm/components/UTDataElement/styles.module.scss +5 -0
- package/dist/esm/components/UTDataElement/theme.js +12 -10
- package/dist/esm/components/UTRadioGroup/UTRadioGroup.stories.js +123 -3
- package/dist/esm/components/UTRadioGroup/versions/V1/components/Radio/index.js +12 -6
- package/dist/esm/components/UTRadioGroup/versions/V1/constants.js +1 -0
- package/dist/esm/components/UTRadioGroup/versions/V1/index.js +25 -9
- package/dist/esm/components/UTRadioGroup/versions/V1/styles.module.scss +5 -0
- package/dist/esm/components/UTRadioGroup/versions/V1/utils.js +34 -0
- package/dist/esm/constants/Palette.js +17 -1
- package/dist/esm/utils/colorUtils.js +15 -0
- package/dist/esm/utils/hooks/useCSSVariables/constants.js +1 -0
- package/dist/utils/colorUtils.js +16 -1
- package/dist/utils/hooks/useCSSVariables/constants.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getAreaStyle = void 0;
|
|
7
|
+
var _Palette = require("../../../../constants/Palette");
|
|
8
|
+
var _colorUtils = require("../../../../utils/colorUtils");
|
|
9
|
+
// colorTheme sin entrada real en la paleta del tenant (ej. 'primary', o un valor inválido) -> se trata como si no
|
|
10
|
+
// se hubiera pasado ningún colorTheme (getAreaStyle no agrega fondo/borde para ese lado del área).
|
|
11
|
+
const resolvePaletteColorTheme = colorTheme => _Palette.VALID_PALETTE_COLOR_THEMES.has(colorTheme) ? colorTheme : undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Calcula el estilo del área de fondo de UTRadioGroup según areaProps. Sin `area`, no agrega borde ni fondo.
|
|
15
|
+
* A diferencia de UTDataCategory/UTDataElement, acá el fondo no tiene un colorTheme por defecto: solo se
|
|
16
|
+
* aplica si `areaProps.colorTheme` está configurado explícitamente.
|
|
17
|
+
* @param {boolean} area - Si el área debe mostrarse.
|
|
18
|
+
* @param {{ colorTheme?: string, shade?: string, borderColorTheme?: string, borderShade?: string }} [areaProps] - Personalización del área. Sin `colorTheme` no se agrega fondo; sin `borderColorTheme` no se agrega borde.
|
|
19
|
+
* @returns {object} Estilos inline a aplicar sobre el contenedor.
|
|
20
|
+
*/
|
|
21
|
+
const getAreaStyle = function (area) {
|
|
22
|
+
let areaProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
23
|
+
if (!area) return {};
|
|
24
|
+
const colorTheme = resolvePaletteColorTheme(areaProps.colorTheme);
|
|
25
|
+
const borderColorTheme = resolvePaletteColorTheme(areaProps.borderColorTheme);
|
|
26
|
+
const shade = areaProps.shade || (colorTheme === _Palette.COLOR_THEMES.light ? _Palette.COLOR_SHADES.shade03 : _Palette.COLOR_SHADES.shade01);
|
|
27
|
+
const borderShade = areaProps.borderShade || (borderColorTheme === _Palette.COLOR_THEMES.light ? _Palette.COLOR_SHADES.shade03 : _Palette.COLOR_SHADES.shade01);
|
|
28
|
+
return {
|
|
29
|
+
...(colorTheme && {
|
|
30
|
+
backgroundColor: (0, _colorUtils.getPaletteCssVar)(colorTheme, shade)
|
|
31
|
+
}),
|
|
32
|
+
...(borderColorTheme && {
|
|
33
|
+
border: "1px solid ".concat((0, _colorUtils.getPaletteCssVar)(borderColorTheme, borderShade))
|
|
34
|
+
}),
|
|
35
|
+
borderRadius: 8,
|
|
36
|
+
boxSizing: 'border-box',
|
|
37
|
+
padding: 8
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
exports.getAreaStyle = getAreaStyle;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.COLOR_THEMES = exports.COLOR_SHADES = void 0;
|
|
6
|
+
exports.VALID_PALETTE_COLOR_THEMES = exports.PALETTE_CSS_VAR_PREFIX_MAPPER = exports.COLOR_THEMES = exports.COLOR_SHADES = void 0;
|
|
7
7
|
const COLOR_SHADES = exports.COLOR_SHADES = {
|
|
8
8
|
shade01: '01',
|
|
9
9
|
shade02: '02',
|
|
@@ -23,4 +23,20 @@ const COLOR_THEMES = exports.COLOR_THEMES = {
|
|
|
23
23
|
primary: 'primary',
|
|
24
24
|
success: 'success',
|
|
25
25
|
warning: 'warning'
|
|
26
|
-
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Prefijo real de la CSS var de la paleta multi-tenant para cada colorTheme (ej. 'accent' -> 'actionAccent01').
|
|
29
|
+
// Los themes sin entrada acá (dark, gray, light, primary) no llevan prefijo: la CSS var coincide con el colorTheme.
|
|
30
|
+
const PALETTE_CSS_VAR_PREFIX_MAPPER = exports.PALETTE_CSS_VAR_PREFIX_MAPPER = {
|
|
31
|
+
[COLOR_THEMES.accent]: 'actionAccent',
|
|
32
|
+
[COLOR_THEMES.error]: 'semanticError',
|
|
33
|
+
[COLOR_THEMES.information]: 'semanticInformation',
|
|
34
|
+
[COLOR_THEMES.negative]: 'actionNegative',
|
|
35
|
+
[COLOR_THEMES.neutral]: 'actionNeutral',
|
|
36
|
+
[COLOR_THEMES.success]: 'semanticSuccess',
|
|
37
|
+
[COLOR_THEMES.warning]: 'semanticWarning'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// colorTheme de COLOR_THEMES que sí tienen una entrada real en la paleta de cada tenant (ver .storybook/palettes/palette.js).
|
|
41
|
+
// 'primary' queda afuera a propósito: es un valor válido de COLOR_THEMES pero ningún tenant define esa key.
|
|
42
|
+
const VALID_PALETTE_COLOR_THEMES = exports.VALID_PALETTE_COLOR_THEMES = new Set([COLOR_THEMES.accent, COLOR_THEMES.dark, COLOR_THEMES.error, COLOR_THEMES.gray, COLOR_THEMES.information, COLOR_THEMES.light, COLOR_THEMES.negative, COLOR_THEMES.neutral, COLOR_THEMES.success, COLOR_THEMES.warning]);
|
|
@@ -12,6 +12,8 @@ A collapsible container component that displays a list of data elements with an
|
|
|
12
12
|
| classNames | object | | Custom CSS class names for styling the component. |
|
|
13
13
|
| collapsable | bool | `true` | Specifies if the data list is collapsible. |
|
|
14
14
|
| dataTestId | string | | Test ID for testing purposes. |
|
|
15
|
+
| description | string | | Description text displayed below the title. |
|
|
16
|
+
| descriptionProps | object | | Additional props for customizing the description UTLabel component. |
|
|
15
17
|
| elements | array | `[]` | Array of objects to be rendered as UTDataElement components. |
|
|
16
18
|
| elementsProps | object | `{}` | Additional props that apply to all UTDataElement components. |
|
|
17
19
|
| expanded | bool | `false` | Controls the initial expanded state of the component. |
|
|
@@ -21,7 +23,7 @@ A collapsible container component that displays a list of data elements with an
|
|
|
21
23
|
|
|
22
24
|
## Behavior
|
|
23
25
|
|
|
24
|
-
- **Collapsible**: The component is only collapsible if it has a `title` and `collapsable` is `true`
|
|
26
|
+
- **Collapsible**: The component is only collapsible if it has a `title` and `collapsable` is `true`. Clicking anywhere on the header (title, description) toggles it; the chevron next to the title is only a visual indicator. Clicks on `action` don't affect the toggle.
|
|
25
27
|
- **Initial State**: The component starts collapsed by default unless `expanded` is `true`
|
|
26
28
|
- **Area Styling**: When `area` is `true`, the component gets background color and padding
|
|
27
29
|
- **Smooth Transitions**: Collapse/expand animations use CSS transitions for smooth UX
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/* eslint-disable no-alert */
|
|
2
|
+
import { ACTION_TYPE } from './constants';
|
|
3
|
+
import UTDataCategory from '.';
|
|
4
|
+
|
|
5
|
+
// Mock data for examples
|
|
6
|
+
const mockElements = [{
|
|
7
|
+
title: 'Plan Mensual',
|
|
8
|
+
Data: '$4.999',
|
|
9
|
+
Icon: 'IconCreditCard',
|
|
10
|
+
badge: 'Activo'
|
|
11
|
+
}, {
|
|
12
|
+
title: 'Almacenamiento',
|
|
13
|
+
Data: '50GB disponibles',
|
|
14
|
+
Icon: 'IconCloud'
|
|
15
|
+
}, {
|
|
16
|
+
title: 'Soporte Prioritario',
|
|
17
|
+
Data: 'Atención 24/7',
|
|
18
|
+
Icon: 'IconHeadset'
|
|
19
|
+
}];
|
|
20
|
+
const mockElementsWithActions = [{
|
|
21
|
+
title: 'Streaming Plus',
|
|
22
|
+
Data: 'Plan mensual',
|
|
23
|
+
Icon: 'IconDeviceTv',
|
|
24
|
+
badge: 'Activo',
|
|
25
|
+
action: {
|
|
26
|
+
type: ACTION_TYPE.SWITCH,
|
|
27
|
+
checked: true,
|
|
28
|
+
onChange: checked => alert("Streaming Plus ".concat(checked ? 'activado' : 'desactivado'))
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
title: 'Almacenamiento en la Nube',
|
|
32
|
+
Data: '50GB disponibles',
|
|
33
|
+
Icon: 'IconCloud',
|
|
34
|
+
action: {
|
|
35
|
+
type: ACTION_TYPE.BUTTON,
|
|
36
|
+
text: 'Editar',
|
|
37
|
+
variant: 'text',
|
|
38
|
+
onClick: () => alert('Editar plan de almacenamiento')
|
|
39
|
+
}
|
|
40
|
+
}, {
|
|
41
|
+
title: 'Soporte Premium',
|
|
42
|
+
Data: 'Atención prioritaria 24/7',
|
|
43
|
+
Icon: 'IconHeadset',
|
|
44
|
+
action: {
|
|
45
|
+
type: ACTION_TYPE.SWITCH,
|
|
46
|
+
checked: false,
|
|
47
|
+
onChange: checked => alert("Soporte Premium ".concat(checked ? 'activado' : 'desactivado'))
|
|
48
|
+
}
|
|
49
|
+
}];
|
|
50
|
+
export default {
|
|
51
|
+
args: {
|
|
52
|
+
title: 'Categoría de Datos',
|
|
53
|
+
elements: mockElements,
|
|
54
|
+
collapsable: true,
|
|
55
|
+
expanded: false
|
|
56
|
+
},
|
|
57
|
+
argTypes: {
|
|
58
|
+
title: {
|
|
59
|
+
control: 'text',
|
|
60
|
+
description: 'Título que se muestra en el encabezado de la categoría.',
|
|
61
|
+
table: {
|
|
62
|
+
defaultValue: {
|
|
63
|
+
summary: 'undefined'
|
|
64
|
+
},
|
|
65
|
+
type: {
|
|
66
|
+
summary: 'string'
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
description: {
|
|
71
|
+
control: 'text',
|
|
72
|
+
description: 'Descripción que se muestra debajo del título.',
|
|
73
|
+
table: {
|
|
74
|
+
defaultValue: {
|
|
75
|
+
summary: 'undefined'
|
|
76
|
+
},
|
|
77
|
+
type: {
|
|
78
|
+
summary: 'string'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
descriptionProps: {
|
|
83
|
+
control: false,
|
|
84
|
+
description: 'Props adicionales para el UTLabel de la descripción.',
|
|
85
|
+
table: {
|
|
86
|
+
defaultValue: {
|
|
87
|
+
summary: '{}'
|
|
88
|
+
},
|
|
89
|
+
type: {
|
|
90
|
+
summary: 'object'
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
Icon: {
|
|
95
|
+
control: 'text',
|
|
96
|
+
description: 'Icono que se muestra al inicio del título. Nombre de icono de UTIcon.',
|
|
97
|
+
table: {
|
|
98
|
+
defaultValue: {
|
|
99
|
+
summary: 'undefined'
|
|
100
|
+
},
|
|
101
|
+
type: {
|
|
102
|
+
summary: 'string'
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
iconProps: {
|
|
107
|
+
control: false,
|
|
108
|
+
description: 'Props adicionales para el icono del título.',
|
|
109
|
+
table: {
|
|
110
|
+
defaultValue: {
|
|
111
|
+
summary: 'undefined'
|
|
112
|
+
},
|
|
113
|
+
type: {
|
|
114
|
+
summary: 'object'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
collapsable: {
|
|
119
|
+
control: 'boolean',
|
|
120
|
+
description: 'Determina si la categoría es colapsable. Al hacer clic en el encabezado (título, descripción) se expande/colapsa; el chevron junto al título es solo un indicador visual.',
|
|
121
|
+
table: {
|
|
122
|
+
defaultValue: {
|
|
123
|
+
summary: 'true'
|
|
124
|
+
},
|
|
125
|
+
type: {
|
|
126
|
+
summary: 'boolean'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
expanded: {
|
|
131
|
+
control: 'boolean',
|
|
132
|
+
description: 'Controla el estado inicial expandido del componente.',
|
|
133
|
+
table: {
|
|
134
|
+
defaultValue: {
|
|
135
|
+
summary: 'false'
|
|
136
|
+
},
|
|
137
|
+
type: {
|
|
138
|
+
summary: 'boolean'
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
action: {
|
|
143
|
+
control: false,
|
|
144
|
+
description: 'Configuración de la acción principal del encabezado (botón o switch). No dispara el colapso al hacer clic.',
|
|
145
|
+
table: {
|
|
146
|
+
defaultValue: {
|
|
147
|
+
summary: 'undefined'
|
|
148
|
+
},
|
|
149
|
+
type: {
|
|
150
|
+
summary: 'object'
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
elements: {
|
|
155
|
+
control: false,
|
|
156
|
+
description: 'Array de objetos que se renderizan como componentes UTDataElement.',
|
|
157
|
+
table: {
|
|
158
|
+
defaultValue: {
|
|
159
|
+
summary: '[]'
|
|
160
|
+
},
|
|
161
|
+
type: {
|
|
162
|
+
summary: 'array'
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
elementsProps: {
|
|
167
|
+
control: false,
|
|
168
|
+
description: 'Props adicionales aplicadas a todos los UTDataElement renderizados.',
|
|
169
|
+
table: {
|
|
170
|
+
defaultValue: {
|
|
171
|
+
summary: '{}'
|
|
172
|
+
},
|
|
173
|
+
type: {
|
|
174
|
+
summary: 'object'
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
area: {
|
|
179
|
+
control: 'boolean',
|
|
180
|
+
description: 'Cuando es true, aplica color de fondo y padding para dar apariencia de área.',
|
|
181
|
+
table: {
|
|
182
|
+
defaultValue: {
|
|
183
|
+
summary: 'false'
|
|
184
|
+
},
|
|
185
|
+
type: {
|
|
186
|
+
summary: 'boolean'
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
areaProps: {
|
|
191
|
+
control: false,
|
|
192
|
+
description: "Personaliza el fondo del área. Acepta `colorTheme` (cualquier valor de COLOR_THEMES) y `shade` ('01'–'05'). Solo aplica cuando `area` es `true`.",
|
|
193
|
+
table: {
|
|
194
|
+
defaultValue: {
|
|
195
|
+
summary: '{}'
|
|
196
|
+
},
|
|
197
|
+
type: {
|
|
198
|
+
summary: 'object'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
dataTestId: {
|
|
203
|
+
control: 'text',
|
|
204
|
+
description: 'ID de test para pruebas automatizadas.',
|
|
205
|
+
table: {
|
|
206
|
+
defaultValue: {
|
|
207
|
+
summary: 'undefined'
|
|
208
|
+
},
|
|
209
|
+
type: {
|
|
210
|
+
summary: 'string'
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
titleProps: {
|
|
215
|
+
control: false,
|
|
216
|
+
description: 'Props adicionales para el UTLabel del título.',
|
|
217
|
+
table: {
|
|
218
|
+
defaultValue: {
|
|
219
|
+
summary: 'undefined'
|
|
220
|
+
},
|
|
221
|
+
type: {
|
|
222
|
+
summary: 'object'
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
classes: {
|
|
227
|
+
control: false,
|
|
228
|
+
description: 'Clases de tema para estilos.',
|
|
229
|
+
table: {
|
|
230
|
+
defaultValue: {
|
|
231
|
+
summary: 'undefined'
|
|
232
|
+
},
|
|
233
|
+
type: {
|
|
234
|
+
summary: 'object'
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
classNames: {
|
|
239
|
+
control: false,
|
|
240
|
+
description: 'Clases CSS personalizadas para diferentes elementos.',
|
|
241
|
+
table: {
|
|
242
|
+
defaultValue: {
|
|
243
|
+
summary: 'undefined'
|
|
244
|
+
},
|
|
245
|
+
type: {
|
|
246
|
+
summary: 'object'
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
component: UTDataCategory,
|
|
252
|
+
parameters: {
|
|
253
|
+
controls: {
|
|
254
|
+
exclude: []
|
|
255
|
+
},
|
|
256
|
+
docs: {
|
|
257
|
+
description: {
|
|
258
|
+
component: 'Contenedor colapsable que agrupa una lista de UTDataElement bajo un título y descripción opcionales.'
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
title: 'Energy-UI/UTDataCategory'
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// Basic Stories
|
|
266
|
+
export const Default = {
|
|
267
|
+
args: {
|
|
268
|
+
title: 'Información de la Cuenta',
|
|
269
|
+
elements: mockElements
|
|
270
|
+
},
|
|
271
|
+
name: 'Básico'
|
|
272
|
+
};
|
|
273
|
+
export const WithDescription = {
|
|
274
|
+
args: {
|
|
275
|
+
title: 'Información de la Cuenta',
|
|
276
|
+
description: 'Datos generales asociados a tu cuenta actual.',
|
|
277
|
+
Icon: 'IconUser',
|
|
278
|
+
elements: mockElements
|
|
279
|
+
},
|
|
280
|
+
name: 'Con Descripción'
|
|
281
|
+
};
|
|
282
|
+
export const NonCollapsable = {
|
|
283
|
+
args: {
|
|
284
|
+
title: 'Resumen Fijo',
|
|
285
|
+
description: 'Esta categoría siempre está expandida.',
|
|
286
|
+
collapsable: false,
|
|
287
|
+
elements: mockElements
|
|
288
|
+
},
|
|
289
|
+
name: 'No Colapsable'
|
|
290
|
+
};
|
|
291
|
+
export const ExpandedByDefault = {
|
|
292
|
+
args: {
|
|
293
|
+
title: 'Categoría Expandida',
|
|
294
|
+
elements: mockElements,
|
|
295
|
+
expanded: true
|
|
296
|
+
},
|
|
297
|
+
name: 'Expandida por Defecto'
|
|
298
|
+
};
|
|
299
|
+
export const WithHeaderAction = {
|
|
300
|
+
args: {
|
|
301
|
+
title: 'Métodos de Pago',
|
|
302
|
+
description: 'Administrá los métodos de pago asociados a tu cuenta.',
|
|
303
|
+
Icon: 'IconWallet',
|
|
304
|
+
action: {
|
|
305
|
+
type: ACTION_TYPE.BUTTON,
|
|
306
|
+
text: 'Agregar',
|
|
307
|
+
variant: 'text',
|
|
308
|
+
onClick: () => alert('Agregar nuevo método de pago')
|
|
309
|
+
},
|
|
310
|
+
elements: mockElements
|
|
311
|
+
},
|
|
312
|
+
name: 'Con Acción en el Encabezado'
|
|
313
|
+
};
|
|
314
|
+
export const WithButtonAction = {
|
|
315
|
+
args: {
|
|
316
|
+
title: 'Datos de Facturación',
|
|
317
|
+
description: 'Información asociada a tu método de pago activo.',
|
|
318
|
+
Icon: 'IconCreditCard',
|
|
319
|
+
action: {
|
|
320
|
+
type: ACTION_TYPE.BUTTON,
|
|
321
|
+
text: 'Editar',
|
|
322
|
+
variant: 'text',
|
|
323
|
+
onClick: () => alert('Editar datos de facturación')
|
|
324
|
+
},
|
|
325
|
+
elements: mockElements
|
|
326
|
+
},
|
|
327
|
+
name: 'Con Acción Botón'
|
|
328
|
+
};
|
|
329
|
+
export const WithSwitchAction = {
|
|
330
|
+
args: {
|
|
331
|
+
title: 'Notificaciones Push',
|
|
332
|
+
description: 'Activá o desactivá las notificaciones de tu cuenta.',
|
|
333
|
+
Icon: 'IconBell',
|
|
334
|
+
action: {
|
|
335
|
+
type: ACTION_TYPE.SWITCH,
|
|
336
|
+
checked: true,
|
|
337
|
+
onChange: checked => alert("Switch ".concat(checked ? 'activado' : 'desactivado'))
|
|
338
|
+
},
|
|
339
|
+
elements: mockElements
|
|
340
|
+
},
|
|
341
|
+
name: 'Con Acción Switch'
|
|
342
|
+
};
|
|
343
|
+
export const CollapsableWithActions = {
|
|
344
|
+
args: {
|
|
345
|
+
title: 'Suscripciones Activas',
|
|
346
|
+
description: 'Gestioná los servicios a los que estás suscripto.',
|
|
347
|
+
Icon: 'IconApps',
|
|
348
|
+
collapsable: true,
|
|
349
|
+
action: {
|
|
350
|
+
type: ACTION_TYPE.BUTTON,
|
|
351
|
+
text: 'Agregar',
|
|
352
|
+
variant: 'text',
|
|
353
|
+
onClick: () => alert('Agregar nueva suscripción')
|
|
354
|
+
},
|
|
355
|
+
elements: mockElementsWithActions
|
|
356
|
+
},
|
|
357
|
+
name: 'Colapsable con Acciones (Encabezado y Elementos)'
|
|
358
|
+
};
|
|
359
|
+
export const AreaMode = {
|
|
360
|
+
args: {
|
|
361
|
+
title: 'Categoría con Área',
|
|
362
|
+
description: 'Esta categoría tiene un fondo destacado.',
|
|
363
|
+
area: true,
|
|
364
|
+
elements: mockElements
|
|
365
|
+
},
|
|
366
|
+
name: 'Modo Área'
|
|
367
|
+
};
|
|
368
|
+
export const AreaModeCustomProps = {
|
|
369
|
+
args: {
|
|
370
|
+
title: 'Área con Color Personalizado',
|
|
371
|
+
area: true,
|
|
372
|
+
areaProps: {
|
|
373
|
+
colorTheme: 'accent',
|
|
374
|
+
shade: '01'
|
|
375
|
+
},
|
|
376
|
+
elements: mockElements
|
|
377
|
+
},
|
|
378
|
+
name: 'Modo Área — Color Personalizado'
|
|
379
|
+
};
|
|
380
|
+
export const CustomDataTestId = {
|
|
381
|
+
args: {
|
|
382
|
+
title: 'Con Test ID',
|
|
383
|
+
elements: mockElements,
|
|
384
|
+
dataTestId: 'custom-data-category'
|
|
385
|
+
},
|
|
386
|
+
name: 'Con Test ID Personalizado'
|
|
387
|
+
};
|
|
388
|
+
export const Playground = {
|
|
389
|
+
args: {
|
|
390
|
+
title: 'Categoría de Datos',
|
|
391
|
+
description: '',
|
|
392
|
+
Icon: 'IconFolder',
|
|
393
|
+
collapsable: true,
|
|
394
|
+
expanded: false,
|
|
395
|
+
area: false,
|
|
396
|
+
elements: mockElementsWithActions,
|
|
397
|
+
dataTestId: 'playground-data-category'
|
|
398
|
+
},
|
|
399
|
+
name: 'Playground'
|
|
400
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
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); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { bool, oneOf, func, string, number, oneOfType } from 'prop-types';
|
|
4
|
+
import { TEST_IDS } from '../../../../constants/testIds';
|
|
5
|
+
import UTSwitch from '../../../UTSwitch';
|
|
6
|
+
import UTButton from '../../../UTButton';
|
|
7
|
+
import { ACTION_TYPE } from '../../constants';
|
|
8
|
+
const {
|
|
9
|
+
dataElement
|
|
10
|
+
} = TEST_IDS;
|
|
11
|
+
const MainAction = _ref => {
|
|
12
|
+
let {
|
|
13
|
+
type = ACTION_TYPE.BUTTON,
|
|
14
|
+
onChange,
|
|
15
|
+
value,
|
|
16
|
+
onClick,
|
|
17
|
+
dataTestId,
|
|
18
|
+
...props
|
|
19
|
+
} = _ref;
|
|
20
|
+
return type === ACTION_TYPE.SWITCH && onChange ? /*#__PURE__*/React.createElement(UTSwitch, _extends({
|
|
21
|
+
onChange: onChange,
|
|
22
|
+
value: value
|
|
23
|
+
}, props, {
|
|
24
|
+
dataTestId: dataTestId ? "".concat(dataTestId, ".").concat(dataElement.switchAction) : undefined,
|
|
25
|
+
version: "V1"
|
|
26
|
+
})) : type === ACTION_TYPE.BUTTON && onClick ? /*#__PURE__*/React.createElement(UTButton, _extends({
|
|
27
|
+
dataTestId: dataTestId ? "".concat(dataTestId, ".").concat(dataElement.buttonAction) : undefined,
|
|
28
|
+
variant: "text",
|
|
29
|
+
onClick: onClick
|
|
30
|
+
}, props)) : null;
|
|
31
|
+
};
|
|
32
|
+
MainAction.propTypes = {
|
|
33
|
+
dataTestId: string,
|
|
34
|
+
id: oneOfType([string, number]),
|
|
35
|
+
onChange: func,
|
|
36
|
+
onClick: func,
|
|
37
|
+
type: oneOf(Object.values(ACTION_TYPE)),
|
|
38
|
+
value: bool
|
|
39
|
+
};
|
|
40
|
+
export default MainAction;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
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); }
|
|
2
|
-
import { array, bool, object, objectOf, string } from 'prop-types';
|
|
3
|
-
import React, { useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { array, bool, object, objectOf, shape, string } from 'prop-types';
|
|
3
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import isEmpty from 'lodash/isEmpty';
|
|
5
5
|
import WithTheme from '../WithTheme';
|
|
6
6
|
import UTDataElement from '../UTDataElement';
|
|
7
7
|
import UTLabel from '../UTLabel';
|
|
8
|
-
import
|
|
8
|
+
import UTTouchableWithoutFeedback from '../UTTouchableWithoutFeedback';
|
|
9
9
|
import { mergeClasses } from '../../utils/classesUtils';
|
|
10
10
|
import { TEST_IDS } from '../../constants/testIds';
|
|
11
11
|
import UTIcon from '../UTIcon';
|
|
12
|
-
import MainAction from '../UTDataElement/components/MainAction';
|
|
13
12
|
import styles from './styles.module.scss';
|
|
14
13
|
import { retrieveStyle } from './theme';
|
|
15
14
|
import { WITHOUT_DATA_TEXT } from './constants';
|
|
15
|
+
import MainAction from './components/MainAction';
|
|
16
16
|
const {
|
|
17
17
|
dataCategory
|
|
18
18
|
} = TEST_IDS;
|
|
@@ -24,6 +24,8 @@ const UTDataCategory = _ref => {
|
|
|
24
24
|
classNames,
|
|
25
25
|
collapsable = true,
|
|
26
26
|
dataTestId,
|
|
27
|
+
description,
|
|
28
|
+
descriptionProps = {},
|
|
27
29
|
elements = [],
|
|
28
30
|
elementsProps = {},
|
|
29
31
|
expanded = false,
|
|
@@ -37,13 +39,20 @@ const UTDataCategory = _ref => {
|
|
|
37
39
|
const classes = useMemo(() => mergeClasses(theme, classNames), [classNames, theme]);
|
|
38
40
|
const [isCollapsed, setIsCollapsed] = useState(showTitle && collapsable && !expanded);
|
|
39
41
|
const childrenRef = useRef(null);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
setIsCollapsed(showTitle && collapsable && !expanded);
|
|
44
|
+
}, [expanded, showTitle, collapsable]);
|
|
40
45
|
const toggleCollapsed = () => setIsCollapsed(!isCollapsed);
|
|
46
|
+
const handleHeaderKeyDown = useCallback(event => {
|
|
47
|
+
if (event.target === event.currentTarget && (event.key === 'Enter' || event.key === ' ')) {
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
toggleCollapsed();
|
|
50
|
+
}
|
|
51
|
+
}, [toggleCollapsed]);
|
|
52
|
+
const stopActionPropagation = useCallback(event => event.stopPropagation(), []);
|
|
41
53
|
const containerClasses = "".concat(styles.container, " ").concat(classes.container || '', " ").concat(area ? classes.area : '');
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
className: containerClasses,
|
|
45
|
-
"data-testid": dataTestId ? "".concat(dataTestId, ".").concat(dataCategory.container) : undefined
|
|
46
|
-
}, title && /*#__PURE__*/React.createElement("div", {
|
|
54
|
+
const collapseIconClasses = "".concat(styles.collapseButton, " ").concat(isCollapsed ? styles.collapsed : '');
|
|
55
|
+
const headerContent = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
47
56
|
className: styles.title
|
|
48
57
|
}, IconComponent && /*#__PURE__*/React.createElement(IconComponent, _extends({
|
|
49
58
|
name: Icon,
|
|
@@ -51,15 +60,31 @@ const UTDataCategory = _ref => {
|
|
|
51
60
|
}, iconProps)), /*#__PURE__*/React.createElement(UTLabel, _extends({
|
|
52
61
|
colorTheme: "gray",
|
|
53
62
|
weight: "medium"
|
|
54
|
-
}, titleProps), title), collapsable && /*#__PURE__*/React.createElement(
|
|
55
|
-
className:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
variant: "text",
|
|
59
|
-
onClick: toggleCollapsed,
|
|
60
|
-
size: "small",
|
|
63
|
+
}, titleProps), title), collapsable && /*#__PURE__*/React.createElement(UTIcon, {
|
|
64
|
+
className: collapseIconClasses,
|
|
65
|
+
colorTheme: "gray",
|
|
66
|
+
name: "IconChevronUp",
|
|
61
67
|
dataTestId: dataTestId ? "".concat(dataTestId, ".").concat(dataCategory.collapseButton) : undefined
|
|
62
|
-
})
|
|
68
|
+
}), action &&
|
|
69
|
+
/*#__PURE__*/
|
|
70
|
+
// Sin role="button": este div solo corta la propagación del click/keydown hacia el toggle de colapso, no es un control propio.
|
|
71
|
+
React.createElement("div", {
|
|
72
|
+
onClick: stopActionPropagation,
|
|
73
|
+
onKeyDown: stopActionPropagation
|
|
74
|
+
}, /*#__PURE__*/React.createElement(MainAction, action))), description && /*#__PURE__*/React.createElement(UTLabel, _extends({
|
|
75
|
+
colorTheme: "gray"
|
|
76
|
+
}, descriptionProps), description));
|
|
77
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
78
|
+
className: containerClasses,
|
|
79
|
+
"data-testid": dataTestId ? "".concat(dataTestId, ".").concat(dataCategory.container) : undefined
|
|
80
|
+
}, title && (collapsable ? /*#__PURE__*/React.createElement(UTTouchableWithoutFeedback, {
|
|
81
|
+
className: "".concat(styles.header, " ").concat(styles.clickable),
|
|
82
|
+
onClick: toggleCollapsed,
|
|
83
|
+
onKeyDown: handleHeaderKeyDown,
|
|
84
|
+
"aria-expanded": !isCollapsed
|
|
85
|
+
}, headerContent) : /*#__PURE__*/React.createElement("div", {
|
|
86
|
+
className: styles.header
|
|
87
|
+
}, headerContent)), /*#__PURE__*/React.createElement("div", {
|
|
63
88
|
style: {
|
|
64
89
|
gridTemplateRows: isCollapsed ? '0fr' : '1fr',
|
|
65
90
|
marginTop: isCollapsed || !showTitle ? 0 : 16
|
|
@@ -86,11 +111,16 @@ const UTDataCategory = _ref => {
|
|
|
86
111
|
UTDataCategory.propTypes = {
|
|
87
112
|
action: object,
|
|
88
113
|
area: bool,
|
|
89
|
-
areaProps:
|
|
114
|
+
areaProps: shape({
|
|
115
|
+
colorTheme: string,
|
|
116
|
+
shade: string
|
|
117
|
+
}),
|
|
90
118
|
classes: objectOf(string),
|
|
91
119
|
classNames: objectOf(string),
|
|
92
120
|
collapsable: bool,
|
|
93
121
|
dataTestId: string,
|
|
122
|
+
description: string,
|
|
123
|
+
descriptionProps: object,
|
|
94
124
|
elements: array,
|
|
95
125
|
elementsProps: object,
|
|
96
126
|
expanded: bool,
|
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
.header {
|
|
7
|
+
align-items: stretch;
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
grid-gap: var(--UT-dataCategory-title-gap, 0.5rem);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.clickable {
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
}
|
|
16
|
+
|
|
6
17
|
.title {
|
|
7
18
|
align-items: center;
|
|
8
19
|
display: flex;
|