anima-ds-nucleus 1.0.0 → 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/README.md +94 -13
- package/dist/anima-ds-nucleus.css +1 -0
- package/dist/anima-ds.cjs.js +99 -1299
- package/dist/anima-ds.esm.js +17383 -70929
- package/package.json +76 -76
- 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 +7 -0
- package/src/main.jsx +2 -2
- package/src/style.css +12 -0
- package/dist/vite.svg +0 -1
package/package.json
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "anima-ds-nucleus",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Anima Design System - A comprehensive React component library",
|
|
5
|
-
"author": "Nucleus Labs <ipvasallo@nucleus.com.ar>",
|
|
6
|
-
"license": "UNLICENSED",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/NucleusNova/anima-ds.git"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"react",
|
|
13
|
-
"design system",
|
|
14
|
-
"ui",
|
|
15
|
-
"components",
|
|
16
|
-
"anima",
|
|
17
|
-
"nucleus"
|
|
18
|
-
],
|
|
19
|
-
"type": "module",
|
|
20
|
-
"main": "./dist/anima-ds.cjs.js",
|
|
21
|
-
"module": "./dist/anima-ds.esm.js",
|
|
22
|
-
"exports": {
|
|
23
|
-
".": {
|
|
24
|
-
"import": "./dist/anima-ds.esm.js",
|
|
25
|
-
"require": "./dist/anima-ds.cjs.js"
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"build
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"react
|
|
43
|
-
"
|
|
44
|
-
"@storybook
|
|
45
|
-
"@storybook/addon-
|
|
46
|
-
"@storybook/addon-
|
|
47
|
-
"@storybook/addon-
|
|
48
|
-
"@storybook/
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"@vitest/
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"@
|
|
67
|
-
"
|
|
68
|
-
"i18next": "^
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
"react-
|
|
75
|
-
}
|
|
76
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "anima-ds-nucleus",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Anima Design System - A comprehensive React component library",
|
|
5
|
+
"author": "Nucleus Labs <ipvasallo@nucleus.com.ar>",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/NucleusNova/anima-ds.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"react",
|
|
13
|
+
"design system",
|
|
14
|
+
"ui",
|
|
15
|
+
"components",
|
|
16
|
+
"anima",
|
|
17
|
+
"nucleus"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"main": "./dist/anima-ds.cjs.js",
|
|
21
|
+
"module": "./dist/anima-ds.esm.js",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./dist/anima-ds.esm.js",
|
|
25
|
+
"require": "./dist/anima-ds.cjs.js"
|
|
26
|
+
},
|
|
27
|
+
"./styles": "./dist/anima-ds-nucleus.css"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"src"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "vite",
|
|
35
|
+
"build": "vite build",
|
|
36
|
+
"build:app": "vite build --config vite.app.config.js",
|
|
37
|
+
"preview": "vite preview",
|
|
38
|
+
"storybook": "storybook dev -p 6006",
|
|
39
|
+
"build-storybook": "storybook build"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"react": "^18.3.1",
|
|
43
|
+
"react-dom": "^18.3.1",
|
|
44
|
+
"@chromatic-com/storybook": "^4.1.3",
|
|
45
|
+
"@storybook/addon-a11y": "^10.0.8",
|
|
46
|
+
"@storybook/addon-docs": "^10.0.8",
|
|
47
|
+
"@storybook/addon-onboarding": "^10.0.8",
|
|
48
|
+
"@storybook/addon-vitest": "^10.0.8",
|
|
49
|
+
"@storybook/react-vite": "^10.0.8",
|
|
50
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
51
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
52
|
+
"@vitest/browser-playwright": "^4.0.10",
|
|
53
|
+
"@vitest/coverage-v8": "^4.0.10",
|
|
54
|
+
"autoprefixer": "^10.4.22",
|
|
55
|
+
"playwright": "^1.56.1",
|
|
56
|
+
"postcss": "^8.5.6",
|
|
57
|
+
"storybook": "^10.0.8",
|
|
58
|
+
"tailwindcss": "^4.1.17",
|
|
59
|
+
"vite": "^7.2.2",
|
|
60
|
+
"vitest": "^4.0.10"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"react": ">=18 <21",
|
|
65
|
+
"react-dom": ">=18 <21",
|
|
66
|
+
"@heroicons/react": "^2.0.0",
|
|
67
|
+
"i18next": "^25.0.0",
|
|
68
|
+
"react-i18next": "^16.0.0",
|
|
69
|
+
"@mui/material": "^7.0.0",
|
|
70
|
+
"@mui/x-data-grid": "^8.0.0",
|
|
71
|
+
"@emotion/react": "^11.0.0",
|
|
72
|
+
"@emotion/styled": "^11.0.0",
|
|
73
|
+
"apexcharts": "^5.0.0",
|
|
74
|
+
"react-apexcharts": "^1.8.0"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const Typography = ({
|
|
2
|
-
variant = '
|
|
2
|
+
variant = 'body-lg',
|
|
3
3
|
component,
|
|
4
4
|
children,
|
|
5
5
|
className = '',
|
|
@@ -7,29 +7,61 @@ export const Typography = ({
|
|
|
7
7
|
color,
|
|
8
8
|
...props
|
|
9
9
|
}) => {
|
|
10
|
-
//
|
|
10
|
+
// Mapeo de pesos a clases CSS genéricas
|
|
11
|
+
const weightClasses = {
|
|
12
|
+
light: 'font-light',
|
|
13
|
+
regular: 'font-regular',
|
|
14
|
+
medium: 'font-medium',
|
|
15
|
+
semibold: 'font-semibold',
|
|
16
|
+
bold: 'font-bold',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Mapeo de colores a clases CSS genéricas
|
|
20
|
+
const colorClasses = {
|
|
21
|
+
black: 'color-black',
|
|
22
|
+
white: 'color-white',
|
|
23
|
+
'gray-900': 'color-gray-900',
|
|
24
|
+
'gray-700': 'color-gray-700',
|
|
25
|
+
'gray-600': 'color-gray-600',
|
|
26
|
+
'gray-500': 'color-gray-500',
|
|
27
|
+
'gray-400': 'color-gray-400',
|
|
28
|
+
'red-600': 'color-red-600',
|
|
29
|
+
'red-500': 'color-red-500',
|
|
30
|
+
'blue-600': 'color-blue-600',
|
|
31
|
+
'green-600': 'color-green-600',
|
|
32
|
+
'green-100': 'color-green-100',
|
|
33
|
+
brand: 'color-brand', // Color brand principal del sistema (#56B676)
|
|
34
|
+
main: 'color-main', // Main color (verde-azulado oscuro #38656D)
|
|
35
|
+
teal: 'color-teal', // Teal color (usado en botones #2D5C63)
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Clases genéricas basadas en Figma - Usando las clases predefinidas del CSS
|
|
11
39
|
const variantClasses = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
h1: 'text-h1',
|
|
41
|
+
h2: 'text-h2',
|
|
42
|
+
h3: 'text-h3',
|
|
43
|
+
h4: 'text-h4',
|
|
44
|
+
h5: 'text-h5',
|
|
45
|
+
h6: 'text-h6',
|
|
46
|
+
'body-lg': 'text-body-lg',
|
|
47
|
+
'body-md': 'text-body-md',
|
|
48
|
+
'body-sm': 'text-body-sm',
|
|
49
|
+
body1: 'text-body-lg', // Alias de body-lg
|
|
50
|
+
body2: 'text-body-md', // Alias de body-md
|
|
51
|
+
caption: 'text-body-sm color-gray-600', // Body small con color gris por defecto
|
|
52
|
+
overline: 'text-body-sm uppercase tracking-wide',
|
|
23
53
|
};
|
|
24
54
|
|
|
25
55
|
const Component = component || (variant.startsWith('h') ? variant : 'p');
|
|
26
56
|
|
|
27
|
-
// Construir clases base
|
|
28
|
-
let baseClasses = variantClasses[variant] || variantClasses
|
|
57
|
+
// Construir clases base usando las clases genéricas CSS
|
|
58
|
+
let baseClasses = variantClasses[variant] || variantClasses['body-lg'];
|
|
29
59
|
|
|
30
|
-
// Si se especifica un peso, agregarlo
|
|
60
|
+
// Si se especifica un peso, agregarlo (remover peso por defecto si existe)
|
|
31
61
|
if (weight && weightClasses[weight]) {
|
|
32
|
-
|
|
62
|
+
// Remover cualquier peso previo de las clases base (font-light, font-regular, etc.)
|
|
63
|
+
baseClasses = baseClasses.replace(/font-(light|regular|medium|semibold|bold)/g, '');
|
|
64
|
+
baseClasses = `${baseClasses} ${weightClasses[weight]}`.trim();
|
|
33
65
|
}
|
|
34
66
|
|
|
35
67
|
// Si se especifica un color, agregarlo (remover color por defecto si existe, como en caption)
|
|
@@ -49,4 +81,3 @@ export const Typography = ({
|
|
|
49
81
|
};
|
|
50
82
|
|
|
51
83
|
export default Typography;
|
|
52
|
-
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
},
|
|
16
16
|
color: {
|
|
17
17
|
control: 'select',
|
|
18
|
-
options: ['black', 'white', 'gray-900', 'gray-700', 'gray-600', 'gray-500', 'gray-400', 'red-600', 'red-500', 'blue-600', 'green-600', 'green-100'],
|
|
18
|
+
options: ['black', 'white', 'gray-900', 'gray-700', 'gray-600', 'gray-500', 'gray-400', 'red-600', 'red-500', 'blue-600', 'green-600', 'green-100', 'brand', 'main', 'teal'],
|
|
19
19
|
description: 'Color del texto usando clases genéricas predefinidas',
|
|
20
20
|
},
|
|
21
21
|
},
|
|
@@ -24,8 +24,8 @@ export default {
|
|
|
24
24
|
// Ejemplos usando el componente Typography
|
|
25
25
|
export const Heading1 = {
|
|
26
26
|
args: {
|
|
27
|
-
variant: '
|
|
28
|
-
children: 'Heading 1',
|
|
27
|
+
variant: 'h1',
|
|
28
|
+
children: 'Heading 1 - IBM Plex Sans 40/60 Bold',
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
3
|
+
import { Avatar } from '../../Atoms/Avatar/Avatar';
|
|
4
|
+
import { Typography } from '../../Atoms/Typography/Typography';
|
|
5
|
+
|
|
6
|
+
export const HeaderConBuscador = ({
|
|
7
|
+
searchPlaceholder = 'Buscar empleados, reportes, configuraciones...',
|
|
8
|
+
userName,
|
|
9
|
+
userAvatar,
|
|
10
|
+
notificationCount = 0,
|
|
11
|
+
onSearch,
|
|
12
|
+
onNotificationClick,
|
|
13
|
+
onUserClick,
|
|
14
|
+
className = '',
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
const [searchValue, setSearchValue] = useState('');
|
|
18
|
+
|
|
19
|
+
const handleSearchChange = (e) => {
|
|
20
|
+
const value = e.target.value;
|
|
21
|
+
setSearchValue(value);
|
|
22
|
+
if (onSearch) {
|
|
23
|
+
onSearch(value);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const handleSearchSubmit = (e) => {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
if (onSearch) {
|
|
30
|
+
onSearch(searchValue);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<header
|
|
36
|
+
className={`bg-white border-b border-gray-200 ${className}`}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
|
40
|
+
<div className="flex items-center justify-between h-16">
|
|
41
|
+
{/* Barra de búsqueda */}
|
|
42
|
+
<div className="flex-1 max-w-2xl mr-8">
|
|
43
|
+
<form onSubmit={handleSearchSubmit} className="relative">
|
|
44
|
+
<input
|
|
45
|
+
type="text"
|
|
46
|
+
value={searchValue}
|
|
47
|
+
onChange={handleSearchChange}
|
|
48
|
+
placeholder={searchPlaceholder}
|
|
49
|
+
className="w-full pl-4 pr-12 py-2.5 bg-slate-50 border border-gray-200 rounded-lg
|
|
50
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
|
|
51
|
+
text-body-md color-gray-700 placeholder:color-gray-400"
|
|
52
|
+
/>
|
|
53
|
+
<button
|
|
54
|
+
type="submit"
|
|
55
|
+
className="absolute right-3 top-1/2 transform -translate-y-1/2
|
|
56
|
+
hover:opacity-70 transition-opacity"
|
|
57
|
+
aria-label="Buscar"
|
|
58
|
+
>
|
|
59
|
+
<Icon
|
|
60
|
+
name="MagnifyingGlassIcon"
|
|
61
|
+
variant="24-outline"
|
|
62
|
+
size={20}
|
|
63
|
+
className="color-gray-400"
|
|
64
|
+
/>
|
|
65
|
+
</button>
|
|
66
|
+
</form>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{/* Notificaciones y Perfil */}
|
|
70
|
+
<div className="flex items-center space-x-6">
|
|
71
|
+
{/* Icono de notificaciones */}
|
|
72
|
+
{notificationCount !== undefined && (
|
|
73
|
+
<button
|
|
74
|
+
onClick={onNotificationClick}
|
|
75
|
+
className="flex items-center space-x-2 p-2 hover:bg-gray-100 rounded-lg transition-colors"
|
|
76
|
+
aria-label="Notificaciones"
|
|
77
|
+
>
|
|
78
|
+
<Icon
|
|
79
|
+
name="BellIcon"
|
|
80
|
+
variant="24-outline"
|
|
81
|
+
size={24}
|
|
82
|
+
className="color-gray-600"
|
|
83
|
+
/>
|
|
84
|
+
{notificationCount > 0 && (
|
|
85
|
+
<span
|
|
86
|
+
className="px-2 py-0.5 min-w-[20px] h-5
|
|
87
|
+
text-white rounded-full flex items-center justify-center
|
|
88
|
+
text-body-sm font-medium"
|
|
89
|
+
style={{
|
|
90
|
+
backgroundColor: '#6D3856',
|
|
91
|
+
borderRadius: '12px'
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{notificationCount > 9 ? '9+' : notificationCount}
|
|
95
|
+
</span>
|
|
96
|
+
)}
|
|
97
|
+
</button>
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{/* Perfil de usuario */}
|
|
101
|
+
{userName && (
|
|
102
|
+
<button
|
|
103
|
+
onClick={onUserClick}
|
|
104
|
+
className="flex items-center space-x-3 hover:bg-gray-50
|
|
105
|
+
rounded-lg px-2 py-1.5 transition-colors"
|
|
106
|
+
aria-label="Perfil de usuario"
|
|
107
|
+
>
|
|
108
|
+
<Avatar
|
|
109
|
+
src={userAvatar}
|
|
110
|
+
name={userName}
|
|
111
|
+
size="medium"
|
|
112
|
+
variant="circle"
|
|
113
|
+
/>
|
|
114
|
+
<Typography
|
|
115
|
+
variant="body-md"
|
|
116
|
+
className="color-teal font-medium hidden sm:block"
|
|
117
|
+
>
|
|
118
|
+
{userName}
|
|
119
|
+
</Typography>
|
|
120
|
+
<Icon
|
|
121
|
+
name="ChevronDownIcon"
|
|
122
|
+
variant="24-outline"
|
|
123
|
+
size={20}
|
|
124
|
+
className="color-gray-500 hidden sm:block"
|
|
125
|
+
/>
|
|
126
|
+
</button>
|
|
127
|
+
)}
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</header>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export default HeaderConBuscador;
|
|
136
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { HeaderConBuscador } from './HeaderConBuscador';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Layout/HeaderConBuscador',
|
|
6
|
+
component: HeaderConBuscador,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const Default = {
|
|
11
|
+
render: () => {
|
|
12
|
+
const [searchValue, setSearchValue] = useState('');
|
|
13
|
+
return (
|
|
14
|
+
<HeaderConBuscador
|
|
15
|
+
searchPlaceholder="Buscar empleados, reportes, configuraciones..."
|
|
16
|
+
userName="Maria Garcia Alonso"
|
|
17
|
+
userAvatar="https://i.pravatar.cc/150?img=47"
|
|
18
|
+
notificationCount={2}
|
|
19
|
+
onSearch={(value) => {
|
|
20
|
+
setSearchValue(value);
|
|
21
|
+
console.log('Buscando:', value);
|
|
22
|
+
}}
|
|
23
|
+
onNotificationClick={() => {
|
|
24
|
+
console.log('Notificaciones clickeadas');
|
|
25
|
+
}}
|
|
26
|
+
onUserClick={() => {
|
|
27
|
+
console.log('Perfil clickeado');
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const SinNotificaciones = {
|
|
35
|
+
render: () => (
|
|
36
|
+
<HeaderConBuscador
|
|
37
|
+
userName="Juan Pérez"
|
|
38
|
+
notificationCount={0}
|
|
39
|
+
/>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const SinNotificacionesProp = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<HeaderConBuscador
|
|
46
|
+
userName="Ana López"
|
|
47
|
+
/>
|
|
48
|
+
),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const ConMuchasNotificaciones = {
|
|
52
|
+
render: () => (
|
|
53
|
+
<HeaderConBuscador
|
|
54
|
+
userName="Carlos Rodríguez"
|
|
55
|
+
notificationCount={15}
|
|
56
|
+
/>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const SinAvatar = {
|
|
61
|
+
render: () => (
|
|
62
|
+
<HeaderConBuscador
|
|
63
|
+
userName="Laura Martínez"
|
|
64
|
+
notificationCount={3}
|
|
65
|
+
/>
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const CustomSearchPlaceholder = {
|
|
70
|
+
render: () => (
|
|
71
|
+
<HeaderConBuscador
|
|
72
|
+
searchPlaceholder="Buscar en el sistema..."
|
|
73
|
+
userName="Pedro Sánchez"
|
|
74
|
+
notificationCount={1}
|
|
75
|
+
/>
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Typography } from '../../Atoms/Typography/Typography';
|
|
2
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
3
|
+
|
|
4
|
+
export const HeaderCore = ({
|
|
5
|
+
logo,
|
|
6
|
+
companyName = 'HEXA Core',
|
|
7
|
+
date,
|
|
8
|
+
pointLabel = 'HEXA Point',
|
|
9
|
+
onPointClick,
|
|
10
|
+
className = '',
|
|
11
|
+
...props
|
|
12
|
+
}) => {
|
|
13
|
+
// Formatear fecha si no se proporciona
|
|
14
|
+
const formattedDate = date || new Date().toLocaleDateString('es-AR', {
|
|
15
|
+
weekday: 'long',
|
|
16
|
+
year: 'numeric',
|
|
17
|
+
month: 'long',
|
|
18
|
+
day: 'numeric',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Capitalizar primera letra de la fecha
|
|
22
|
+
const capitalizedDate = formattedDate.charAt(0).toUpperCase() + formattedDate.slice(1);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<header
|
|
26
|
+
className={`bg-white border-b border-gray-200 ${className}`}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
|
30
|
+
<div className="flex items-center justify-between h-16">
|
|
31
|
+
{/* Lado izquierdo: Línea vertical, logo y nombre */}
|
|
32
|
+
<div className="flex items-center space-x-4">
|
|
33
|
+
{/* Línea vertical */}
|
|
34
|
+
<div className="w-px h-8 bg-gray-400"></div>
|
|
35
|
+
|
|
36
|
+
{/* Logo hexagonal */}
|
|
37
|
+
{logo ? (
|
|
38
|
+
<img
|
|
39
|
+
src={logo}
|
|
40
|
+
alt={companyName}
|
|
41
|
+
className="w-8 h-8"
|
|
42
|
+
/>
|
|
43
|
+
) : (
|
|
44
|
+
<svg
|
|
45
|
+
width="36"
|
|
46
|
+
height="36"
|
|
47
|
+
viewBox="0 0 36 36"
|
|
48
|
+
fill="none"
|
|
49
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
50
|
+
className="w-9 h-9"
|
|
51
|
+
>
|
|
52
|
+
{/* Hexágono con fondo verde oscuro y esquinas redondeadas - más ancho */}
|
|
53
|
+
<path
|
|
54
|
+
d="M18 4L28 9L28 27L18 32L8 27L8 9L18 4Z"
|
|
55
|
+
fill="#2D5C63"
|
|
56
|
+
stroke="#2D5C63"
|
|
57
|
+
strokeWidth="0.5"
|
|
58
|
+
strokeLinejoin="round"
|
|
59
|
+
/>
|
|
60
|
+
{/* H estilizada en blanco - bold con bordes redondeados */}
|
|
61
|
+
<path
|
|
62
|
+
d="M15 13V23M21 13V23M15 18H21"
|
|
63
|
+
stroke="white"
|
|
64
|
+
strokeWidth="1.5"
|
|
65
|
+
strokeLinecap="round"
|
|
66
|
+
strokeLinejoin="round"
|
|
67
|
+
/>
|
|
68
|
+
</svg>
|
|
69
|
+
)}
|
|
70
|
+
|
|
71
|
+
{/* Nombre de la empresa */}
|
|
72
|
+
<Typography
|
|
73
|
+
variant="body-md"
|
|
74
|
+
className="color-teal font-bold"
|
|
75
|
+
>
|
|
76
|
+
{companyName}
|
|
77
|
+
</Typography>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
{/* Centro: Fecha */}
|
|
81
|
+
<div className="flex-1 flex justify-center">
|
|
82
|
+
<Typography
|
|
83
|
+
variant="body-md"
|
|
84
|
+
className="color-gray-500"
|
|
85
|
+
>
|
|
86
|
+
{capitalizedDate}
|
|
87
|
+
</Typography>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
{/* Lado derecho: Botón HEXA Point */}
|
|
91
|
+
<div className="flex items-center">
|
|
92
|
+
<button
|
|
93
|
+
onClick={onPointClick}
|
|
94
|
+
className="px-4 py-2 border bg-white rounded-lg
|
|
95
|
+
hover:bg-gray-50 transition-colors flex items-center space-x-2"
|
|
96
|
+
style={{ borderColor: '#2D5C63' }}
|
|
97
|
+
>
|
|
98
|
+
<Typography
|
|
99
|
+
variant="body-md"
|
|
100
|
+
className="color-teal"
|
|
101
|
+
>
|
|
102
|
+
{pointLabel}
|
|
103
|
+
</Typography>
|
|
104
|
+
<Icon
|
|
105
|
+
name="ArrowUpRightIcon"
|
|
106
|
+
variant="24-outline"
|
|
107
|
+
size={16}
|
|
108
|
+
className="color-teal"
|
|
109
|
+
/>
|
|
110
|
+
</button>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</header>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default HeaderCore;
|
|
119
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HeaderCore } from './HeaderCore';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Layout/HeaderCore',
|
|
5
|
+
component: HeaderCore,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
render: () => (
|
|
11
|
+
<HeaderCore
|
|
12
|
+
companyName="HEXA Corp"
|
|
13
|
+
date="Martes, 20 de octubre de 2023"
|
|
14
|
+
newElementLabel="NUEVO ELEMENTO"
|
|
15
|
+
pointLabel="HEXA Point"
|
|
16
|
+
onNewElementClick={() => console.log('Nuevo elemento clickeado')}
|
|
17
|
+
onPointClick={() => console.log('HEXA Point clickeado')}
|
|
18
|
+
/>
|
|
19
|
+
),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const ConFechaAutomatica = {
|
|
23
|
+
render: () => (
|
|
24
|
+
<HeaderCore
|
|
25
|
+
companyName="HEXA Corp"
|
|
26
|
+
newElementLabel="NUEVO ELEMENTO"
|
|
27
|
+
pointLabel="HEXA Point"
|
|
28
|
+
/>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const ConLogoPersonalizado = {
|
|
33
|
+
render: () => (
|
|
34
|
+
<HeaderCore
|
|
35
|
+
companyName="Mi Empresa"
|
|
36
|
+
logo="https://via.placeholder.com/32"
|
|
37
|
+
date="Lunes, 15 de enero de 2024"
|
|
38
|
+
newElementLabel="CREAR"
|
|
39
|
+
pointLabel="Mi Punto"
|
|
40
|
+
/>
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const ConLabelsPersonalizados = {
|
|
45
|
+
render: () => (
|
|
46
|
+
<HeaderCore
|
|
47
|
+
companyName="ACME Corp"
|
|
48
|
+
date="Viernes, 25 de diciembre de 2024"
|
|
49
|
+
newElementLabel="AGREGAR"
|
|
50
|
+
pointLabel="ACME Hub"
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
|