@widergy/energy-ui 3.138.5 → 3.139.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 +7 -0
- package/dist/components/UTPanel/UTPanel.stories.js +149 -1
- package/dist/components/UTPanel/versions/V1/DOCUMENTATION.md +307 -0
- package/dist/components/UTPanel/versions/V1/components/AdditionalContentModule/index.js +91 -0
- package/dist/components/UTPanel/versions/V1/components/AdditionalContentModule/styles.module.scss +85 -0
- package/dist/components/UTPanel/versions/V1/components/BodySection/index.js +57 -0
- package/dist/components/UTPanel/versions/V1/components/ControlAreaSection/index.js +118 -0
- package/dist/components/UTPanel/versions/V1/components/HeaderSection/index.js +122 -0
- package/dist/components/UTPanel/versions/V1/index.js +90 -121
- package/dist/components/UTPanel/versions/V1/styles.module.scss +79 -19
- package/dist/constants/testIds.js +15 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [3.139.0](https://github.com/widergy/energy-ui/compare/v3.138.5...v3.139.0) (2026-02-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* [AXCH-1193] ut panel component refactor ([#753](https://github.com/widergy/energy-ui/issues/753)) ([e30c16a](https://github.com/widergy/energy-ui/commit/e30c16a09d6e4e27be50161be797fb6c962aa81f))
|
|
7
|
+
|
|
1
8
|
## [3.138.5](https://github.com/widergy/energy-ui/compare/v3.138.4...v3.138.5) (2026-02-24)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = exports.V1Workflow = exports.V1WithStatus = exports.V1WithPagination = exports.V1WithHeaderItems = exports.V1WithActions = exports.V1LargeSize = exports.V1Inline = exports.V1Default = exports.V1Collapsible = exports.V0WithCustomTitle = exports.V0LeftSide = exports.V0Default = exports.Playground = void 0;
|
|
6
|
+
exports.default = exports.V1Workflow = exports.V1WithStatus = exports.V1WithPagination = exports.V1WithHeaderItems = exports.V1WithAdditionalContent = exports.V1WithActions = exports.V1LargeSize = exports.V1Inline = exports.V1Default = exports.V1Collapsible = exports.V0WithCustomTitle = exports.V0LeftSide = exports.V0Default = exports.Playground = void 0;
|
|
7
7
|
var _react = _interopRequireDefault(require("react"));
|
|
8
8
|
var _utils = require("stories/utils");
|
|
9
9
|
var _UTLabel = _interopRequireDefault(require("../UTLabel"));
|
|
@@ -61,6 +61,95 @@ const headerItemsExample = [{
|
|
|
61
61
|
icon: 'IconUser',
|
|
62
62
|
value: 'Juan Pérez'
|
|
63
63
|
}];
|
|
64
|
+
|
|
65
|
+
// Mock components for AdditionalContent
|
|
66
|
+
const SettingsBodyComponent = () => /*#__PURE__*/_react.default.createElement("div", {
|
|
67
|
+
style: {
|
|
68
|
+
padding: '16px'
|
|
69
|
+
}
|
|
70
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
71
|
+
variant: "title3",
|
|
72
|
+
weight: "medium",
|
|
73
|
+
style: {
|
|
74
|
+
marginBottom: '12px'
|
|
75
|
+
}
|
|
76
|
+
}, "Configuraci\xF3n"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
77
|
+
variant: "body2",
|
|
78
|
+
colorTheme: "gray",
|
|
79
|
+
style: {
|
|
80
|
+
marginBottom: '16px'
|
|
81
|
+
}
|
|
82
|
+
}, "Ajusta los par\xE1metros de la aplicaci\xF3n desde aqu\xED."), /*#__PURE__*/_react.default.createElement("div", {
|
|
83
|
+
style: {
|
|
84
|
+
display: 'flex',
|
|
85
|
+
flexDirection: 'column',
|
|
86
|
+
gap: '8px'
|
|
87
|
+
}
|
|
88
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
89
|
+
variant: "body2"
|
|
90
|
+
}, "\u2022 Tema oscuro"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
91
|
+
variant: "body2"
|
|
92
|
+
}, "\u2022 Notificaciones"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
93
|
+
variant: "body2"
|
|
94
|
+
}, "\u2022 Privacidad")));
|
|
95
|
+
const NotificationsBodyComponent = () => /*#__PURE__*/_react.default.createElement("div", {
|
|
96
|
+
style: {
|
|
97
|
+
padding: '16px'
|
|
98
|
+
}
|
|
99
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
100
|
+
variant: "title3",
|
|
101
|
+
weight: "medium",
|
|
102
|
+
style: {
|
|
103
|
+
marginBottom: '12px'
|
|
104
|
+
}
|
|
105
|
+
}, "Notificaciones"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
106
|
+
variant: "body2",
|
|
107
|
+
colorTheme: "gray",
|
|
108
|
+
style: {
|
|
109
|
+
marginBottom: '16px'
|
|
110
|
+
}
|
|
111
|
+
}, "Gestiona tus notificaciones aqu\xED."), /*#__PURE__*/_react.default.createElement("div", {
|
|
112
|
+
style: {
|
|
113
|
+
display: 'flex',
|
|
114
|
+
flexDirection: 'column',
|
|
115
|
+
gap: '8px'
|
|
116
|
+
}
|
|
117
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
118
|
+
variant: "body2"
|
|
119
|
+
}, "\u2022 Notificaciones por email"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
120
|
+
variant: "body2"
|
|
121
|
+
}, "\u2022 Alertas de sistema"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
122
|
+
variant: "body2"
|
|
123
|
+
}, "\u2022 Recordatorios")));
|
|
124
|
+
const HelpBodyComponent = () => /*#__PURE__*/_react.default.createElement("div", {
|
|
125
|
+
style: {
|
|
126
|
+
padding: '16px'
|
|
127
|
+
}
|
|
128
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
129
|
+
variant: "title3",
|
|
130
|
+
weight: "medium",
|
|
131
|
+
style: {
|
|
132
|
+
marginBottom: '12px'
|
|
133
|
+
}
|
|
134
|
+
}, "Ayuda"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
135
|
+
variant: "body2",
|
|
136
|
+
colorTheme: "gray",
|
|
137
|
+
style: {
|
|
138
|
+
marginBottom: '16px'
|
|
139
|
+
}
|
|
140
|
+
}, "Encuentra respuestas a tus preguntas."), /*#__PURE__*/_react.default.createElement("div", {
|
|
141
|
+
style: {
|
|
142
|
+
display: 'flex',
|
|
143
|
+
flexDirection: 'column',
|
|
144
|
+
gap: '8px'
|
|
145
|
+
}
|
|
146
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
147
|
+
variant: "body2"
|
|
148
|
+
}, "\u2022 Documentaci\xF3n"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
149
|
+
variant: "body2"
|
|
150
|
+
}, "\u2022 Preguntas frecuentes"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
151
|
+
variant: "body2"
|
|
152
|
+
}, "\u2022 Soporte t\xE9cnico")));
|
|
64
153
|
var _default = exports.default = {
|
|
65
154
|
args: {
|
|
66
155
|
children: mockContent,
|
|
@@ -695,6 +784,65 @@ const V1LargeSize = exports.V1LargeSize = {
|
|
|
695
784
|
},
|
|
696
785
|
name: 'V1 - Tamaño Grande'
|
|
697
786
|
};
|
|
787
|
+
const V1WithAdditionalContent = exports.V1WithAdditionalContent = {
|
|
788
|
+
args: {
|
|
789
|
+
version: 'V1',
|
|
790
|
+
open: false,
|
|
791
|
+
title: 'Panel con Contenido Adicional',
|
|
792
|
+
subtitle: 'Panel con sidebar de navegación',
|
|
793
|
+
panelSide: 'right',
|
|
794
|
+
size: 'M',
|
|
795
|
+
additionalContent: [{
|
|
796
|
+
id: 'settings',
|
|
797
|
+
Icon: 'IconSettings',
|
|
798
|
+
BodyComponent: SettingsBodyComponent,
|
|
799
|
+
tooltipProps: {
|
|
800
|
+
content: 'Configuración'
|
|
801
|
+
}
|
|
802
|
+
}, {
|
|
803
|
+
id: 'notifications',
|
|
804
|
+
Icon: 'IconBell',
|
|
805
|
+
BodyComponent: NotificationsBodyComponent,
|
|
806
|
+
tooltipProps: {
|
|
807
|
+
content: 'Notificaciones'
|
|
808
|
+
}
|
|
809
|
+
}, {
|
|
810
|
+
id: 'help',
|
|
811
|
+
Icon: 'IconHelpCircle',
|
|
812
|
+
BodyComponent: HelpBodyComponent,
|
|
813
|
+
tooltipProps: {
|
|
814
|
+
content: 'Ayuda'
|
|
815
|
+
}
|
|
816
|
+
}],
|
|
817
|
+
children: /*#__PURE__*/_react.default.createElement("div", {
|
|
818
|
+
style: {
|
|
819
|
+
padding: '16px'
|
|
820
|
+
}
|
|
821
|
+
}, /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
822
|
+
variant: "title2",
|
|
823
|
+
weight: "medium",
|
|
824
|
+
style: {
|
|
825
|
+
marginBottom: '16px'
|
|
826
|
+
}
|
|
827
|
+
}, "Contenido Principal"), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
828
|
+
variant: "body1",
|
|
829
|
+
style: {
|
|
830
|
+
marginBottom: '12px'
|
|
831
|
+
}
|
|
832
|
+
}, "Este panel demuestra el nuevo m\xF3dulo AdditionalContent."), /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
833
|
+
variant: "body2",
|
|
834
|
+
colorTheme: "gray"
|
|
835
|
+
}, "Haz click en los iconos de la barra lateral derecha para ver el contenido adicional. El panel ahora tiene una arquitectura modular con subcomponentes separados."))
|
|
836
|
+
},
|
|
837
|
+
name: 'V1 - Con Contenido Adicional',
|
|
838
|
+
parameters: {
|
|
839
|
+
docs: {
|
|
840
|
+
description: {
|
|
841
|
+
story: 'Panel V1 con el nuevo módulo AdditionalContent. Incluye una barra lateral de navegación con tooltips y componentes de contenido dinámico.'
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
};
|
|
698
846
|
const Playground = exports.Playground = {
|
|
699
847
|
args: {
|
|
700
848
|
version: 'V1',
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# UTPanel V1 - Documentación
|
|
2
|
+
|
|
3
|
+
## Estructura del Componente
|
|
4
|
+
|
|
5
|
+
El componente `UTPanel V1` está organizado en **5 secciones principales**:
|
|
6
|
+
|
|
7
|
+
### Sección 1: Control Area
|
|
8
|
+
Barra de control ubicada en la parte superior del panel.
|
|
9
|
+
|
|
10
|
+
**Componentes incluidos:**
|
|
11
|
+
- Back Button (opcional)
|
|
12
|
+
- Pagination (opcional)
|
|
13
|
+
- Close Button (siempre a la derecha)
|
|
14
|
+
- Progress Bar (solo si `isWorkflow={true}`)
|
|
15
|
+
|
|
16
|
+
### Sección 2: Contenido Principal (Flex Row)
|
|
17
|
+
|
|
18
|
+
#### Subsección 2.1: Main Content Section
|
|
19
|
+
Contenido principal del panel que se expande dinámicamente.
|
|
20
|
+
|
|
21
|
+
**Composición:**
|
|
22
|
+
- Header (si `hideHeader !== true`)
|
|
23
|
+
- Header Items (si existen)
|
|
24
|
+
- Body (área scrollable principal)
|
|
25
|
+
- Main Button (si `hideMainButton !== true`)
|
|
26
|
+
|
|
27
|
+
#### Subsección 2.2 & 2.3: Additional Content Module
|
|
28
|
+
Módulo opcional que incluye un panel lateral con navegación.
|
|
29
|
+
|
|
30
|
+
**Composición:**
|
|
31
|
+
- Body Component: Panel de contenido (450px, ancho fijo)
|
|
32
|
+
- Sidebar: Barra de navegación (56px, ancho fijo)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## AdditionalContent - Nuevo Agregado
|
|
37
|
+
|
|
38
|
+
### ¿Qué es?
|
|
39
|
+
|
|
40
|
+
El módulo `AdditionalContent` permite agregar un panel lateral secundario al `UTPanel` con navegación mediante iconos. Es ideal para:
|
|
41
|
+
- Paneles de configuración
|
|
42
|
+
- Menús secundarios
|
|
43
|
+
- Navegación por pestañas
|
|
44
|
+
- Contenido complementario
|
|
45
|
+
|
|
46
|
+
### Interface esperada
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface AdditionalContentElement {
|
|
50
|
+
id: string; // Identificador único
|
|
51
|
+
Icon: string; // Nombre del icono (ej: "IconSettings")
|
|
52
|
+
BodyComponent: React.FC<any>; // Componente a renderizar
|
|
53
|
+
tooltipProps: {
|
|
54
|
+
content: string; // Contenido del tooltip
|
|
55
|
+
arrow?: boolean; // Mostrar flecha del tooltip (default: true)
|
|
56
|
+
tippyProps?: {
|
|
57
|
+
placement?: string; // "top" | "bottom" | "left" | "right" | etc
|
|
58
|
+
hideOnClick?: boolean;
|
|
59
|
+
interactive?: boolean;
|
|
60
|
+
duration?: [number, number]; // [show delay, hide delay]
|
|
61
|
+
[key: string]: any;
|
|
62
|
+
};
|
|
63
|
+
stringContentProps?: object; // Props adicionales para el contenido
|
|
64
|
+
stringContentClassName?: string; // CSS customizado para el contenido
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type AdditionalContent = AdditionalContentElement[] | undefined
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Ejemplo de uso
|
|
72
|
+
|
|
73
|
+
```jsx
|
|
74
|
+
import { UTPanel } from '@widergy/energy-ui';
|
|
75
|
+
|
|
76
|
+
// Definir componentes de contenido
|
|
77
|
+
const SettingsBody = () => (
|
|
78
|
+
<div style={{ padding: '16px' }}>
|
|
79
|
+
<h3>Configuración</h3>
|
|
80
|
+
<p>Contenido de configuración aquí</p>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const NotificationsBody = () => (
|
|
85
|
+
<div style={{ padding: '16px' }}>
|
|
86
|
+
<h3>Notificaciones</h3>
|
|
87
|
+
<p>Contenido de notificaciones aquí</p>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Crear array de AdditionalContent - Simple
|
|
92
|
+
const additionalContent = [
|
|
93
|
+
{
|
|
94
|
+
id: 'settings',
|
|
95
|
+
Icon: 'IconSettings',
|
|
96
|
+
BodyComponent: SettingsBody,
|
|
97
|
+
tooltipProps: {
|
|
98
|
+
content: 'Configuración'
|
|
99
|
+
// Los props de Tippy se aplican automáticamente:
|
|
100
|
+
// - placement: 'right' (por defecto)
|
|
101
|
+
// - zIndex: 9999
|
|
102
|
+
// - appendTo: document.body (para evitar overflow: hidden)
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'notifications',
|
|
107
|
+
Icon: 'IconBell',
|
|
108
|
+
BodyComponent: NotificationsBody,
|
|
109
|
+
tooltipProps: {
|
|
110
|
+
content: 'Notificaciones'
|
|
111
|
+
// Sin necesidad de repetir tippyProps
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
// Con configuración personalizada de Tippy (opcional)
|
|
117
|
+
const additionalContentAdvanced = [
|
|
118
|
+
{
|
|
119
|
+
id: 'settings',
|
|
120
|
+
Icon: 'IconSettings',
|
|
121
|
+
BodyComponent: SettingsBody,
|
|
122
|
+
tooltipProps: {
|
|
123
|
+
content: 'Configuración',
|
|
124
|
+
tippyProps: {
|
|
125
|
+
placement: 'left', // Cambiar posición si deseas
|
|
126
|
+
zIndex: 5000 // Cambiar z-index si deseas
|
|
127
|
+
// appendTo se aplica automáticamente
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// Usar en el componente
|
|
134
|
+
<UTPanel
|
|
135
|
+
additionalContent={additionalContent}
|
|
136
|
+
title="Mi Panel"
|
|
137
|
+
open={true}
|
|
138
|
+
// ... otros props
|
|
139
|
+
>
|
|
140
|
+
Contenido principal aquí
|
|
141
|
+
</UTPanel>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Nota**: El componente `AdditionalContentModule` aplica automáticamente los props necesarios para que los tooltips se vean correctamente:
|
|
145
|
+
- **placement**: 'right' (predeterminado)
|
|
146
|
+
- **zIndex**: 9999 (por encima de todo)
|
|
147
|
+
- **appendTo**: `document.body` (para evitar ser cortados por `overflow: hidden`)
|
|
148
|
+
|
|
149
|
+
Si necesitas personalizar alguno de estos valores, puedes hacerlo en `tippyProps`.
|
|
150
|
+
|
|
151
|
+
### Comportamiento
|
|
152
|
+
|
|
153
|
+
- **Primera opción preseleccionada**: La primera opción del array se selecciona automáticamente
|
|
154
|
+
- **BodyComponent oculto**: Si no hay ninguna opción seleccionada, el panel de contenido se oculta (solo se muestra la sidebar)
|
|
155
|
+
- **Sidebar siempre visible**: La barra lateral con iconos está siempre visible si `additionalContent` está definido
|
|
156
|
+
- **Ancho dinámico**: El panel total expande automáticamente:
|
|
157
|
+
- Sin AdditionalContent: 300px | 450px | 600px (según `size`)
|
|
158
|
+
- Con AdditionalContent: +506px adicionales (450px body + 56px sidebar)
|
|
159
|
+
|
|
160
|
+
### Propiedades del Panel con AdditionalContent
|
|
161
|
+
|
|
162
|
+
| Propiedad | Tipo | Valor |
|
|
163
|
+
|-----------|------|-------|
|
|
164
|
+
| `additionalContent` | `AdditionalContentElement[]` | Array de opciones |
|
|
165
|
+
| `size` | `"S" \| "M" \| "L"` | Tamaño del mainContentSection |
|
|
166
|
+
| Ancho total | - | mainContentSection + 506px |
|
|
167
|
+
|
|
168
|
+
**Ejemplos de tamaños finales:**
|
|
169
|
+
- Size S: 300px + 506px = 806px
|
|
170
|
+
- Size M: 450px + 506px = 956px
|
|
171
|
+
- Size L: 600px + 506px = 1106px
|
|
172
|
+
|
|
173
|
+
### Reglas de CSS
|
|
174
|
+
|
|
175
|
+
El componente utiliza Flexbox con las siguientes características:
|
|
176
|
+
|
|
177
|
+
```css
|
|
178
|
+
.contentRowContainer {
|
|
179
|
+
display: flex;
|
|
180
|
+
flex-direction: row; /* Alineación horizontal */
|
|
181
|
+
flex: 1; /* Toma espacio disponible */
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.mainContentSection {
|
|
185
|
+
flex: 1; /* Se expande dinámicamente */
|
|
186
|
+
min-width: 0; /* Permite shrink a 0 si es necesario */
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.bodyComponent {
|
|
190
|
+
width: 450px;
|
|
191
|
+
flex-shrink: 0; /* No se reduce */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.sidebar {
|
|
195
|
+
width: 56px;
|
|
196
|
+
flex-shrink: 0; /* No se reduce */
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Props existentes (compatibles)
|
|
203
|
+
|
|
204
|
+
Todos los props anteriores funcionan sin cambios:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
<UTPanel
|
|
208
|
+
// Control Area
|
|
209
|
+
showBackButton={boolean}
|
|
210
|
+
showPagination={boolean}
|
|
211
|
+
hideCloseButton={boolean}
|
|
212
|
+
isWorkflow={boolean}
|
|
213
|
+
|
|
214
|
+
// Header
|
|
215
|
+
hideHeader={boolean}
|
|
216
|
+
title={string}
|
|
217
|
+
subtitle={string}
|
|
218
|
+
headerItems={array}
|
|
219
|
+
|
|
220
|
+
// Body
|
|
221
|
+
children={ReactNode}
|
|
222
|
+
disableScrollbar={boolean}
|
|
223
|
+
|
|
224
|
+
// Main Button
|
|
225
|
+
hideMainButton={boolean}
|
|
226
|
+
mainButton={object}
|
|
227
|
+
|
|
228
|
+
// Layout
|
|
229
|
+
size={"S" | "M" | "L"}
|
|
230
|
+
|
|
231
|
+
// Callbacks
|
|
232
|
+
onClose={function}
|
|
233
|
+
onGoBack={function}
|
|
234
|
+
|
|
235
|
+
// Nuevo prop
|
|
236
|
+
additionalContent={array}
|
|
237
|
+
/>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Estructura de archivos
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
src/lib/components/UTPanel/versions/V1/
|
|
246
|
+
├── index.js # Componente principal
|
|
247
|
+
├── styles.module.scss # Estilos principales
|
|
248
|
+
├── constants.js # Constantes compartidas
|
|
249
|
+
├── theme.js # Tema/estilos avanzados
|
|
250
|
+
├── DOCUMENTATION.md # Este archivo
|
|
251
|
+
├── components/
|
|
252
|
+
│ ├── AdditionalContentModule/
|
|
253
|
+
│ │ ├── index.js # Módulo de contenido adicional
|
|
254
|
+
│ │ └── styles.module.scss # Estilos del módulo
|
|
255
|
+
│ ├── BodySection/
|
|
256
|
+
│ │ └── index.js # Sección del cuerpo principal
|
|
257
|
+
│ ├── ControlAreaSection/
|
|
258
|
+
│ │ └── index.js # Sección de control (botones, paginación)
|
|
259
|
+
│ ├── HeaderSection/
|
|
260
|
+
│ │ └── index.js # Sección del header
|
|
261
|
+
│ └── DataItem/
|
|
262
|
+
│ └── index.js # Componente de item
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Data Test IDs
|
|
268
|
+
|
|
269
|
+
El componente incluye `dataTestId` para facilitar las pruebas automatizadas. Todos los IDs están definidos en `src/lib/constants/testIds.js`.
|
|
270
|
+
|
|
271
|
+
### IDs disponibles
|
|
272
|
+
|
|
273
|
+
| Elemento | dataTestId | Descripción |
|
|
274
|
+
|----------|------------|-------------|
|
|
275
|
+
| Back Button | `panel.backButton` | Botón de retroceso |
|
|
276
|
+
| Close Button | `panel.closeButton` | Botón de cerrar |
|
|
277
|
+
| Title | `panel.title` | Título del panel |
|
|
278
|
+
| Main Action | `panel.mainAction` | Botón de acción principal del header |
|
|
279
|
+
| Secondary Action | `panel.secondaryAction` | Botón de acción secundaria del header |
|
|
280
|
+
| Main Button | `panel.mainButton` | Botón principal del footer |
|
|
281
|
+
| Pagination Prev | `panel.paginationPrev` | Botón de página anterior |
|
|
282
|
+
| Pagination Next | `panel.paginationNext` | Botón de página siguiente |
|
|
283
|
+
| Additional Content Body | `panel.additionalContent.additionalContentBody` | Contenedor del cuerpo adicional |
|
|
284
|
+
| Additional Content Sidebar | `panel.additionalContent.sidebar` | Barra lateral del contenido adicional |
|
|
285
|
+
| Sidebar Button | `panel.additionalContent.sidebarButton.{id}` | Botón de la sidebar (dinámico por `id`) |
|
|
286
|
+
| Sidebar Button Tooltip | `panel.additionalContent.sidebarButton.{id}.tooltip` | Tooltip del botón (dinámico por `id`) |
|
|
287
|
+
|
|
288
|
+
### Ejemplo de uso en tests
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
// Usando Testing Library
|
|
292
|
+
const backButton = screen.getByTestId('panel.backButton');
|
|
293
|
+
const mainButton = screen.getByTestId('panel.mainButton');
|
|
294
|
+
const settingsButton = screen.getByTestId('panel.additionalContent.sidebarButton.settings');
|
|
295
|
+
|
|
296
|
+
// Verificar que el sidebar existe
|
|
297
|
+
expect(screen.getByTestId('panel.additionalContent.sidebar')).toBeInTheDocument();
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Notas de desarrollo
|
|
303
|
+
|
|
304
|
+
- El componente mantiene **compatibilidad total** con versiones anteriores
|
|
305
|
+
- No hay breaking changes
|
|
306
|
+
- El módulo `AdditionalContent` es **completamente opcional**
|
|
307
|
+
- El panel sin `additionalContent` funciona exactamente como antes
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _propTypes = require("prop-types");
|
|
9
|
+
require("react-perfect-scrollbar/dist/css/styles.css");
|
|
10
|
+
var _reactPerfectScrollbar = _interopRequireDefault(require("react-perfect-scrollbar"));
|
|
11
|
+
var _UTButton = _interopRequireDefault(require("../../../../../UTButton"));
|
|
12
|
+
var _UTTooltip = _interopRequireDefault(require("../../../../../UTTooltip"));
|
|
13
|
+
var _testIds = require("../../../../../../constants/testIds");
|
|
14
|
+
var _stylesModule = _interopRequireDefault(require("./styles.module.scss"));
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
17
|
+
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); }
|
|
18
|
+
const {
|
|
19
|
+
panel
|
|
20
|
+
} = _testIds.TEST_IDS;
|
|
21
|
+
const AdditionalContentModule = _ref => {
|
|
22
|
+
let {
|
|
23
|
+
activeId,
|
|
24
|
+
additionalContent,
|
|
25
|
+
onSelectItem,
|
|
26
|
+
tooltipContainer
|
|
27
|
+
} = _ref;
|
|
28
|
+
const activeContent = (0, _react.useMemo)(() => additionalContent.find(item => item.id === activeId), [additionalContent, activeId]);
|
|
29
|
+
if (!additionalContent || additionalContent.length === 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const ActiveBodyComponent = activeContent === null || activeContent === void 0 ? void 0 : activeContent.BodyComponent;
|
|
33
|
+
const defaultTooltipContainer = tooltipContainer || (() => document.body);
|
|
34
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
35
|
+
className: _stylesModule.default.additionalContentWrapper
|
|
36
|
+
}, activeContent && /*#__PURE__*/_react.default.createElement("div", {
|
|
37
|
+
className: _stylesModule.default.bodyComponent,
|
|
38
|
+
"data-testid": panel.additionalContent.body
|
|
39
|
+
}, ActiveBodyComponent && /*#__PURE__*/_react.default.createElement(ActiveBodyComponent, null)), /*#__PURE__*/_react.default.createElement("div", {
|
|
40
|
+
className: "".concat(_stylesModule.default.sidebar, " ").concat(!activeContent ? _stylesModule.default.sidebarCollapsed : ''),
|
|
41
|
+
"data-testid": panel.additionalContent.sidebar
|
|
42
|
+
}, /*#__PURE__*/_react.default.createElement(_reactPerfectScrollbar.default, {
|
|
43
|
+
options: {
|
|
44
|
+
suppressScrollX: true
|
|
45
|
+
},
|
|
46
|
+
className: _stylesModule.default.sidebarScroll
|
|
47
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
48
|
+
className: _stylesModule.default.sidebarContent
|
|
49
|
+
}, additionalContent.map(item => {
|
|
50
|
+
var _item$tooltipProps, _item$tooltipProps2, _item$tooltipProps$ti, _item$tooltipProps3, _item$tooltipProps4, _item$tooltipProps5;
|
|
51
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
52
|
+
key: item.id,
|
|
53
|
+
className: _stylesModule.default.sidebarItemWrapper
|
|
54
|
+
}, /*#__PURE__*/_react.default.createElement(_UTTooltip.default, _extends({
|
|
55
|
+
content: ((_item$tooltipProps = item.tooltipProps) === null || _item$tooltipProps === void 0 ? void 0 : _item$tooltipProps.content) || item.id,
|
|
56
|
+
dataTestId: "".concat(panel.additionalContent.sidebarButton).concat(item.id, ".tooltip"),
|
|
57
|
+
tippyProps: {
|
|
58
|
+
placement: ((_item$tooltipProps2 = item.tooltipProps) === null || _item$tooltipProps2 === void 0 || (_item$tooltipProps2 = _item$tooltipProps2.tippyProps) === null || _item$tooltipProps2 === void 0 ? void 0 : _item$tooltipProps2.placement) || 'right',
|
|
59
|
+
zIndex: (_item$tooltipProps$ti = (_item$tooltipProps3 = item.tooltipProps) === null || _item$tooltipProps3 === void 0 || (_item$tooltipProps3 = _item$tooltipProps3.tippyProps) === null || _item$tooltipProps3 === void 0 ? void 0 : _item$tooltipProps3.zIndex) !== null && _item$tooltipProps$ti !== void 0 ? _item$tooltipProps$ti : 9999,
|
|
60
|
+
appendTo: ((_item$tooltipProps4 = item.tooltipProps) === null || _item$tooltipProps4 === void 0 || (_item$tooltipProps4 = _item$tooltipProps4.tippyProps) === null || _item$tooltipProps4 === void 0 ? void 0 : _item$tooltipProps4.appendTo) || defaultTooltipContainer,
|
|
61
|
+
...(((_item$tooltipProps5 = item.tooltipProps) === null || _item$tooltipProps5 === void 0 ? void 0 : _item$tooltipProps5.tippyProps) || {})
|
|
62
|
+
}
|
|
63
|
+
}, (_ref2 => {
|
|
64
|
+
let {
|
|
65
|
+
_,
|
|
66
|
+
...rest
|
|
67
|
+
} = _ref2;
|
|
68
|
+
return rest;
|
|
69
|
+
})(item.tooltipProps)), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_UTButton.default, {
|
|
70
|
+
colorTheme: activeId === item.id ? 'primary' : 'gray',
|
|
71
|
+
className: "".concat(_stylesModule.default.sidebarButton),
|
|
72
|
+
dataTestId: "".concat(panel.additionalContent.sidebarButton).concat(item.id),
|
|
73
|
+
Icon: item.Icon,
|
|
74
|
+
onClick: () => onSelectItem(activeId === item.id ? null : item.id),
|
|
75
|
+
size: "medium",
|
|
76
|
+
variant: activeId === item.id ? 'semitransparent' : 'text'
|
|
77
|
+
}))));
|
|
78
|
+
})))));
|
|
79
|
+
};
|
|
80
|
+
AdditionalContentModule.propTypes = {
|
|
81
|
+
additionalContent: (0, _propTypes.arrayOf)((0, _propTypes.shape)({
|
|
82
|
+
id: _propTypes.string.isRequired,
|
|
83
|
+
Icon: _propTypes.string.isRequired,
|
|
84
|
+
BodyComponent: _propTypes.elementType.isRequired,
|
|
85
|
+
tooltipProps: _propTypes.object.isRequired
|
|
86
|
+
})).isRequired,
|
|
87
|
+
activeId: _propTypes.string,
|
|
88
|
+
onSelectItem: _propTypes.func.isRequired,
|
|
89
|
+
tooltipContainer: _propTypes.func
|
|
90
|
+
};
|
|
91
|
+
var _default = exports.default = AdditionalContentModule;
|
package/dist/components/UTPanel/versions/V1/components/AdditionalContentModule/styles.module.scss
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
$body-component-width: 450px;
|
|
2
|
+
$sidebar-width: 56px;
|
|
3
|
+
|
|
4
|
+
.additionalContentWrapper {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
flex-shrink: 0;
|
|
8
|
+
height: 100%;
|
|
9
|
+
min-height: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.bodyComponent {
|
|
13
|
+
background-color: var(--light02);
|
|
14
|
+
border-bottom-left-radius: 8px;
|
|
15
|
+
border-bottom-style: solid;
|
|
16
|
+
border-bottom-width: 1px;
|
|
17
|
+
border-color: var(--light04);
|
|
18
|
+
border-left-style: solid;
|
|
19
|
+
border-left-width: 1px;
|
|
20
|
+
border-top-left-radius: 8px;
|
|
21
|
+
border-top-style: solid;
|
|
22
|
+
border-top-width: 1px;
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
min-width: $body-component-width;
|
|
27
|
+
opacity: 1;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
padding: 16px;
|
|
30
|
+
width: $body-component-width;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.sidebar {
|
|
34
|
+
background-color: var(--light02);
|
|
35
|
+
border-top-color: var(--light04);
|
|
36
|
+
border-top-style: solid;
|
|
37
|
+
border-top-width: 1px;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
flex-shrink: 0;
|
|
41
|
+
min-width: $sidebar-width;
|
|
42
|
+
overflow: visible;
|
|
43
|
+
position: relative;
|
|
44
|
+
width: $sidebar-width;
|
|
45
|
+
z-index: 10;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sidebarCollapsed {
|
|
49
|
+
background-color: var(--light01);
|
|
50
|
+
border-color: var(--light04);
|
|
51
|
+
border-left-style: solid;
|
|
52
|
+
border-left-width: 1px;
|
|
53
|
+
border-top-left-radius: 8px;
|
|
54
|
+
border-top-style: solid;
|
|
55
|
+
border-top-width: 1px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sidebarScroll {
|
|
59
|
+
flex: 1;
|
|
60
|
+
overflow-x: hidden;
|
|
61
|
+
overflow-y: auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sidebarContent {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
gap: 4px;
|
|
68
|
+
padding: 8px 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.sidebarItemWrapper {
|
|
72
|
+
display: flex;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
padding: 0 8px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.sidebarButton {
|
|
78
|
+
align-items: center;
|
|
79
|
+
border-radius: 4px;
|
|
80
|
+
display: flex;
|
|
81
|
+
height: 40px;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
transition: all 0.2s ease;
|
|
84
|
+
width: 40px;
|
|
85
|
+
}
|