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/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "anima-ds-nucleus",
3
- "version": "1.0.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
- "files": [
29
- "dist",
30
- "src"
31
- ],
32
- "scripts": {
33
- "dev": "vite",
34
- "build": "vite build",
35
- "build:app": "vite build --config vite.app.config.js",
36
- "preview": "vite preview",
37
- "storybook": "storybook dev -p 6006",
38
- "build-storybook": "storybook build"
39
- },
40
- "devDependencies": {
41
- "react": "^19.2.0",
42
- "react-dom": "^19.2.0",
43
- "@chromatic-com/storybook": "^4.1.3",
44
- "@storybook/addon-a11y": "^10.0.8",
45
- "@storybook/addon-docs": "^10.0.8",
46
- "@storybook/addon-onboarding": "^10.0.8",
47
- "@storybook/addon-vitest": "^10.0.8",
48
- "@storybook/react-vite": "^10.0.8",
49
- "@tailwindcss/postcss": "^4.1.17",
50
- "@vitejs/plugin-react": "^5.1.1",
51
- "@vitest/browser-playwright": "^4.0.10",
52
- "@vitest/coverage-v8": "^4.0.10",
53
- "autoprefixer": "^10.4.22",
54
- "playwright": "^1.56.1",
55
- "postcss": "^8.5.6",
56
- "storybook": "^10.0.8",
57
- "tailwindcss": "^4.1.17",
58
- "vite": "^7.2.2",
59
- "vitest": "^4.0.10"
60
- },
61
- "dependencies": {
62
- "@emotion/react": "^11.14.0",
63
- "@emotion/styled": "^11.14.1",
64
- "@heroicons/react": "^2.1.5",
65
- "@mui/material": "^7.3.5",
66
- "@mui/x-data-grid": "^8.18.0",
67
- "apexcharts": "^5.3.6",
68
- "i18next": "^25.6.2",
69
- "react-apexcharts": "^1.8.0",
70
- "react-i18next": "^16.3.3"
71
- },
72
- "peerDependencies": {
73
- "react": ">=18 <21",
74
- "react-dom": ">=18 <21"
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 = 'body1',
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
- // Clases genéricas basadas en Figma - Usando las clases predefinidas
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
- pruebaColor: 'text-4xl font-bold text-brand-600',
13
- h1: 'text-4xl font-bold',
14
- h2: 'text-3xl font-bold',
15
- h3: 'text-2xl font-semibold',
16
- h4: 'text-xl font-semibold',
17
- h5: 'text-lg font-medium',
18
- h6: 'text-base font-medium',
19
- body1: 'text-base',
20
- body2: 'text-sm',
21
- caption: 'text-xs text-gray-600',
22
- overline: 'text-xs uppercase tracking-wide',
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.body1;
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
- baseClasses = `${baseClasses} ${weightClasses[weight]}`;
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: 'pruebaColor',
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
+