anteriority-ui 1.0.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.
Files changed (199) hide show
  1. package/.github/workflows/ci.yml +31 -0
  2. package/.github/workflows/publish.yml +45 -0
  3. package/.npmrc.bak +1 -0
  4. package/.storybook/main.js +15 -0
  5. package/.storybook/preview.jsx +26 -0
  6. package/AnteriorityUI.md +2400 -0
  7. package/CLAUDE.md +91 -0
  8. package/README.md +182 -0
  9. package/assets/anteriorityUI/AnteriorityUI.logo.jpeg +0 -0
  10. package/assets/favicon/anteriorityUI.ico +0 -0
  11. package/common/api/client.js +43 -0
  12. package/common/storage/LocalStorage.js +13 -0
  13. package/common/styles/typography.css +5 -0
  14. package/common/styles/variables.css +192 -0
  15. package/common/theme/muiTheme.js +9 -0
  16. package/features/password-reset/api.js +39 -0
  17. package/features/user-profile/api.js +5 -0
  18. package/hooks/useAdminPasswordReset.js +133 -0
  19. package/index.js +57 -0
  20. package/package.json +57 -0
  21. package/pnpm-workspace.yaml +3 -0
  22. package/screens/components/AlertModal/AlertModal.jsx +259 -0
  23. package/screens/components/AlertModal/AlertModal.module.css +185 -0
  24. package/screens/components/AlertModal/AlertModal.stories.jsx +87 -0
  25. package/screens/components/Avatar/index.jsx +0 -0
  26. package/screens/components/Avatar/index.module.css +0 -0
  27. package/screens/components/Avatar/utils.js +0 -0
  28. package/screens/components/Badge/index.jsx +33 -0
  29. package/screens/components/Badge/index.module.css +18 -0
  30. package/screens/components/Badge/index.stories.jsx +40 -0
  31. package/screens/components/Barnner/index.jsx +21 -0
  32. package/screens/components/Barnner/index.module.css +33 -0
  33. package/screens/components/Barnner/index.stories.jsx +39 -0
  34. package/screens/components/Barnner/utils.js +0 -0
  35. package/screens/components/BlueLink/index.jsx +27 -0
  36. package/screens/components/BlueLink/index.module.css +11 -0
  37. package/screens/components/BlueLink/index.stories.jsx +29 -0
  38. package/screens/components/Breadcrumbs/index.jsx +62 -0
  39. package/screens/components/Breadcrumbs/index.module.css +158 -0
  40. package/screens/components/Breadcrumbs/index.stories.jsx +37 -0
  41. package/screens/components/Button/index.jsx +169 -0
  42. package/screens/components/Button/index.module.css +168 -0
  43. package/screens/components/Button/index.stories.jsx +71 -0
  44. package/screens/components/Button/utils.js +28 -0
  45. package/screens/components/CalendarComponent/CustomDatePicker.jsx +248 -0
  46. package/screens/components/CalendarComponent/CustomDatePicker.module.css +323 -0
  47. package/screens/components/CalendarComponent/CustomDatePicker.stories.jsx +45 -0
  48. package/screens/components/CalendarPicker/Constants.js +12 -0
  49. package/screens/components/CalendarPicker/index.jsx +263 -0
  50. package/screens/components/CalendarPicker/index.module.css +147 -0
  51. package/screens/components/CalendarPicker/index.stories.jsx +45 -0
  52. package/screens/components/CalendarPicker/utils.js +42 -0
  53. package/screens/components/CardV1/index.jsx +165 -0
  54. package/screens/components/CardV1/index.module.css +232 -0
  55. package/screens/components/CardV1/index.stories.jsx +62 -0
  56. package/screens/components/CardV1/utils.js +49 -0
  57. package/screens/components/ChatWindow/index.jsx +251 -0
  58. package/screens/components/ChatWindow/index.module.css +311 -0
  59. package/screens/components/ChatWindow/index.stories.jsx +62 -0
  60. package/screens/components/Checks/index.jsx +31 -0
  61. package/screens/components/Checks/index.module.css +32 -0
  62. package/screens/components/Checks/index.stories.jsx +32 -0
  63. package/screens/components/Container/index.jsx +36 -0
  64. package/screens/components/Container/index.module.css +24 -0
  65. package/screens/components/Container/index.stories.jsx +32 -0
  66. package/screens/components/CopyText/index.jsx +42 -0
  67. package/screens/components/CopyText/index.module.css +52 -0
  68. package/screens/components/CopyText/index.stories.jsx +24 -0
  69. package/screens/components/CountdownBar/constants.js +3 -0
  70. package/screens/components/CountdownBar/index.jsx +81 -0
  71. package/screens/components/CountdownBar/index.module.css +45 -0
  72. package/screens/components/CountdownBar/index.stories.jsx +43 -0
  73. package/screens/components/CountdownBar/utils.js +119 -0
  74. package/screens/components/DateTag/index.jsx +33 -0
  75. package/screens/components/DateTag/index.module.css +12 -0
  76. package/screens/components/DateTag/index.stories.jsx +29 -0
  77. package/screens/components/DesplegablePanel/constants.js +0 -0
  78. package/screens/components/DesplegablePanel/index.jsx +61 -0
  79. package/screens/components/DesplegablePanel/index.module.css +120 -0
  80. package/screens/components/DesplegablePanel/index.stories.jsx +44 -0
  81. package/screens/components/DesplegablePanel/utils.js +0 -0
  82. package/screens/components/DrawPanel/index.jsx +217 -0
  83. package/screens/components/DrawPanel/index.module.css +252 -0
  84. package/screens/components/DrawPanel/index.stories.jsx +66 -0
  85. package/screens/components/DrawPanel/utils.js +0 -0
  86. package/screens/components/Filter/index.jsx +105 -0
  87. package/screens/components/Filter/index.module.css +91 -0
  88. package/screens/components/Filter/index.stories.jsx +46 -0
  89. package/screens/components/Filter/utils.js +0 -0
  90. package/screens/components/FormControls/FormControls.module.css +86 -0
  91. package/screens/components/FormControls/index.jsx +51 -0
  92. package/screens/components/FormControls/index.stories.jsx +36 -0
  93. package/screens/components/Frame/index.jsx +54 -0
  94. package/screens/components/Frame/index.module.css +102 -0
  95. package/screens/components/Frame/index.stories.jsx +37 -0
  96. package/screens/components/Frame/utils.js +0 -0
  97. package/screens/components/GreenHighlight/index.jsx +11 -0
  98. package/screens/components/GreenHighlight/index.module.css +7 -0
  99. package/screens/components/GreenHighlight/index.stories.jsx +26 -0
  100. package/screens/components/GreenHighlight/utils.jsx +45 -0
  101. package/screens/components/HoursPicker/Constants.js +26 -0
  102. package/screens/components/HoursPicker/index.jsx +350 -0
  103. package/screens/components/HoursPicker/index.module.css +99 -0
  104. package/screens/components/HoursPicker/index.stories.jsx +44 -0
  105. package/screens/components/HoursPicker/utils.js +48 -0
  106. package/screens/components/InfoTooltip/index.jsx +59 -0
  107. package/screens/components/InfoTooltip/index.module.css +98 -0
  108. package/screens/components/InfoTooltip/index.stories.jsx +35 -0
  109. package/screens/components/Input/index.jsx +36 -0
  110. package/screens/components/Input/index.module.css +49 -0
  111. package/screens/components/Input/index.stories.jsx +37 -0
  112. package/screens/components/Input/utils.js +0 -0
  113. package/screens/components/Loading/index.jsx +76 -0
  114. package/screens/components/Loading/index.module.css +193 -0
  115. package/screens/components/Loading/index.stories.jsx +38 -0
  116. package/screens/components/Loading/utils.js +0 -0
  117. package/screens/components/MarkdownContent/index.jsx +16 -0
  118. package/screens/components/MarkdownContent/index.module.css +149 -0
  119. package/screens/components/MarkdownContent/index.stories.jsx +30 -0
  120. package/screens/components/MarkdownEditor/index.jsx +430 -0
  121. package/screens/components/MarkdownEditor/index.module.css +192 -0
  122. package/screens/components/MarkdownEditor/index.stories.jsx +50 -0
  123. package/screens/components/Material-UI/Components/InputWithIcon/index.jsx +87 -0
  124. package/screens/components/Material-UI/Components/InputWithIcon/index.stories.jsx +49 -0
  125. package/screens/components/Material-UI/Components/MenuPopover/index.jsx +117 -0
  126. package/screens/components/Material-UI/Components/MenuPopover/index.stories.jsx +36 -0
  127. package/screens/components/Material-UI/Components/MultilinePlaceholder/index.jsx +44 -0
  128. package/screens/components/Material-UI/Components/MultilinePlaceholder/index.stories.jsx +45 -0
  129. package/screens/components/Material-UI/Components/Paginador/index.jsx +79 -0
  130. package/screens/components/Material-UI/Components/Paginador/index.stories.jsx +49 -0
  131. package/screens/components/Material-UI/Components/Search/index.jsx +81 -0
  132. package/screens/components/Material-UI/Components/Search/index.stories.jsx +68 -0
  133. package/screens/components/Material-UI/Components/Selector/index.jsx +100 -0
  134. package/screens/components/Material-UI/Components/Selector/index.module.css +0 -0
  135. package/screens/components/Material-UI/Components/Selector/index.stories.jsx +52 -0
  136. package/screens/components/Material-UI/Components/Selector/utils.js +0 -0
  137. package/screens/components/Material-UI/Components/TextField/index.jsx +61 -0
  138. package/screens/components/Material-UI/Components/TextField/index.stories.jsx +53 -0
  139. package/screens/components/ModalTooltip/ModalTooltip.jsx +122 -0
  140. package/screens/components/ModalTooltip/ModalTooltip.module.css +65 -0
  141. package/screens/components/ModalTooltip/ModalTooltip.stories.jsx +39 -0
  142. package/screens/components/Notification/Error/ErrorMessage.jsx +30 -0
  143. package/screens/components/Notification/Error/ErrorMessage.module.css +57 -0
  144. package/screens/components/Notification/Error/ErrorMessage.stories.jsx +37 -0
  145. package/screens/components/PasswordResetPanel/index.jsx +325 -0
  146. package/screens/components/PasswordResetPanel/index.stories.jsx +26 -0
  147. package/screens/components/PlaceholderButton/index.jsx +169 -0
  148. package/screens/components/PlaceholderButton/index.module.css +162 -0
  149. package/screens/components/PlaceholderButton/index.stories.jsx +69 -0
  150. package/screens/components/PlaceholderButton/utils.js +42 -0
  151. package/screens/components/Profile/Avatar/index.jsx +125 -0
  152. package/screens/components/Profile/Avatar/index.module.css +86 -0
  153. package/screens/components/Profile/Avatar/index.stories.jsx +48 -0
  154. package/screens/components/Profile/Avatar/utils.js +18 -0
  155. package/screens/components/Profile/index.jsx +58 -0
  156. package/screens/components/Profile/index.module.css +0 -0
  157. package/screens/components/Profile/index.stories.jsx +38 -0
  158. package/screens/components/Profile/utils.js +0 -0
  159. package/screens/components/ScrollBar/index.jsx +62 -0
  160. package/screens/components/ScrollBar/index.module.css +78 -0
  161. package/screens/components/ScrollBar/index.stories.jsx +64 -0
  162. package/screens/components/ScrollBar/utils.js +127 -0
  163. package/screens/components/Sidebar/constants.js +16 -0
  164. package/screens/components/Sidebar/index.jsx +399 -0
  165. package/screens/components/Sidebar/index.module.css +405 -0
  166. package/screens/components/Sidebar/index.stories.jsx +86 -0
  167. package/screens/components/Sidebar/utils.js +75 -0
  168. package/screens/components/Skeleton/index.jsx +11 -0
  169. package/screens/components/Skeleton/index.module.css +26 -0
  170. package/screens/components/Skeleton/index.stories.jsx +42 -0
  171. package/screens/components/SubSidebarLayout/index.jsx +44 -0
  172. package/screens/components/SubSidebarLayout/index.module.css +80 -0
  173. package/screens/components/SubSidebarLayout/index.stories.jsx +51 -0
  174. package/screens/components/SummaryCard/index.jsx +50 -0
  175. package/screens/components/SummaryCard/index.module.css +30 -0
  176. package/screens/components/SummaryCard/index.stories.jsx +29 -0
  177. package/screens/components/Swich/constants.js +4 -0
  178. package/screens/components/Swich/index.jsx +85 -0
  179. package/screens/components/Swich/index.module.css +68 -0
  180. package/screens/components/Swich/index.stories.jsx +44 -0
  181. package/screens/components/Swich/utils.js +0 -0
  182. package/screens/components/TableA/index.jsx +156 -0
  183. package/screens/components/TableA/index.module.css +105 -0
  184. package/screens/components/TableA/index.stories.jsx +116 -0
  185. package/screens/components/TableA/utils.js +11 -0
  186. package/screens/components/TableB/index.jsx +222 -0
  187. package/screens/components/TableB/index.module.css +295 -0
  188. package/screens/components/TableB/index.stories.jsx +110 -0
  189. package/screens/components/TableB/utils.js +11 -0
  190. package/screens/components/ToggleCard/index.jsx +64 -0
  191. package/screens/components/ToggleCard/index.module.css +111 -0
  192. package/screens/components/ToggleCard/index.stories.jsx +49 -0
  193. package/screens/components/UserEditPopover/index.jsx +102 -0
  194. package/screens/components/UserEditPopover/index.module.css +97 -0
  195. package/screens/components/UserEditPopover/index.stories.jsx +49 -0
  196. package/scripts/build.mjs +129 -0
  197. package/scripts/check-case.mjs +127 -0
  198. package/scripts/verify-dist.mjs +45 -0
  199. package/vitest.config.js +36 -0
