anima-ds-nucleus 1.0.2 → 1.0.3
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/dist/anima-ds-nucleus.css +1 -1
- package/dist/anima-ds.cjs.js +86 -34
- package/dist/anima-ds.esm.js +8251 -7178
- package/package.json +1 -1
- package/src/components/Atoms/Typography/Typography.jsx +49 -18
- package/src/components/Atoms/Typography/Typography.stories.jsx +3 -3
- package/src/components/Layout/Header/HeaderConBuscador.jsx +136 -0
- package/src/components/Layout/Header/HeaderConBuscador.stories.jsx +79 -0
- package/src/components/Layout/Header/HeaderCore.jsx +119 -0
- package/src/components/Layout/Header/HeaderCore.stories.jsx +55 -0
- package/src/components/Layout/Sidebar/Sidebar.jsx +210 -37
- package/src/components/Layout/Sidebar/Sidebar.stories.jsx +57 -18
- package/src/components/Layout/Sidebar/SidebarCore.jsx +346 -0
- package/src/components/Layout/Sidebar/SidebarCore.stories.jsx +92 -0
- package/src/components/Layout/Sidebar/SidebarPoint.jsx +440 -0
- package/src/components/Layout/Sidebar/SidebarPoint.stories.jsx +114 -0
- package/src/index.js +4 -0
- package/src/style.css +12 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
3
|
+
import { Typography } from '../../Atoms/Typography/Typography';
|
|
4
|
+
|
|
5
|
+
// Mock data con 2 títulos y 2 secciones
|
|
6
|
+
const MOCK_SECTIONS = [
|
|
7
|
+
{
|
|
8
|
+
title: 'PERSONAS',
|
|
9
|
+
items: [
|
|
10
|
+
{ id: 'empleados', label: 'Empleados', icon: 'UserGroupIcon' },
|
|
11
|
+
{ id: 'organizacion', label: 'Organización', icon: 'BuildingOfficeIcon' },
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: 'TALENTO',
|
|
16
|
+
items: [
|
|
17
|
+
{ id: 'reclutamiento', label: 'Reclutamiento', icon: 'UserPlusIcon' },
|
|
18
|
+
{ id: 'desarrollo', label: 'Desarrollo', icon: 'AcademicCapIcon' },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export const SidebarCore = ({
|
|
24
|
+
sections = MOCK_SECTIONS,
|
|
25
|
+
activeItem,
|
|
26
|
+
onItemClick,
|
|
27
|
+
defaultCollapsed = false,
|
|
28
|
+
companyName = 'HEXA Core',
|
|
29
|
+
companyLogo,
|
|
30
|
+
onCompanyClick,
|
|
31
|
+
nucleusName = 'Nucleus AR',
|
|
32
|
+
nucleusLogo,
|
|
33
|
+
onNucleusClick,
|
|
34
|
+
itemBadges = {}, // Objeto con { itemId: number } para los badges
|
|
35
|
+
className = '',
|
|
36
|
+
...props
|
|
37
|
+
}) => {
|
|
38
|
+
const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
|
|
39
|
+
|
|
40
|
+
const toggleCollapse = () => {
|
|
41
|
+
setIsCollapsed(!isCollapsed);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<aside
|
|
46
|
+
className={`bg-white border-r border-gray-200 transition-all duration-300 ease-in-out ${
|
|
47
|
+
isCollapsed ? 'w-20' : 'w-64'
|
|
48
|
+
} ${className}`}
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
<nav className="h-full flex flex-col overflow-hidden">
|
|
52
|
+
{/* Barra superior con HEXA Core */}
|
|
53
|
+
{!isCollapsed && (
|
|
54
|
+
<div className="p-4 border-b border-gray-200">
|
|
55
|
+
<button
|
|
56
|
+
onClick={onCompanyClick}
|
|
57
|
+
className="w-full bg-white rounded-lg px-3 py-2.5
|
|
58
|
+
flex items-center justify-between hover:bg-gray-50 transition-colors"
|
|
59
|
+
>
|
|
60
|
+
<div className="flex items-center space-x-3">
|
|
61
|
+
{/* Icono cuadrado oscuro con H */}
|
|
62
|
+
{companyLogo ? (
|
|
63
|
+
<img
|
|
64
|
+
src={companyLogo}
|
|
65
|
+
alt={companyName}
|
|
66
|
+
className="w-8 h-8 rounded"
|
|
67
|
+
/>
|
|
68
|
+
) : (
|
|
69
|
+
<div className="w-8 h-8 bg-gray-700 rounded flex items-center justify-center">
|
|
70
|
+
<Typography
|
|
71
|
+
variant="body-md"
|
|
72
|
+
className="color-white font-bold"
|
|
73
|
+
>
|
|
74
|
+
H
|
|
75
|
+
</Typography>
|
|
76
|
+
</div>
|
|
77
|
+
)}
|
|
78
|
+
{/* Nombre de la empresa */}
|
|
79
|
+
<Typography
|
|
80
|
+
variant="body-md"
|
|
81
|
+
className="color-gray-900 font-medium"
|
|
82
|
+
>
|
|
83
|
+
{companyName}
|
|
84
|
+
</Typography>
|
|
85
|
+
</div>
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
)}
|
|
89
|
+
{/* Botón Nucleus AR */}
|
|
90
|
+
{!isCollapsed && (
|
|
91
|
+
<div className="bg-gray-100 py-4 w-full">
|
|
92
|
+
<div className="px-4">
|
|
93
|
+
<button
|
|
94
|
+
onClick={onNucleusClick}
|
|
95
|
+
className="w-full flex items-center px-4 py-2.5 rounded-lg
|
|
96
|
+
transition-all duration-200 color-gray-700 hover:bg-gray-200
|
|
97
|
+
justify-between"
|
|
98
|
+
>
|
|
99
|
+
<div className="flex items-center">
|
|
100
|
+
<Icon
|
|
101
|
+
name="BuildingOfficeIcon"
|
|
102
|
+
variant="24-outline"
|
|
103
|
+
size={20}
|
|
104
|
+
className="mr-3 color-teal"
|
|
105
|
+
/>
|
|
106
|
+
<Typography
|
|
107
|
+
variant="body-md"
|
|
108
|
+
className="font-medium color-gray-700"
|
|
109
|
+
>
|
|
110
|
+
{nucleusName}
|
|
111
|
+
</Typography>
|
|
112
|
+
</div>
|
|
113
|
+
{/* Chevron hacia abajo */}
|
|
114
|
+
<Icon
|
|
115
|
+
name="ChevronDownIcon"
|
|
116
|
+
variant="24-outline"
|
|
117
|
+
size={16}
|
|
118
|
+
className="color-teal"
|
|
119
|
+
/>
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
124
|
+
|
|
125
|
+
{/* Botón de colapsar/expandir - Solo visible cuando está expandido */}
|
|
126
|
+
{!isCollapsed && (
|
|
127
|
+
<div className="px-4 pb-2 flex justify-end">
|
|
128
|
+
<button
|
|
129
|
+
onClick={toggleCollapse}
|
|
130
|
+
className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
|
|
131
|
+
aria-label="Colapsar sidebar"
|
|
132
|
+
style={{ marginRight: '10px' }}
|
|
133
|
+
>
|
|
134
|
+
<Icon
|
|
135
|
+
name="ChevronDoubleLeftIcon"
|
|
136
|
+
variant="24-outline"
|
|
137
|
+
size={20}
|
|
138
|
+
className="color-teal"
|
|
139
|
+
/>
|
|
140
|
+
</button>
|
|
141
|
+
</div>
|
|
142
|
+
)}
|
|
143
|
+
|
|
144
|
+
{/* Logo H cuando está colapsado */}
|
|
145
|
+
{isCollapsed && (
|
|
146
|
+
<div className="p-4 border-b border-gray-200 flex justify-center">
|
|
147
|
+
{companyLogo ? (
|
|
148
|
+
<img
|
|
149
|
+
src={companyLogo}
|
|
150
|
+
alt={companyName}
|
|
151
|
+
className="w-8 h-8 rounded"
|
|
152
|
+
/>
|
|
153
|
+
) : (
|
|
154
|
+
<div className="w-8 h-8 bg-gray-700 rounded flex items-center justify-center">
|
|
155
|
+
<Typography
|
|
156
|
+
variant="body-md"
|
|
157
|
+
className="color-white font-bold"
|
|
158
|
+
>
|
|
159
|
+
H
|
|
160
|
+
</Typography>
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
</div>
|
|
164
|
+
)}
|
|
165
|
+
|
|
166
|
+
{/* Botón Nucleus AR cuando está colapsado */}
|
|
167
|
+
{isCollapsed && (
|
|
168
|
+
<div className="bg-gray-100 py-4 w-full">
|
|
169
|
+
<div className="px-4 flex justify-center">
|
|
170
|
+
<button
|
|
171
|
+
onClick={onNucleusClick}
|
|
172
|
+
className="flex items-center justify-center p-2.5 rounded-lg
|
|
173
|
+
transition-all duration-200 color-gray-700 hover:bg-gray-200"
|
|
174
|
+
>
|
|
175
|
+
<Icon
|
|
176
|
+
name="BuildingOfficeIcon"
|
|
177
|
+
variant="24-outline"
|
|
178
|
+
size={20}
|
|
179
|
+
className="color-teal"
|
|
180
|
+
/>
|
|
181
|
+
<Icon
|
|
182
|
+
name="ChevronDownIcon"
|
|
183
|
+
variant="24-outline"
|
|
184
|
+
size={16}
|
|
185
|
+
className="ml-1 color-teal"
|
|
186
|
+
/>
|
|
187
|
+
</button>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
)}
|
|
191
|
+
|
|
192
|
+
{/* Botón para expandir - Solo visible cuando está colapsado */}
|
|
193
|
+
{isCollapsed && (
|
|
194
|
+
<div className="px-4 pb-2 flex justify-center">
|
|
195
|
+
<button
|
|
196
|
+
onClick={toggleCollapse}
|
|
197
|
+
className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
|
|
198
|
+
aria-label="Expandir sidebar"
|
|
199
|
+
>
|
|
200
|
+
<Icon
|
|
201
|
+
name="ChevronDoubleRightIcon"
|
|
202
|
+
variant="24-outline"
|
|
203
|
+
size={20}
|
|
204
|
+
className="color-teal"
|
|
205
|
+
/>
|
|
206
|
+
</button>
|
|
207
|
+
</div>
|
|
208
|
+
)}
|
|
209
|
+
|
|
210
|
+
{/* Contenido del sidebar */}
|
|
211
|
+
<div className="flex-1 overflow-y-auto py-4">
|
|
212
|
+
{/* Item "Inicio" destacado */}
|
|
213
|
+
<div className="px-4 mb-4">
|
|
214
|
+
<button
|
|
215
|
+
onClick={() => onItemClick && onItemClick('inicio')}
|
|
216
|
+
className={`w-full flex items-center ${
|
|
217
|
+
isCollapsed ? 'justify-center px-2' : 'px-4 justify-between'
|
|
218
|
+
} py-2.5 rounded-lg transition-all duration-200 ${
|
|
219
|
+
activeItem === 'inicio'
|
|
220
|
+
? ''
|
|
221
|
+
: 'color-gray-700 hover:bg-gray-100'
|
|
222
|
+
}`}
|
|
223
|
+
style={
|
|
224
|
+
activeItem === 'inicio'
|
|
225
|
+
? { backgroundColor: '#2D5C63' }
|
|
226
|
+
: {}
|
|
227
|
+
}
|
|
228
|
+
>
|
|
229
|
+
<div className="flex items-center">
|
|
230
|
+
<Icon
|
|
231
|
+
name="HomeIcon"
|
|
232
|
+
variant="24-outline"
|
|
233
|
+
size={20}
|
|
234
|
+
className={`${isCollapsed ? '' : 'mr-3'} ${
|
|
235
|
+
activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
|
|
236
|
+
}`}
|
|
237
|
+
/>
|
|
238
|
+
{!isCollapsed && (
|
|
239
|
+
<Typography
|
|
240
|
+
variant="body-md"
|
|
241
|
+
className={`font-medium ${
|
|
242
|
+
activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
|
|
243
|
+
}`}
|
|
244
|
+
>
|
|
245
|
+
Inicio
|
|
246
|
+
</Typography>
|
|
247
|
+
)}
|
|
248
|
+
</div>
|
|
249
|
+
{!isCollapsed && itemBadges['inicio'] !== undefined && itemBadges['inicio'] > 0 && (
|
|
250
|
+
<span
|
|
251
|
+
className="px-2 py-0.5 min-w-[20px] h-5
|
|
252
|
+
text-white rounded-full flex items-center justify-center
|
|
253
|
+
text-body-sm font-medium"
|
|
254
|
+
style={{
|
|
255
|
+
backgroundColor: '#6D3856',
|
|
256
|
+
borderRadius: '12px'
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
{itemBadges['inicio'] > 9 ? '9+' : itemBadges['inicio']}
|
|
260
|
+
</span>
|
|
261
|
+
)}
|
|
262
|
+
</button>
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
{/* Secciones */}
|
|
266
|
+
{sections.map((section, sectionIndex) => (
|
|
267
|
+
<div key={sectionIndex} className="mb-6">
|
|
268
|
+
{/* Título de la sección */}
|
|
269
|
+
{!isCollapsed && (
|
|
270
|
+
<div className="px-4 mb-2">
|
|
271
|
+
<Typography
|
|
272
|
+
variant="body-sm"
|
|
273
|
+
className="color-gray-500 uppercase font-medium tracking-wider"
|
|
274
|
+
>
|
|
275
|
+
{section.title}
|
|
276
|
+
</Typography>
|
|
277
|
+
</div>
|
|
278
|
+
)}
|
|
279
|
+
|
|
280
|
+
{/* Items de la sección */}
|
|
281
|
+
<div className="space-y-1">
|
|
282
|
+
{section.items.map((item) => (
|
|
283
|
+
<div key={item.id} className="px-4">
|
|
284
|
+
<button
|
|
285
|
+
onClick={() => onItemClick && onItemClick(item.id)}
|
|
286
|
+
className={`w-full flex items-center ${
|
|
287
|
+
isCollapsed ? 'justify-center px-2' : 'px-4 justify-between'
|
|
288
|
+
} py-2.5 rounded-lg transition-all duration-200 ${
|
|
289
|
+
activeItem === item.id
|
|
290
|
+
? ''
|
|
291
|
+
: 'color-gray-700 hover:bg-gray-100'
|
|
292
|
+
}`}
|
|
293
|
+
style={
|
|
294
|
+
activeItem === item.id
|
|
295
|
+
? { backgroundColor: '#2D5C63' }
|
|
296
|
+
: {}
|
|
297
|
+
}
|
|
298
|
+
title={isCollapsed ? item.label : ''}
|
|
299
|
+
>
|
|
300
|
+
<div className="flex items-center">
|
|
301
|
+
<Icon
|
|
302
|
+
name={item.icon}
|
|
303
|
+
variant="24-outline"
|
|
304
|
+
size={20}
|
|
305
|
+
className={`${isCollapsed ? '' : 'mr-3'} ${
|
|
306
|
+
activeItem === item.id ? 'color-white' : 'color-gray-700'
|
|
307
|
+
}`}
|
|
308
|
+
/>
|
|
309
|
+
{!isCollapsed && (
|
|
310
|
+
<Typography
|
|
311
|
+
variant="body-md"
|
|
312
|
+
className={`font-medium ${
|
|
313
|
+
activeItem === item.id ? 'color-white' : 'color-gray-700'
|
|
314
|
+
}`}
|
|
315
|
+
>
|
|
316
|
+
{item.label}
|
|
317
|
+
</Typography>
|
|
318
|
+
)}
|
|
319
|
+
</div>
|
|
320
|
+
{!isCollapsed && ((itemBadges[item.id] !== undefined && itemBadges[item.id] > 0) || (item.id === 'empleados' && 2)) && (
|
|
321
|
+
<span
|
|
322
|
+
className="px-2 py-0.5 min-w-[20px] h-5
|
|
323
|
+
text-white rounded-full flex items-center justify-center
|
|
324
|
+
text-body-sm font-medium"
|
|
325
|
+
style={{
|
|
326
|
+
backgroundColor: '#6D3856',
|
|
327
|
+
borderRadius: '12px'
|
|
328
|
+
}}
|
|
329
|
+
>
|
|
330
|
+
{item.id === 'empleados' ? 2 : (itemBadges[item.id] > 9 ? '9+' : itemBadges[item.id])}
|
|
331
|
+
</span>
|
|
332
|
+
)}
|
|
333
|
+
</button>
|
|
334
|
+
</div>
|
|
335
|
+
))}
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
))}
|
|
339
|
+
</div>
|
|
340
|
+
</nav>
|
|
341
|
+
</aside>
|
|
342
|
+
);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
export default SidebarCore;
|
|
346
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { SidebarCore } from './SidebarCore';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Layout/SidebarCore',
|
|
6
|
+
component: SidebarCore,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// Mock data con 2 títulos y 2 secciones
|
|
11
|
+
const mockSections = [
|
|
12
|
+
{
|
|
13
|
+
title: 'PERSONAS',
|
|
14
|
+
items: [
|
|
15
|
+
{ id: 'empleados', label: 'Empleados', icon: 'UserGroupIcon' },
|
|
16
|
+
{ id: 'organizacion', label: 'Organización', icon: 'BuildingOfficeIcon' },
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: 'TALENTO',
|
|
21
|
+
items: [
|
|
22
|
+
{ id: 'reclutamiento', label: 'Reclutamiento', icon: 'UserPlusIcon' },
|
|
23
|
+
{ id: 'desarrollo', label: 'Desarrollo', icon: 'AcademicCapIcon' },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export const Default = {
|
|
29
|
+
render: () => {
|
|
30
|
+
const [activeItem, setActiveItem] = useState('inicio');
|
|
31
|
+
return (
|
|
32
|
+
<div className="h-screen bg-gray-100">
|
|
33
|
+
<SidebarCore
|
|
34
|
+
sections={mockSections}
|
|
35
|
+
activeItem={activeItem}
|
|
36
|
+
onItemClick={setActiveItem}
|
|
37
|
+
companyName="HEXA Core"
|
|
38
|
+
onCompanyClick={() => console.log('Company clicked')}
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const Colapsado = {
|
|
46
|
+
render: () => {
|
|
47
|
+
const [activeItem, setActiveItem] = useState('inicio');
|
|
48
|
+
return (
|
|
49
|
+
<div className="h-screen bg-gray-100">
|
|
50
|
+
<SidebarCore
|
|
51
|
+
sections={mockSections}
|
|
52
|
+
activeItem={activeItem}
|
|
53
|
+
onItemClick={setActiveItem}
|
|
54
|
+
defaultCollapsed={true}
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const ConSeccionesPersonalizadas = {
|
|
62
|
+
render: () => {
|
|
63
|
+
const [activeItem, setActiveItem] = useState('item1');
|
|
64
|
+
const customSections = [
|
|
65
|
+
{
|
|
66
|
+
title: 'ADMINISTRACIÓN',
|
|
67
|
+
items: [
|
|
68
|
+
{ id: 'item1', label: 'Usuarios', icon: 'UserIcon' },
|
|
69
|
+
{ id: 'item2', label: 'Roles', icon: 'ShieldCheckIcon' },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
title: 'REPORTES',
|
|
74
|
+
items: [
|
|
75
|
+
{ id: 'item3', label: 'Analíticas', icon: 'ChartBarIcon' },
|
|
76
|
+
{ id: 'item4', label: 'Exportar', icon: 'ArrowDownTrayIcon' },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
return (
|
|
81
|
+
<div className="h-screen bg-gray-100">
|
|
82
|
+
<SidebarCore
|
|
83
|
+
sections={customSections}
|
|
84
|
+
activeItem={activeItem}
|
|
85
|
+
onItemClick={setActiveItem}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
|