@@ -0,0 +1,59 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { HelpCircle } from 'lucide-react';
3
+ import styles from './index.module.css';
4
+
5
+ const InfoTooltip = ({
6
+ content,
7
+ title,
8
+ icon: Icon = HelpCircle,
9
+ iconSize = 18,
10
+ iconColor = "#94a3b8",
11
+ width = "280px"
12
+ }) => {
13
+ const [isOpen, setIsOpen] = useState(false);
14
+ const containerRef = useRef(null);
15
+
16
+ useEffect(() => {
17
+ if (!isOpen) return;
18
+ const handleClickOutside = (e) => {
19
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
20
+ setIsOpen(false);
21
+ }
22
+ };
23
+ document.addEventListener('mousedown', handleClickOutside);
24
+ return () => document.removeEventListener('mousedown', handleClickOutside);
25
+ }, [isOpen]);
26
+
27
+ return (
28
+ <div className={styles.container} ref={containerRef}>
29
+ <button
30
+ type="button"
31
+ className={styles.triggerButton}
32
+ onClick={(e) => { e.preventDefault(); setIsOpen(!isOpen); }}
33
+ aria-label={title || "Información"}
34
+ >
35
+ <Icon size={iconSize} color={iconColor} className={styles.icon} />
36
+ </button>
37
+
38
+ {isOpen && (
39
+ <div className={styles.popover} style={{ width }}>
40
+ <div className={styles.popoverContent}>
41
+ {title && <h4 className={styles.popoverTitle}>{title}</h4>}
42
+ <div className={styles.popoverBody}>
43
+ {Array.isArray(content)
44
+ ? content.map((p, i) => (
45
+ <p key={i} style={{ marginBottom: i < content.length - 1 ? '0.5rem' : 0 }}>
46
+ {p}
47
+ </p>
48
+ ))
49
+ : content}
50
+ </div>
51
+ </div>
52
+ <div className={styles.arrow}></div>
53
+ </div>
54
+ )}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default InfoTooltip;
@@ -0,0 +1,98 @@
1
+ .container {
2
+ position: relative;
3
+ display: inline-flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ }
7
+
8
+ .triggerButton {
9
+ background: transparent;
10
+ border: none;
11
+ cursor: pointer;
12
+ padding: 6px;
13
+ border-radius: 50%;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ transition: all 0.2s ease;
18
+ }
19
+
20
+ .triggerButton:hover {
21
+ background: #f1f5f9;
22
+ }
23
+
24
+ .icon {
25
+ transition: color 0.2s ease;
26
+ }
27
+
28
+ .triggerButton:hover .icon {
29
+ color: #475569 !important;
30
+ }
31
+
32
+ .popover {
33
+ position: absolute;
34
+ bottom: calc(100% + 12px); /* Space for arrow and gap */
35
+ left: 50%;
36
+ transform: translateX(-50%);
37
+ background: #ffffff;
38
+ border: 1px solid #e2e8f0;
39
+ border-radius: 12px;
40
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
41
+ z-index: 1000;
42
+ animation: slideUpFade 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards;
43
+ pointer-events: auto;
44
+ }
45
+
46
+ .arrow {
47
+ position: absolute;
48
+ bottom: -6px;
49
+ left: 50%;
50
+ transform: translateX(-50%) rotate(45deg);
51
+ width: 12px;
52
+ height: 12px;
53
+ background: #ffffff;
54
+ border-right: 1px solid #e2e8f0;
55
+ border-bottom: 1px solid #e2e8f0;
56
+ }
57
+
58
+ .popoverContent {
59
+ padding: 1rem;
60
+ position: relative;
61
+ z-index: 2;
62
+ background: #ffffff;
63
+ border-radius: 12px;
64
+ }
65
+
66
+ .popoverTitle {
67
+ margin: 0 0 0.5rem 0;
68
+ font-size: 0.95rem;
69
+ font-weight: 600;
70
+ color: #1e293b;
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 0.5rem;
74
+ padding-bottom: 0.5rem;
75
+ border-bottom: 1px solid #f1f5f9;
76
+ }
77
+
78
+ .popoverBody {
79
+ font-size: 0.85rem;
80
+ line-height: 1.5;
81
+ color: #475569;
82
+ text-align: left;
83
+ }
84
+
85
+ .popoverBody p {
86
+ margin: 0;
87
+ }
88
+
89
+ @keyframes slideUpFade {
90
+ from {
91
+ opacity: 0;
92
+ transform: translateX(-50%) translateY(10px);
93
+ }
94
+ to {
95
+ opacity: 1;
96
+ transform: translateX(-50%) translateY(0);
97
+ }
98
+ }
@@ -0,0 +1,35 @@
1
+ import { Info } from 'lucide-react';
2
+ import InfoTooltip from './index.jsx';
3
+
4
+ export default {
5
+ title: 'Components/InfoTooltip',
6
+ component: InfoTooltip,
7
+ };
8
+
9
+ export const Default = {
10
+ args: {
11
+ title: '¿Qué es esto?',
12
+ content: 'Este campo se utiliza para identificar de forma única cada registro en el sistema.',
13
+ },
14
+ };
15
+
16
+ export const MultipleParagraphs = {
17
+ args: {
18
+ title: 'Detalles del cálculo',
19
+ content: [
20
+ 'El total se calcula sumando todos los conceptos activos.',
21
+ 'Los descuentos se aplican antes de los impuestos.',
22
+ ],
23
+ },
24
+ };
25
+
26
+ export const CustomIcon = {
27
+ args: {
28
+ title: 'Información adicional',
29
+ content: 'Puedes personalizar el ícono, tamaño y color del disparador.',
30
+ icon: Info,
31
+ iconSize: 22,
32
+ iconColor: '#3b82f6',
33
+ width: '320px',
34
+ },
35
+ };
@@ -0,0 +1,36 @@
1
+ import React, { forwardRef } from 'react';
2
+ import TextField from '../Material-UI/Components/TextField/index';
3
+
4
+ const Input = forwardRef(({
5
+ label,
6
+ id,
7
+ className = '',
8
+ error,
9
+ helperText,
10
+ required,
11
+ requiredColor = 'red',
12
+ ...props
13
+ }, ref) => {
14
+ const displayLabel = label ? (
15
+ <span>
16
+ {label}
17
+ {required && <span style={{ color: requiredColor, marginLeft: '4px' }}>**</span>}
18
+ </span>
19
+ ) : undefined;
20
+
21
+ return (
22
+ <TextField
23
+ id={id}
24
+ label={displayLabel}
25
+ error={error}
26
+ helperText={error || helperText}
27
+ ref={ref}
28
+ className={className}
29
+ {...props}
30
+ />
31
+ );
32
+ });
33
+
34
+ Input.displayName = 'Input';
35
+
36
+ export default Input;
@@ -0,0 +1,49 @@
1
+ .inputGroup {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.2rem;
5
+ }
6
+
7
+ .label {
8
+ font-size: 0.85rem;
9
+ font-weight: 700;
10
+ color: #000000;
11
+ }
12
+
13
+ .input {
14
+ width: 100%;
15
+ padding: 0.5rem 0.5rem;
16
+ background-color: #ffffff;
17
+ border: 1.5px solid #000000;
18
+ border-radius: 2px;
19
+ font-size: 0.85rem;
20
+ font-weight: 500;
21
+ color: #000000;
22
+ outline: none;
23
+ box-sizing: border-box;
24
+ font-family: inherit;
25
+ transition: box-shadow 0.2s;
26
+ }
27
+
28
+ .input::placeholder {
29
+ color: #000000;
30
+ font-weight: 500;
31
+ opacity: 1;
32
+ }
33
+
34
+ .input:focus {
35
+ box-shadow: 0 0 0 1px #000000;
36
+ }
37
+
38
+ .inputError {
39
+ border-color: #ff0000;
40
+ }
41
+
42
+ .errorText {
43
+ color: #ff0000;
44
+ font-size: 0.75rem;
45
+ margin-top: 0.1rem;
46
+ }
47
+ .required{
48
+ margin-left: 4px;
49
+ }
@@ -0,0 +1,37 @@
1
+ import Input from './index.jsx';
2
+
3
+ export default {
4
+ title: 'Components/Input',
5
+ component: Input,
6
+ };
7
+
8
+ export const Default = {
9
+ args: {
10
+ label: 'Nombre',
11
+ placeholder: 'Escribe tu nombre',
12
+ },
13
+ };
14
+
15
+ export const Required = {
16
+ args: {
17
+ label: 'Correo electrónico',
18
+ placeholder: 'correo@ejemplo.com',
19
+ required: true,
20
+ },
21
+ };
22
+
23
+ export const WithError = {
24
+ args: {
25
+ label: 'Teléfono',
26
+ placeholder: '555-555-5555',
27
+ error: 'El número de teléfono no es válido',
28
+ },
29
+ };
30
+
31
+ export const WithHelperText = {
32
+ args: {
33
+ label: 'Contraseña',
34
+ type: 'password',
35
+ helperText: 'Debe tener al menos 8 caracteres',
36
+ },
37
+ };
File without changes
@@ -0,0 +1,76 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import styles from './index.module.css';
3
+
4
+ const Loading = ({ text = "", phrases = [], size = 'medium', variant = 'default', className = '', color }) => {
5
+ const [currentText, setCurrentText] = useState(text);
6
+ const [index, setIndex] = useState(0);
7
+ const [fade, setFade] = useState(true);
8
+
9
+ useEffect(() => {
10
+ if (!phrases || phrases.length === 0) {
11
+ setCurrentText(text);
12
+ return;
13
+ }
14
+
15
+ setCurrentText(phrases[0]);
16
+
17
+ const interval = setInterval(() => {
18
+ setFade(false);
19
+
20
+ setTimeout(() => {
21
+ setIndex((prevIndex) => {
22
+ const nextIndex = (prevIndex + 1) % phrases.length;
23
+ setCurrentText(phrases[nextIndex]);
24
+ return nextIndex;
25
+ });
26
+ setFade(true);
27
+ }, 250);
28
+
29
+ }, 3500);
30
+
31
+ return () => clearInterval(interval);
32
+ }, [phrases, text]);
33
+
34
+ const renderLoader = () => {
35
+ switch (variant) {
36
+ case 'bars':
37
+ return <div className={styles.loaderBars}></div>;
38
+ case 'bounce':
39
+ return <div className={styles.loaderBounce}></div>;
40
+ case 'box':
41
+ return <div className={styles.loaderBox}></div>;
42
+ case 'default':
43
+ default:
44
+ return (
45
+ <div className={styles.spinnerWrapper}>
46
+ <svg className={styles.spinner} viewBox="0 0 50 50">
47
+ <circle
48
+ className={styles.spinnerCircle}
49
+ cx="25"
50
+ cy="25"
51
+ r="20"
52
+ fill="none"
53
+ strokeWidth="4"
54
+ />
55
+ </svg>
56
+ </div>
57
+ );
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div
63
+ className={`${styles.loadingContainer} ${styles[size]} ${className}`}
64
+ style={color ? { '--loading-color': color } : undefined}
65
+ >
66
+ {renderLoader()}
67
+ {currentText && (
68
+ <span className={`${styles.text} ${fade ? styles.fadeIn : styles.fadeOut}`}>
69
+ {currentText}
70
+ </span>
71
+ )}
72
+ </div>
73
+ );
74
+ };
75
+
76
+ export default Loading;
@@ -0,0 +1,193 @@
1
+ .loadingContainer {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ gap: 12px;
7
+ padding: 1.5rem;
8
+ width: 100%;
9
+ color: var(--text-color, #64748b);
10
+ border-radius: 8px;
11
+ background-color: rgba(106, 105, 105, 0);
12
+ }
13
+
14
+ /* ==========================================
15
+ 1. VERSIÓN POR DEFECTO (Tu original exacta)
16
+ ========================================== */
17
+ .spinnerWrapper {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ }
22
+
23
+ .spinner {
24
+ width: 24px;
25
+ height: 24px;
26
+ animation: spinnerRotate 1.8s linear infinite;
27
+ }
28
+
29
+ .spinnerCircle {
30
+ stroke: var(--loading-color, var(--btn-blue));
31
+ stroke-linecap: round;
32
+ animation: spinnerDash 1.5s ease-in-out infinite;
33
+ }
34
+
35
+ .small .spinner {
36
+ width: 16px;
37
+ height: 16px;
38
+ }
39
+
40
+ .medium .spinner {
41
+ width: 24px;
42
+ height: 24px;
43
+ }
44
+
45
+ .large .spinner {
46
+ width: 40px;
47
+ height: 40px;
48
+ }
49
+
50
+ .giant .spinner {
51
+ width: 64px;
52
+ height: 64px;
53
+ }
54
+
55
+ @keyframes spinnerRotate {
56
+ 100% {
57
+ transform: rotate(360deg);
58
+ }
59
+ }
60
+
61
+ @keyframes spinnerDash {
62
+ 0% {
63
+ stroke-dasharray: 1, 150;
64
+ stroke-dashoffset: 0;
65
+ }
66
+ 47% {
67
+ stroke-dasharray: 90, 150;
68
+ stroke-dashoffset: -35;
69
+ }
70
+ 95%,
71
+ 100% {
72
+ stroke-dasharray: 90, 150;
73
+ stroke-dashoffset: -124;
74
+ }
75
+ }
76
+
77
+
78
+ /* ==========================================
79
+ 2. VARIANTE: BARS
80
+ ========================================== */
81
+ .loaderBars {
82
+ width: 45px;
83
+ aspect-ratio: .75;
84
+ --c: no-repeat linear-gradient(var(--loading-color, var(--btn-blue, #000)) 0 0);
85
+ background:
86
+ var(--c) 0% 50%,
87
+ var(--c) 50% 50%,
88
+ var(--c) 100% 50%;
89
+ animation: l7 1s infinite linear alternate;
90
+ }
91
+
92
+ @keyframes l7 {
93
+ 0% {background-size: 20% 50% ,20% 50% ,20% 50% }
94
+ 20% {background-size: 20% 20% ,20% 50% ,20% 50% }
95
+ 40% {background-size: 20% 100%,20% 20% ,20% 50% }
96
+ 60% {background-size: 20% 50% ,20% 100%,20% 20% }
97
+ 80% {background-size: 20% 50% ,20% 50% ,20% 100%}
98
+ 100%{background-size: 20% 50% ,20% 50% ,20% 50% }
99
+ }
100
+
101
+
102
+ /* ==========================================
103
+ 3. VARIANTE: BOUNCE
104
+ ========================================== */
105
+ .loaderBounce {
106
+ width: 40px;
107
+ height: 30px;
108
+ --c: no-repeat linear-gradient(var(--loading-color, var(--btn-blue, #000)) 0 0);
109
+ background:
110
+ var(--c) 0 100%/8px 30px,
111
+ var(--c) 50% 100%/8px 20px,
112
+ var(--c) 100% 100%/8px 10px;
113
+ position: relative;
114
+ clip-path: inset(-100% 0);
115
+ }
116
+
117
+ .loaderBounce::before {
118
+ content: "";
119
+ position: absolute;
120
+ width: 8px;
121
+ height: 8px;
122
+ border-radius: 50%;
123
+ background: var(--loading-color, var(--btn-blue, #000));
124
+ left: -16px;
125
+ top: 0;
126
+ animation:
127
+ l5-1 2s linear infinite,
128
+ l5-2 0.5s cubic-bezier(0,200,.8,200) infinite;
129
+ }
130
+
131
+ @keyframes l5-1 {
132
+ 0% {left:-16px;transform:translateY(-8px)}
133
+ 100% {left:calc(100% + 8px);transform:translateY(22px)}
134
+ }
135
+
136
+ @keyframes l5-2 {
137
+ 100% {top:-0.1px}
138
+ }
139
+
140
+
141
+ /* ==========================================
142
+ 4. VARIANTE: BOX (Azul y Negro)
143
+ ========================================== */
144
+ .loaderBox {
145
+ width: 16px;
146
+ aspect-ratio: 1;
147
+ background: var(--loading-color, var(--btn-blue, #3FB8AF)); /* Azul */
148
+ position: relative;
149
+ animation: l8-0 2.5s infinite linear alternate;
150
+ }
151
+
152
+ .loaderBox::before {
153
+ content: "";
154
+ position: absolute;
155
+ inset: 0;
156
+ background: #000000; /* Negro */
157
+ transform: translate(100%);
158
+ transform-origin: top left;
159
+ animation: l8-1 .5s infinite alternate;
160
+ }
161
+
162
+ @keyframes l8-0 {
163
+ 0% ,19.9%,
164
+ 80%,100% {transform: scale(1,1)}
165
+ 20%,39.9% {transform: scale(-1,1)}
166
+ 40%,59.9% {transform: scale(-1,-1)}
167
+ 60%,79.9% {transform: scale(1,-1)}
168
+ }
169
+
170
+ @keyframes l8-1 {
171
+ 0%,20% {transform: translate(100%) rotate(0)}
172
+ 80%,100% {transform: translate(100%) rotate(-180deg)}
173
+ }
174
+
175
+
176
+ /* --- Animaciones de Texto --- */
177
+ .text {
178
+ font-size: 0.95rem;
179
+ font-weight: 500;
180
+ letter-spacing: 0.3px;
181
+ transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
182
+ text-align: center;
183
+ }
184
+
185
+ .fadeIn {
186
+ opacity: 1;
187
+ transform: translateY(0);
188
+ }
189
+
190
+ .fadeOut {
191
+ opacity: 0;
192
+ transform: translateY(-4px);
193
+ }
@@ -0,0 +1,38 @@
1
+ import Loading from './index';
2
+
3
+ export default {
4
+ title: 'Components/Loading',
5
+ component: Loading,
6
+ };
7
+
8
+ export const Default = {
9
+ args: {
10
+ text: 'Cargando...',
11
+ size: 'medium',
12
+ variant: 'default',
13
+ },
14
+ };
15
+
16
+ export const WithRotatingPhrases = {
17
+ args: {
18
+ phrases: ['Cargando datos...', 'Procesando información...', 'Casi listo...'],
19
+ size: 'medium',
20
+ variant: 'default',
21
+ },
22
+ };
23
+
24
+ export const BarsVariant = {
25
+ args: {
26
+ text: 'Un momento...',
27
+ size: 'large',
28
+ variant: 'bars',
29
+ },
30
+ };
31
+
32
+ export const BounceVariantSmall = {
33
+ args: {
34
+ text: 'Cargando',
35
+ size: 'small',
36
+ variant: 'bounce',
37
+ },
38
+ };
File without changes
@@ -0,0 +1,16 @@
1
+ import ReactMarkdown from 'react-markdown';
2
+ import remarkGfm from 'remark-gfm';
3
+ import styles from './index.module.css';
4
+
5
+ export const MarkdownContent = ({ children, className = '', style, components, linkColor }) => (
6
+ <div
7
+ className={`${styles.markdown} ${className}`}
8
+ style={{ ...(linkColor ? { '--markdown-link': linkColor } : {}), ...style }}
9
+ >
10
+ <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
11
+ {children ?? ''}
12
+ </ReactMarkdown>
13
+ </div>
14
+ );
15
+
16
+ export default MarkdownContent;