luna-components-library 1.1.27 → 1.1.28

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 CHANGED
@@ -56,6 +56,7 @@ function App() {
56
56
  variant="primary"
57
57
  size="lg"
58
58
  onClick={() => console.log('Clicked!')}
59
+ className="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200"
59
60
  >
60
61
  Click me
61
62
  </Button>
@@ -64,15 +65,19 @@ function App() {
64
65
  title="Example Card"
65
66
  padding="md"
66
67
  shadow="lg"
67
- className="max-w-md"
68
+ className="max-w-md bg-white border border-gray-200 rounded-lg shadow-lg"
68
69
  >
69
- <p>This is a card component from Luna Components Library.</p>
70
- <Button variant="outline" size="sm">
70
+ <p className="text-gray-700">This is a card component from Luna Components Library.</p>
71
+ <Button variant="outline" size="sm" className="mt-2 border border-gray-300 hover:border-gray-400">
71
72
  Learn More
72
73
  </Button>
73
74
  </Card>
74
75
 
75
- <Anchor href="https://example.com" variant="secondary">
76
+ <Anchor
77
+ href="https://example.com"
78
+ variant="secondary"
79
+ className="text-gray-600 hover:text-gray-800 underline transition-colors duration-200"
80
+ >
76
81
  Visit Example
77
82
  </Anchor>
78
83
 
@@ -80,14 +85,23 @@ function App() {
80
85
  key="demo"
81
86
  active={false}
82
87
  onClick={() => console.log('Toggle')}
83
- header={<h3>Click to expand</h3>}
84
- content={<p>This is the accordion content!</p>}
88
+ header={<h3 className="font-semibold text-gray-800">Click to expand</h3>}
89
+ content={<p className="text-gray-600">This is accordion content!</p>}
90
+ className="border border-gray-200 rounded-lg overflow-hidden"
85
91
  />
86
92
 
87
- <Spinner />
93
+ <Spinner
94
+ size="md"
95
+ type="circle"
96
+ className="text-blue-600"
97
+ />
88
98
 
89
99
  <DropDown
90
- toggle={<button>Select Option</button>}
100
+ toggle={
101
+ <button className="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded px-3 py-2 text-sm">
102
+ Select Option
103
+ </button>
104
+ }
91
105
  options={[
92
106
  { value: 'option1', label: 'Option 1' },
93
107
  { value: 'option2', label: 'Option 2' },
@@ -101,15 +115,16 @@ function App() {
101
115
  show={true}
102
116
  onHide={() => console.log('Modal closed')}
103
117
  title="Modal Title"
118
+ className="bg-white rounded-lg shadow-xl"
104
119
  >
105
- <p>This is a modal component from Luna Components Library.</p>
120
+ <p className="text-gray-700">This is a modal component from Luna Components Library.</p>
106
121
  </Modal>
107
122
 
108
123
  <ScrollTop
109
124
  threshold={200}
110
125
  position="bottom-right"
111
126
  size="md"
112
- className="bg-blue-600 hover:bg-blue-700"
127
+ className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
113
128
  />
114
129
  </div>
115
130
  );
@@ -129,7 +144,7 @@ A versatile button component with multiple variants and sizes.
129
144
  size="md"
130
145
  onClick={handleClick}
131
146
  disabled={false}
132
- className="custom-class"
147
+ className="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200"
133
148
  >
134
149
  Button Text
135
150
  </Button>
@@ -162,9 +177,9 @@ A flexible card component for displaying content with various padding and shadow
162
177
  title="Card Title"
163
178
  padding="md"
164
179
  shadow="lg"
165
- className="custom-card"
180
+ className="bg-white border border-gray-200 rounded-lg shadow-lg"
166
181
  >
167
- <p>Card content goes here</p>
182
+ <p className="text-gray-700">Card content goes here</p>
168
183
  </Card>
169
184
  ```
170
185
 
@@ -189,7 +204,7 @@ A styled link component that opens in a new tab with customizable variants and s
189
204
  href="https://example.com"
190
205
  variant="primary"
191
206
  size="sm"
192
- className="custom-anchor"
207
+ className="text-blue-600 hover:text-blue-800 underline transition-colors duration-200"
193
208
  >
194
209
  Link Text
195
210
  </Anchor>
@@ -216,8 +231,12 @@ A collapsible content component with customizable header and content sections.
216
231
  key="accordion-1"
217
232
  active={isActive}
218
233
  onClick={() => setIsActive(!isActive)}
219
- header={<h3>Accordion Title</h3>}
220
- content={<p>Accordion content goes here</p>}
234
+ header={<h3 className="font-semibold text-gray-800">Accordion Title</h3>}
235
+ content={<p className="text-gray-600">Accordion content goes here</p>}
236
+ className="border border-gray-200 rounded-lg overflow-hidden"
237
+ containerClassName="border border-gray-200 rounded-lg overflow-hidden"
238
+ headerClassName="w-full px-4 py-3 text-left bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition-colors duration-200 flex justify-between items-center"
239
+ contentClassName="transition-all duration-300 ease-in-out"
221
240
  />
222
241
  ```
223
242
 
@@ -227,22 +246,23 @@ A collapsible content component with customizable header and content sections.
227
246
  - `onClick: () => void` - Toggle function
228
247
  - `header: React.ReactNode` - Header content
229
248
  - `content: React.ReactNode` - Content to show when expanded
249
+ - `className?: string` - Additional CSS classes for accordion
250
+ - `containerClassName?: string` - CSS classes for accordion container element
251
+ - `headerClassName?: string` - CSS classes for accordion header element
252
+ - `contentClassName?: string` - CSS classes for accordion content element
230
253
 
231
254
  ### Spinner
232
255
  A loading spinner component with customizable types and animations.
233
256
 
234
257
  ```jsx
235
- <Spinner size="md" type="circle" className="custom-spinner" />
236
- ```
237
-
238
- **Props:**
239
- - `className?: string` - Additional CSS classes
240
- - `containerClassName?: string` - CSS classes for the container element
241
- - `dotClassName?: string` - CSS classes for dot elements
242
- - `barClassName?: string` - CSS classes for bar elements
243
- - `size?: SpinnerSize` - Spinner size (default: 'md')
244
- - `type?: SpinnerType` - Spinner animation type (default: 'circle')
245
-
258
+ <Spinner
259
+ size="md"
260
+ type="circle"
261
+ className="text-blue-600"
262
+ containerClassName="flex justify-center"
263
+ dotClassName="w-2 h-2 bg-blue-600 rounded-full"
264
+ barClassName="w-1 h-4 bg-blue-600 rounded-full"
265
+ />
246
266
  **Types:**
247
267
  ```typescript
248
268
  type SpinnerSize = 'sm' | 'md' | 'lg';
@@ -254,7 +274,11 @@ A dropdown menu component with customizable toggle and options.
254
274
 
255
275
  ```jsx
256
276
  <DropDown
257
- toggle={<button>Menu</button>}
277
+ toggle={
278
+ <button className="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded px-3 py-2 text-sm">
279
+ Menu
280
+ </button>
281
+ }
258
282
  options={[
259
283
  { value: 'option1', label: 'Option 1' },
260
284
  { value: 'option2', label: 'Option 2' },
@@ -262,6 +286,10 @@ A dropdown menu component with customizable toggle and options.
262
286
  ]}
263
287
  selected="option1"
264
288
  onChange={(value) => console.log('Selected:', value)}
289
+ className="relative inline-block text-left"
290
+ dropdownClassName="absolute top-full left-0 mt-1 w-full bg-white border border-gray-300 rounded shadow-lg z-10"
291
+ optionsContainerClassName="py-1"
292
+ optionClassName="block px-3 py-2 hover:bg-gray-100 cursor-pointer text-sm"
265
293
  />
266
294
  ```
267
295
 
@@ -270,6 +298,11 @@ A dropdown menu component with customizable toggle and options.
270
298
  - `options: DropDownOption[]` - Array of option objects with `value` and `label` properties
271
299
  - `selected: string | number` - Currently selected option value
272
300
  - `onChange: (value: string | number) => void` - Selection change handler
301
+ - `className?: string` - Additional CSS classes for container
302
+ - `containerClassName?: string` - CSS classes for dropdown container element
303
+ - `dropdownClassName?: string` - CSS classes for dropdown menu element
304
+ - `optionsContainerClassName?: string` - CSS classes for options container element
305
+ - `optionClassName?: string` - CSS classes for individual option elements
273
306
 
274
307
  **DropDownOption Interface:**
275
308
  ```typescript
@@ -288,6 +321,8 @@ A progress bar component with customizable progress values and accessibility.
288
321
  max={100}
289
322
  min={0}
290
323
  aria-label="Loading progress"
324
+ className="bg-gray-200 rounded-full h-2"
325
+ barClassName="bg-blue-600 h-full rounded-full transition-all duration-300"
291
326
  />
292
327
  ```
293
328
 
@@ -314,10 +349,12 @@ A fullscreen overlay preloader component with customizable spinner and auto-hide
314
349
  <Preloader
315
350
  isLoading={isLoading}
316
351
  duration={2000}
317
- backgroundColor="#1a1a1a"
352
+ backgroundColor="rgba(0,0,0,0.8)"
318
353
  accentColor="#00ff88"
319
354
  size={90}
320
355
  borderWidth={6}
356
+ className="fixed inset-0 z-50"
357
+ spinnerClassName="border-4 border-gray-300 border-t-green-400"
321
358
  onComplete={() => setIsLoading(false)}
322
359
  />
323
360
  ```
@@ -365,7 +402,7 @@ A floating scroll-to-top button that appears when the user scrolls down the page
365
402
  threshold={200}
366
403
  position="bottom-right"
367
404
  size="md"
368
- className="bg-blue-600 hover:bg-blue-700"
405
+ className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
369
406
  />
370
407
  ```
371
408
 
@@ -397,6 +434,8 @@ If you are using this library in a project that also uses Bootstrap (or another
397
434
  - `onVisibilityChange?: (isVisible: boolean) => void` - Callback when visibility changes
398
435
  - `targetElement?: string` - Element ID or selector to check visibility for showing the button
399
436
  - `scrollPercentage?: number` - Percentage of page scroll to show the button (0-100)
437
+ - `buttonClassName?: string` - CSS classes for the button element
438
+ - `containerClassName?: string` - CSS classes for the container element
400
439
 
401
440
  **Position Options:**
402
441
  - `bottom-right` - Fixed bottom right
@@ -474,7 +513,9 @@ A typing animation component that types and deletes text in sequence.
474
513
  typeSpeed={50}
475
514
  backSpeed={30}
476
515
  loop={true}
477
- className="typed-text"
516
+ className="text-blue-600 font-mono text-lg"
517
+ containerClassName="inline-block"
518
+ typedClassName="border-r-2 border-blue-600"
478
519
  />
479
520
  ```
480
521
 
@@ -509,7 +550,7 @@ A WhatsApp button component for quick contact integration.
509
550
  message="Hello! I need help."
510
551
  position="bottom-right"
511
552
  size="md"
512
- className="custom-whatsapp"
553
+ className="bg-green-500 hover:bg-green-600 text-white rounded-full shadow-lg"
513
554
  />
514
555
  ```
515
556
 
@@ -542,14 +583,19 @@ A flexible modal component for displaying dialogs, forms, and overlays.
542
583
  title="Modal Title"
543
584
  size="lg"
544
585
  centered
586
+ className="bg-white rounded-lg shadow-xl"
587
+ contentClassName="p-6"
588
+ headerClassName="border-b border-gray-200 px-6 py-4"
545
589
  >
546
- <p>Modal content goes here.</p>
547
- <Modal.Footer>
548
- <Button variant="secondary" onClick={() => setShowModal(false)}>
590
+ <p className="text-gray-700">Modal content goes here.</p>
591
+ <div className="mt-4 flex gap-2">
592
+ <Button variant="secondary" onClick={() => setShowModal(false)} className="border-gray-300">
549
593
  Close
550
594
  </Button>
551
- <Button onClick={handleSave}>Save Changes</Button>
552
- </Modal.Footer>
595
+ <Button onClick={handleSave} className="bg-blue-600 hover:bg-blue-700">
596
+ Save Changes
597
+ </Button>
598
+ </div>
553
599
  </Modal>
554
600
  ```
555
601
 
@@ -656,24 +702,28 @@ const MyComponent = () => {
656
702
  value={formData.name}
657
703
  onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
658
704
  placeholder="Name"
659
- className="w-full p-2 border rounded mb-2"
705
+ className="w-full p-2 border border-gray-300 rounded-lg mb-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
660
706
  />
661
707
  <input
662
708
  value={formData.email}
663
709
  onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
664
710
  placeholder="Email"
665
- className="w-full p-2 border rounded mb-2"
711
+ className="w-full p-2 border border-gray-300 rounded-lg mb-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
666
712
  />
667
713
  <textarea
668
714
  value={formData.message}
669
715
  onChange={(e) => setFormData(prev => ({ ...prev, message: e.target.value }))}
670
716
  placeholder="Message"
671
- className="w-full p-2 border rounded mb-2"
717
+ className="w-full p-2 border border-gray-300 rounded-lg mb-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
672
718
  rows={3}
673
719
  />
674
720
  <div className="flex gap-2">
675
- <Button variant="secondary" onClick={() => setShowModal(false)}>Cancel</Button>
676
- <Button onClick={() => handleSubmit(formData)}>Save</Button>
721
+ <Button variant="secondary" onClick={() => setShowModal(false)} className="border-gray-300 hover:border-gray-400">
722
+ Cancel
723
+ </Button>
724
+ <Button onClick={() => handleSubmit(formData)} className="bg-blue-600 hover:bg-blue-700">
725
+ Save
726
+ </Button>
677
727
  </div>
678
728
  </form>
679
729
  </Modal>
@@ -1 +1 @@
1
- {"version":3,"file":"luna-components-library.js","names":[],"sources":["../node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/react/jsx-runtime.js","../src/components/Button.tsx","../src/components/Card.tsx","../src/components/Anchor.tsx","../src/components/Accordion.tsx","../src/components/Spinner.tsx","../src/components/DropDown.tsx","../src/components/ProgressBar.tsx","../src/components/Typed.tsx","../src/components/Preloader.tsx","../src/components/ScrollTop.tsx","../src/components/WhatsApp.tsx","../src/components/Modal.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","import React from 'react';\n\n// Button variants and sizes\ntype ButtonVariant = 'primary' | 'secondary' | 'outline';\ntype ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps {\n children: React.ReactNode;\n variant?: ButtonVariant;\n size?: ButtonSize;\n onClick?: () => void;\n disabled?: boolean;\n className?: string;\n containerClassName?: string;\n variantClassName?: string;\n sizeClassName?: string;\n}\n\n{/* onCLick default should open window.open('https://andreychaconresumereact.netlify.app/', '_blank') */ }\n\nconst Button = ({\n children,\n variant = 'primary',\n size = 'sm',\n onClick = () =>\n void 0,\n disabled = false,\n className = '',\n containerClassName = 'font-medium rounded-lg transition-colors focus:outline-none focus:ring-2',\n variantClassName = 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',\n sizeClassName = 'px-3 py-1.5 text-sm'\n}: ButtonProps) => {\n const baseClasses = containerClassName;\n\n const variantClasses = {\n primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',\n secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500',\n outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500',\n };\n\n const sizeClasses = {\n sm: 'px-3 py-1.5 text-sm',\n md: 'px-4 py-2 text-base',\n lg: 'px-6 py-3 text-lg',\n };\n\n const classes = `\n ${baseClasses}\n ${variantClasses[variant]}\n ${sizeClasses[size]}\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${className}\n `.trim();\n\n return (\n <button\n className={classes}\n onClick={onClick}\n disabled={disabled}\n >\n {children}\n </button>\n );\n};\n\nexport default Button;\n","import React from 'react';\n\n// Card padding and shadow variants\ntype CardPadding = 'none' | 'sm' | 'md' | 'lg';\ntype CardShadow = 'none' | 'sm' | 'md' | 'lg';\n\nexport interface CardProps {\n children: React.ReactNode;\n title?: string;\n className?: string;\n containerClassName?: string;\n titleClassName?: string;\n padding?: CardPadding;\n shadow?: CardShadow;\n}\n\nconst Card = ({\n children,\n title,\n className = '',\n containerClassName = 'bg-white rounded-lg border border-gray-200',\n titleClassName = 'text-lg font-semibold text-gray-900',\n padding = 'md',\n shadow = 'md',\n}: CardProps) => {\n const paddingClasses = {\n none: '',\n sm: 'p-3',\n md: 'p-4',\n lg: 'p-6',\n };\n\n const shadowClasses = {\n none: '',\n sm: 'shadow-sm',\n md: 'shadow-md',\n lg: 'shadow-lg',\n };\n\n const classes = `\n ${containerClassName}\n ${paddingClasses[padding]}\n ${shadowClasses[shadow]}\n ${className}\n `.trim();\n\n return (\n <div className={classes}>\n {title && (\n <div className=\"mb-4\">\n <h3 className={titleClassName}>{title}</h3>\n </div>\n )}\n {children}\n </div>\n );\n};\n\nexport default Card;\n","import React from 'react';\r\n\r\n// Anchor link variants and sizes\r\ntype AnchorVariant = 'none' | 'primary' | 'secondary' | 'outline';\r\ntype AnchorSize = 'sm' | 'md' | 'lg';\r\n\r\nexport interface AnchorProps {\r\n children?: React.ReactNode;\r\n variant?: AnchorVariant;\r\n size?: AnchorSize;\r\n href?: string;\r\n className?: string;\r\n containerClassName?: string;\r\n variantClassName?: string;\r\n sizeClassName?: string;\r\n target?: string;\r\n rel?: string;\r\n}\r\n\r\nconst Anchor = ({\r\n children = \"Pablo Andrey Chacon Luna\",\r\n variant = 'none',\r\n size = 'sm',\r\n href = 'https://andreychaconresumereact.netlify.app/',\r\n className,\r\n containerClassName = 'font-medium rounded-lg transition-colors focus:outline-none focus:ring-2',\r\n variantClassName = 'bg-blue-600 text-white hover:bg-blue-700',\r\n sizeClassName = 'px-3 py-1.5 text-sm',\r\n target = '_blank',\r\n rel = 'noopener noreferrer'\r\n}: AnchorProps) => {\r\n\r\n const baseClasses = containerClassName;\r\n\r\n const variantClasses = {\r\n none: '',\r\n primary: 'bg-blue-600 text-white hover:bg-blue-700',\r\n secondary: 'bg-gray-600 text-white hover:bg-gray-700',\r\n outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50',\r\n };\r\n\r\n const sizeClasses = {\r\n sm: 'px-3 py-1.5 text-sm',\r\n md: 'px-4 py-2 text-base',\r\n lg: 'px-6 py-3 text-lg',\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${variantClasses[variant]}\r\n ${sizeClasses[size]}\r\n ${variantClassName}\r\n ${sizeClassName}\r\n ${className}\r\n `.trim();\r\n\r\n return (\r\n <a href={href} target={target} rel={rel} className={classes}>\r\n {children}\r\n </a>\r\n );\r\n};\r\n\r\nexport default Anchor;","\r\nimport React from 'react';\r\n\r\n// Accordion component for collapsible content\r\ninterface AccordionProps {\r\n active: boolean;\r\n onClick: () => void;\r\n header: React.ReactNode;\r\n content: React.ReactNode;\r\n className?: string;\r\n containerClassName?: string;\r\n headerClassName?: string;\r\n contentClassName?: string;\r\n}\r\n\r\nconst Accordion = ({ active, onClick, header, content, className = '', containerClassName = 'border border-gray-200 rounded-lg overflow-hidden', headerClassName = 'w-full px-4 py-3 text-left bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition-colors duration-200 flex justify-between items-center', contentClassName = 'transition-all duration-300 ease-in-out' }: AccordionProps) => {\r\n return (\r\n <div className={`${containerClassName} ${className}`}>\r\n <button\r\n onClick={onClick}\r\n className={headerClassName}\r\n aria-expanded={active}\r\n >\r\n {header}\r\n <svg\r\n className={`w-5 h-5 text-gray-500 transition-transform duration-200 ${active ? 'transform rotate-180' : ''\r\n }`}\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M19 9l-7 7-7-7\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div\r\n className={`${contentClassName} ${active ? 'max-h-96 opacity-100' : 'max-h-0 opacity-0'\r\n } overflow-hidden`}\r\n >\r\n <div className={`p-4 bg-white border-t border-gray-200 ${contentClassName}`}>\r\n {content}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default Accordion;","import React from 'react';\n\ntype SpinnerSize = 'sm' | 'md' | 'lg';\ntype SpinnerType = 'circle' | 'dots' | 'pulse' | 'bars';\n\nexport interface SpinnerProps {\n className?: string;\n containerClassName?: string;\n dotClassName?: string;\n barClassName?: string;\n size?: SpinnerSize;\n type?: SpinnerType;\n};\n\nconst Spinner = ({\n className,\n containerClassName = 'flex gap-1',\n dotClassName = 'bg-blue-600 rounded-full animate-bounce',\n barClassName = 'bg-blue-600 animate-pulse',\n size = 'md',\n type = 'circle'\n}: SpinnerProps) => {\n const sizeClasses = {\n sm: 'w-4 h-4',\n md: 'w-6 h-6',\n lg: 'w-8 h-8'\n };\n\n const dotSizeClasses = {\n sm: 'w-1 h-1',\n md: 'w-2 h-2',\n lg: 'w-3 h-3'\n };\n\n const barSizeClasses = {\n sm: 'w-1 h-4',\n md: 'w-1 h-6',\n lg: 'w-1 h-8'\n };\n\n if (type === 'dots') {\n return (\n <div role=\"status\" className={`${containerClassName} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '0ms' }}></div>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '150ms' }}></div>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '300ms' }}></div>\n </div>\n );\n }\n\n if (type === 'pulse') {\n return (\n <div role=\"status\" className={`${sizeClasses[size]} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${sizeClasses[size]} ${dotClassName}`}></div>\n </div>\n );\n }\n\n if (type === 'bars') {\n return (\n <div role=\"status\" className={`flex gap-1 items-center ${containerClassName} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '0ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '200ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '400ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '600ms' }}></div>\n </div>\n );\n }\n\n // Default circle spinner\n return (\n <div\n role=\"status\"\n className={`inline-block animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className || ''}`}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n};\n\nexport default Spinner;\n","{/* Dropdown component for selecting options */ }\r\nimport React, { useState } from 'react';\r\n\r\ntype DropDownOption = {\r\n value: string;\r\n label: React.ReactNode;\r\n};\r\n\r\ntype DropDownProps = {\r\n toggle: React.ReactNode;\r\n options: React.ReactNode[] | DropDownOption[];\r\n selected: React.ReactNode;\r\n onChange: (value: React.ReactNode) => void;\r\n className?: string;\r\n containerClassName?: string;\r\n dropdownClassName?: string;\r\n optionsContainerClassName?: string;\r\n optionClassName?: string;\r\n};\r\n\r\nconst DropDown = ({\r\n toggle,\r\n options,\r\n selected,\r\n onChange,\r\n className = '',\r\n containerClassName = 'relative inline-block text-left',\r\n dropdownClassName = 'absolute z-50 mt-2 w-48 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none',\r\n optionsContainerClassName = 'py-1 flex flex-col',\r\n optionClassName = 'block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:text-gray-900'\r\n}: DropDownProps) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const handleToggle = () => {\r\n setIsOpen(!isOpen);\r\n };\r\n\r\n const handleOptionClick = (option: React.ReactNode) => {\r\n onChange(option);\r\n setIsOpen(false);\r\n };\r\n\r\n return (\r\n <div className={`${containerClassName} ${className}`}>\r\n <div onClick={handleToggle} className=\"cursor-pointer\">\r\n {toggle}\r\n </div>\r\n\r\n {isOpen && (\r\n <div className={dropdownClassName}>\r\n <div className={optionsContainerClassName}>\r\n {options.map((option, index) => {\r\n const isOptionObject = typeof option === 'object' && option !== null && 'value' in option;\r\n const optionValue = isOptionObject ? (option as DropDownOption).value : option;\r\n const optionLabel = isOptionObject ? (option as DropDownOption).label : option;\r\n\r\n return (\r\n <button\r\n key={index}\r\n onClick={() => handleOptionClick(optionValue)}\r\n className={optionClassName}\r\n >\r\n {optionLabel}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default DropDown;","import React from 'react';\r\n\r\n// Progress bar color variants\r\ntype ProgressBarVariant = 'primary' | 'success' | 'warning' | 'danger' | 'dark' | 'light';\r\n\r\n// Core progress bar props\r\ninterface ProgressBarProps {\r\n progress: number;\r\n max: number;\r\n min: number;\r\n 'aria-label': string;\r\n}\r\n\r\n// Extended props with styling options\r\ntype ProgressBarPropsWithClassName = ProgressBarProps & {\r\n className?: React.CSSProperties;\r\n style?: React.CSSProperties;\r\n containerClassName?: string;\r\n barClassName?: string;\r\n variant?: ProgressBarVariant;\r\n};\r\n\r\nconst ProgressBar = ({ progress, max, min, 'aria-label': ariaLabel, className, style, containerClassName = 'w-full bg-gray-200 rounded-full h-4 overflow-hidden', barClassName = 'h-full rounded-full transition-all duration-300 flex items-center justify-center text-xs font-medium', variant = 'primary' }: ProgressBarPropsWithClassName) => {\r\n const variantClasses = {\r\n primary: {\r\n bg: 'bg-blue-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n success: {\r\n bg: 'bg-green-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n warning: {\r\n bg: 'bg-yellow-500',\r\n text: 'text-gray-900',\r\n containerBg: 'bg-gray-200'\r\n },\r\n danger: {\r\n bg: 'bg-red-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n dark: {\r\n bg: 'bg-gray-800',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-300'\r\n },\r\n light: {\r\n bg: 'bg-gray-100',\r\n text: 'text-gray-900',\r\n containerBg: 'bg-gray-300'\r\n }\r\n };\r\n\r\n const currentVariant = variantClasses[variant];\r\n const barClasses = `${currentVariant.bg} ${barClassName} ${currentVariant.text}`;\r\n\r\n return (\r\n <div className={containerClassName}>\r\n <div\r\n role=\"progressbar\"\r\n className={barClasses}\r\n aria-valuenow={progress}\r\n aria-valuemin={min}\r\n aria-valuemax={max}\r\n style={{ width: `${progress}%`, ...className, ...style }}\r\n >\r\n {progress > 10 && `${progress}%`}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ProgressBar;","import React, { useState, useEffect, CSSProperties } from 'react';\r\n\r\n// Typing animation configuration\r\ntype TypedStyle = CSSProperties & {\r\n animation?: string;\r\n animationDelay?: string;\r\n};\r\n\r\ntype TypedProps = {\r\n strings: string[];\r\n typeSpeed?: number;\r\n backSpeed?: number;\r\n backDelay?: number;\r\n startDelay?: number;\r\n loop?: boolean;\r\n showCursor?: boolean;\r\n className?: string;\r\n containerClassName?: string;\r\n typedClassName?: string;\r\n cursorClassName?: string;\r\n style?: TypedStyle;\r\n};\r\n\r\nconst Typed = ({\r\n strings,\r\n typeSpeed = 50,\r\n backSpeed = 30,\r\n backDelay = 500,\r\n startDelay = 0,\r\n loop = true,\r\n showCursor = true,\r\n className = '',\r\n containerClassName = 'inline-block',\r\n typedClassName = 'typed',\r\n cursorClassName = 'typed-cursor ml-1 inline-block w-0.5 h-5 bg-current',\r\n style = {},\r\n}: TypedProps) => {\r\n const [currentStringIndex, setCurrentStringIndex] = useState(0);\r\n const [currentText, setCurrentText] = useState('');\r\n const [isDeleting, setIsDeleting] = useState(false);\r\n const [isPaused, setIsPaused] = useState(false);\r\n const [cursorOpacity, setCursorOpacity] = useState(1);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setIsPaused(false);\r\n }, startDelay);\r\n\r\n return () => clearTimeout(timer);\r\n }, [startDelay]);\r\n\r\n useEffect(() => {\r\n if (isPaused) return;\r\n\r\n const currentString = strings[currentStringIndex] || '';\r\n\r\n const timer = setTimeout(() => {\r\n if (!isDeleting) {\r\n // Typing\r\n if (currentText.length < currentString.length) {\r\n setCurrentText(currentText + currentString[currentText.length]);\r\n } else {\r\n // Finished typing, wait before deleting\r\n if (loop) {\r\n setIsPaused(true);\r\n setTimeout(() => {\r\n setIsPaused(false);\r\n setIsDeleting(true);\r\n }, backDelay);\r\n }\r\n }\r\n } else {\r\n // Deleting\r\n if (currentText.length > 0) {\r\n setCurrentText(currentText.slice(0, -1));\r\n } else {\r\n // Finished deleting, move to next string\r\n setIsDeleting(false);\r\n setCurrentStringIndex((prevIndex) =>\r\n prevIndex === strings.length - 1 ? 0 : prevIndex + 1\r\n );\r\n }\r\n }\r\n }, isDeleting ? backSpeed : typeSpeed);\r\n\r\n return () => clearTimeout(timer);\r\n }, [currentText, isDeleting, currentStringIndex, strings, typeSpeed, backSpeed, backDelay, loop, isPaused]);\r\n\r\n // Cursor fade effect\r\n useEffect(() => {\r\n const fadeTimer = setInterval(() => {\r\n setCursorOpacity(prev => {\r\n if (prev === 1) return 0;\r\n return 1;\r\n });\r\n }, 750);\r\n\r\n return () => clearInterval(fadeTimer);\r\n }, []);\r\n\r\n return (\r\n <span className={`${containerClassName} ${className}`} >\r\n <span className={typedClassName}>{currentText}</span>\r\n {showCursor && (\r\n <span\r\n className={cursorClassName}\r\n aria-hidden=\"true\"\r\n style={{\r\n ...style,\r\n opacity: cursorOpacity\r\n }}\r\n >\r\n\r\n </span>\r\n )}\r\n </span>\r\n );\r\n};\r\n\r\nexport default Typed;","import React, { useEffect, useState } from 'react';\n\nexport interface PreloaderProps {\n /** Loading state - if true, preloader is shown */\n isLoading?: boolean;\n /** Duration in milliseconds before auto-hide */\n duration?: number;\n /** Background color overlay */\n backgroundColor?: string;\n /** Accent color for the spinner */\n accentColor?: string;\n /** Size of the spinner in pixels */\n size?: number;\n /** Border width of the spinner */\n borderWidth?: number;\n /** Custom className for the preloader */\n className?: string;\n /** Custom className for the spinner */\n spinnerClassName?: string;\n /** Custom z-index */\n zIndex?: number;\n /** Callback when preloader finishes */\n onComplete?: () => void;\n}\n\nconst Preloader = ({\n isLoading: externalLoading,\n duration = 1000,\n backgroundColor,\n accentColor,\n size = 90,\n borderWidth = 6,\n className = '',\n spinnerClassName = '',\n zIndex = 999999,\n onComplete\n}: PreloaderProps) => {\n const [internalLoading, setInternalLoading] = useState(true);\n\n // Use external loading state if provided, otherwise use internal state\n const isLoading = externalLoading !== undefined ? externalLoading : internalLoading;\n\n useEffect(() => {\n // Only auto-hide if we're using internal loading state\n if (externalLoading === undefined) {\n const timer = setTimeout(() => {\n setInternalLoading(false);\n onComplete?.();\n }, duration);\n\n return () => clearTimeout(timer);\n }\n }, [duration, externalLoading, onComplete]);\n\n // Handle external loading state changes - auto-hide when externalLoading is true\n useEffect(() => {\n if (externalLoading === true) {\n const timer = setTimeout(() => {\n onComplete?.();\n }, duration);\n\n return () => clearTimeout(timer);\n }\n }, [externalLoading, duration, onComplete]);\n\n const preloaderStyle: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n zIndex,\n overflow: 'hidden',\n background: backgroundColor || 'var(--background-color, #00000018)',\n transition: 'all 0.6s ease-out',\n display: isLoading ? 'block' : 'none'\n };\n\n const spinnerStyle: React.CSSProperties = {\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n border: `${borderWidth}px solid #ffffff`,\n borderColor: `${accentColor || 'var(--accent-color, #007bff)'} transparent transparent transparent`,\n borderRadius: '50%',\n width: `${size}px`,\n height: `${size}px`,\n animation: 'animate-preloader 1.5s linear infinite'\n };\n\n return (\n <>\n <div\n className={`preloader-overlay ${className}`}\n style={preloaderStyle}\n >\n <div\n className={`preloader-spinner ${spinnerClassName}`}\n style={spinnerStyle}\n />\n </div>\n\n {/* Global styles for animation */}\n <style>{`\n @keyframes animate-preloader {\n 0% {\n transform: translate(-50%, -50%) rotate(0deg);\n }\n 100% {\n transform: translate(-50%, -50%) rotate(360deg);\n }\n }\n `}</style>\n </>\n );\n};\n\nexport default Preloader;\n","import React, { useEffect, useState, useRef } from 'react';\r\n\r\nexport interface ScrollTopProps {\r\n /** Scroll position threshold to show the button (in pixels) */\r\n threshold?: number;\r\n /** Custom className for the button */\r\n className?: string;\r\n /** Custom icon/content for the button */\r\n children?: React.ReactNode;\r\n /** Position of the button */\r\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';\r\n /** Size of the button */\r\n size?: 'sm' | 'md' | 'lg';\r\n /** Shape of the button */\r\n shape?: 'circle' | 'square' | 'rounded';\r\n /** Whether to show the button initially */\r\n showInitially?: boolean;\r\n /** Custom scroll behavior */\r\n scrollBehavior?: 'auto' | 'smooth';\r\n /** Custom styles */\r\n style?: React.CSSProperties;\r\n /** Callback when button is clicked */\r\n onClick?: () => void;\r\n /** Callback when visibility changes */\r\n onVisibilityChange?: (isVisible: boolean) => void;\r\n /** Element ID or selector to check visibility for showing the button */\r\n targetElement?: string;\r\n /** Percentage of page scroll to show the button (0-100) */\r\n scrollPercentage?: number;\r\n}\r\n\r\nconst ScrollTop = ({\r\n threshold = 100,\r\n className = '',\r\n children,\r\n position = 'bottom-right',\r\n size = 'md',\r\n shape = 'circle',\r\n showInitially = false,\r\n scrollBehavior = 'smooth',\r\n style,\r\n onClick,\r\n onVisibilityChange,\r\n targetElement,\r\n scrollPercentage\r\n}: ScrollTopProps) => {\r\n const [isVisible, setIsVisible] = useState(showInitially);\r\n\r\n useEffect(() => {\r\n // Show/hide scroll to top button based on scroll position\r\n const toggleVisibility = () => {\r\n let shouldBeVisible = false;\r\n\r\n // Check scroll percentage first\r\n if (scrollPercentage !== undefined) {\r\n const maxScroll = document.documentElement.scrollHeight - window.innerHeight;\r\n const currentScroll = window.scrollY;\r\n const percentage = (currentScroll / maxScroll) * 100;\r\n shouldBeVisible = percentage >= scrollPercentage;\r\n }\r\n // Check target element visibility\r\n else if (targetElement) {\r\n const element = document.querySelector(targetElement);\r\n if (element) {\r\n const rect = element.getBoundingClientRect();\r\n const isInViewport = rect.top < window.innerHeight && rect.bottom > 0;\r\n shouldBeVisible = isInViewport; // Show when element is visible\r\n } else {\r\n // If element doesn't exist, fall back to threshold behavior\r\n shouldBeVisible = window.scrollY > threshold;\r\n }\r\n }\r\n // Default threshold behavior\r\n else {\r\n shouldBeVisible = window.scrollY > threshold;\r\n }\r\n\r\n // Set visibility immediately\r\n setIsVisible(shouldBeVisible);\r\n onVisibilityChange?.(shouldBeVisible);\r\n };\r\n\r\n window.addEventListener('scroll', toggleVisibility, { passive: true });\r\n // Initial check\r\n toggleVisibility();\r\n\r\n return () => {\r\n window.removeEventListener('scroll', toggleVisibility);\r\n };\r\n }, [threshold, onVisibilityChange, targetElement, scrollPercentage]);\r\n\r\n const scrollToTop = () => {\r\n window.scrollTo({\r\n top: 0,\r\n behavior: scrollBehavior\r\n });\r\n onClick?.();\r\n };\r\n\r\n const handleClick = (e: React.MouseEvent) => {\r\n e.preventDefault();\r\n scrollToTop();\r\n };\r\n\r\n // Position classes\r\n const positionClasses = {\r\n 'bottom-right': 'fixed bottom-8 right-8',\r\n 'bottom-left': 'fixed bottom-8 left-8',\r\n 'bottom-center': 'fixed bottom-8 left-1/2 transform -translate-x-1/2',\r\n 'top-right': 'fixed top-8 right-8',\r\n 'top-left': 'fixed top-8 left-8',\r\n 'top-center': 'fixed top-8 left-1/2 transform -translate-x-1/2'\r\n };\r\n\r\n // Size classes\r\n const sizeClasses = {\r\n sm: 'w-8 h-8 text-sm',\r\n md: 'w-12 h-12 text-base',\r\n lg: 'w-16 h-16 text-lg'\r\n };\r\n\r\n // Shape classes\r\n const shapeClasses = {\r\n circle: 'rounded-full',\r\n square: 'rounded-none',\r\n rounded: 'rounded-lg'\r\n };\r\n\r\n const buttonClasses = `\r\n ${positionClasses[position]}\r\n ${sizeClasses[size]}\r\n ${shapeClasses[shape]}\r\n ${className}\r\n flex items-center justify-center\r\n bg-blue-600 hover:bg-blue-700\r\n text-white\r\n shadow-lg hover:shadow-xl\r\n transition-all duration-300 ease-in-out\r\n cursor-pointer\r\n z-50\r\n ${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4 pointer-events-none'}\r\n `;\r\n\r\n const defaultContent = (\r\n <svg\r\n className=\"w-4 h-4\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M5 10l7-7m0 0l7 7m-7-7v18\"\r\n />\r\n </svg>\r\n );\r\n\r\n return (\r\n <button\r\n className={buttonClasses}\r\n onClick={handleClick}\r\n style={style}\r\n aria-label=\"Scroll to top\"\r\n title=\"Scroll to top\"\r\n >\r\n {children || defaultContent}\r\n </button>\r\n );\r\n};\r\n\r\nexport default ScrollTop;\r\n","import React, { useState, useEffect } from 'react';\n\nexport interface WhatsAppProps {\n /** Phone number for WhatsApp (with country code, without + or spaces) */\n phone?: string;\n /** Default message to send */\n message?: string;\n /** Position of the button */\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';\n /** Size of the button */\n size?: 'sm' | 'md' | 'lg';\n /** Show tooltip on hover */\n showTooltip?: boolean;\n /** Tooltip text */\n tooltipText?: string;\n /** Custom className for the button */\n className?: string;\n /** Custom className for the tooltip */\n tooltipClassName?: string;\n /** Custom styles */\n style?: React.CSSProperties;\n /** Callback when button is clicked */\n onClick?: () => void;\n /** Z-index for the button */\n zIndex?: number;\n /** Whether to open in new tab */\n openInNewTab?: boolean;\n}\n\nconst WhatsApp = ({\n phone = '',\n message = '¡Hola! Me gustaría obtener más información.',\n position = 'bottom-right',\n size = 'md',\n showTooltip = true,\n tooltipText = '¿En qué podemos ayudarte?',\n className = '',\n tooltipClassName = '',\n style,\n onClick,\n zIndex = 50,\n openInNewTab = true\n}: WhatsAppProps) => {\n const [isHovered, setIsHovered] = useState(false);\n\n // Don't render if no phone number provided\n if (!phone) return null;\n\n const handleWhatsAppClick = () => {\n const cleanPhone = phone.replace(/[^\\d]/g, '');\n const encodedMessage = encodeURIComponent(message);\n const whatsappUrl = `https://wa.me/${cleanPhone}?text=${encodedMessage}`;\n\n if (openInNewTab) {\n window.open(whatsappUrl, '_blank');\n } else {\n window.location.href = whatsappUrl;\n }\n\n onClick?.();\n };\n\n // Position classes\n const positionClasses = {\n 'bottom-right': 'bottom-6 right-6',\n 'bottom-left': 'bottom-6 left-6',\n 'bottom-center': 'bottom-6 left-1/2 transform -translate-x-1/2',\n 'top-right': 'top-6 right-6',\n 'top-left': 'top-6 left-6',\n 'top-center': 'top-6 left-1/2 transform -translate-x-1/2'\n };\n\n // Size classes\n const sizeClasses = {\n sm: 'w-10 h-10',\n md: 'w-14 h-14',\n lg: 'w-16 h-16'\n };\n\n // Icon size based on button size\n const iconSizes = {\n sm: 20,\n md: 32,\n lg: 40\n };\n\n const buttonClasses = `\n fixed ${positionClasses[position]}\n ${sizeClasses[size]}\n bg-[#25D366] hover:bg-[#128C7E]\n text-white rounded-full shadow-2xl\n flex items-center justify-center\n transition-all duration-300 hover:scale-110\n z-${zIndex}\n group\n ${className}\n `;\n\n return (\n <>\n <button\n className={buttonClasses}\n onClick={handleWhatsAppClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={style}\n aria-label=\"Chatear por WhatsApp\"\n title=\"Chatear por WhatsApp\"\n >\n <svg\n width={iconSizes[size]}\n height={iconSizes[size]}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\" />\n </svg>\n </button>\n\n {showTooltip && (\n <div\n className={`\n fixed ${positionClasses[position].replace('6', '20').replace('bottom-6', 'bottom-20').replace('top-6', 'top-20')}\n bg-white text-gray-800 px-3 py-1 rounded-md text-sm font-semibold\n shadow-md whitespace-nowrap pointer-events-none\n transition-opacity duration-300\n ${isHovered ? 'opacity-100' : 'opacity-0'}\n ${position.includes('right') ? 'right-20' : position.includes('left') ? 'left-20' : 'left-1/2 transform -translate-x-1/2'}\n ${tooltipClassName}\n `}\n style={{\n [position.includes('bottom') ? 'bottom' : 'top']: position.includes('bottom') ? '5.5rem' : '5.5rem'\n }}\n >\n {tooltipText}\n </div>\n )}\n </>\n );\n};\n\nexport default WhatsApp;\n","import React, { useEffect, useRef } from 'react';\n\n// Modal size variants\ntype ModalSize = 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface ModalProps {\n /** Whether the modal is visible */\n show: boolean;\n /** Callback when modal is closed */\n onHide: () => void;\n /** Modal size variant */\n size?: ModalSize;\n /** Whether to center the modal vertically */\n centered?: boolean;\n /** Whether to show backdrop overlay */\n backdrop?: boolean | 'static';\n /** Whether to close modal when backdrop is clicked */\n backdropClose?: boolean;\n /** Whether to close modal when ESC key is pressed */\n keyboard?: boolean;\n /** Whether to show modal with animation */\n animation?: boolean;\n /** Custom className for the modal */\n className?: string;\n /** Custom className for the modal dialog */\n dialogClassName?: string;\n /** Custom className for the modal content */\n contentClassName?: string;\n /** Custom className for the modal header */\n headerClassName?: string;\n /** Custom className for the modal body */\n bodyClassName?: string;\n /** Custom className for the modal footer */\n footerClassName?: string;\n /** Modal title */\n title?: React.ReactNode;\n /** Modal header content */\n header?: React.ReactNode;\n /** Modal body content */\n children: React.ReactNode;\n /** Modal footer content */\n footer?: React.ReactNode;\n /** Whether to show close button in header */\n closeButton?: boolean;\n}\n\nconst Modal = ({\n show,\n onHide,\n size = 'md',\n centered = false,\n backdrop = true,\n backdropClose = true,\n keyboard = true,\n animation = true,\n className = '',\n dialogClassName = '',\n contentClassName = '',\n headerClassName = '',\n bodyClassName = '',\n footerClassName = '',\n title,\n header,\n children,\n footer,\n closeButton = true\n}: ModalProps) => {\n const modalRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Handle ESC key press\n useEffect(() => {\n if (!show || !keyboard) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onHide();\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [show, keyboard, onHide]);\n\n // Handle backdrop click\n const handleBackdropClick = (event: React.MouseEvent) => {\n if (backdropClose) {\n // Check if click is on backdrop using data attribute\n const target = event.target as HTMLElement;\n if (target.getAttribute('data-backdrop') === 'true' || target.closest('[data-backdrop=\"true\"]')) {\n onHide();\n }\n }\n };\n\n // Focus management\n useEffect(() => {\n if (show) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n // Focus the modal dialog\n if (modalRef.current) {\n modalRef.current.focus();\n }\n // Prevent body scroll\n document.body.style.overflow = 'hidden';\n } else {\n // Restore focus and body scroll\n if (previousActiveElement.current) {\n previousActiveElement.current.focus();\n }\n document.body.style.overflow = '';\n }\n\n return () => {\n document.body.style.overflow = '';\n };\n }, [show]);\n\n // Size classes\n const sizeClasses = {\n sm: 'max-w-sm',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl'\n };\n\n const modalClasses = `\n fixed inset-0 z-60 flex items-center justify-center\n ${show ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}\n ${animation ? 'transition-opacity duration-300' : ''}\n ${className}\n `.trim();\n\n const dialogClasses = `\n relative w-full ${sizeClasses[size]} mx-auto\n ${centered ? 'flex items-center justify-center min-h-screen' : 'mt-8'}\n ${dialogClassName}\n `.trim();\n\n if (!show) return null;\n\n return (\n <div\n ref={modalRef}\n className={modalClasses}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n >\n {/* Backdrop */}\n {backdrop && (\n <div\n data-backdrop=\"true\"\n className={`absolute inset-0 bg-black bg-opacity-50 ${animation ? 'transition-opacity duration-300' : ''} ${show ? 'opacity-100' : 'opacity-0'}`}\n onClick={handleBackdropClick}\n />\n )}\n\n {/* Modal Content */}\n <div className={dialogClasses}>\n <div className={`bg-white rounded-lg shadow-xl relative z-10 ${contentClassName}`}>\n {/* Modal Header */}\n {(header || title || closeButton) && (\n <div className={`flex items-center justify-between p-4 border-b border-gray-200 ${headerClassName}`}>\n {header || (title && (\n <h3 className=\"text-lg font-semibold text-gray-900\" id=\"modal-title\">\n {title}\n </h3>\n ))}\n {closeButton && (\n <button\n type=\"button\"\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n onClick={onHide}\n aria-label=\"Close\"\n >\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Modal Body */}\n <div className={`p-4 ${bodyClassName}`}>\n {children}\n </div>\n\n {/* Modal Footer */}\n {footer && (\n <div className={`flex items-center justify-end p-4 border-t border-gray-200 space-x-2 ${footerClassName}`}>\n {footer}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Modal;\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"luna-components-library.js","names":[],"sources":["../node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/react/jsx-runtime.js","../src/components/Button.tsx","../src/components/Card.tsx","../src/components/Anchor.tsx","../src/components/Accordion.tsx","../src/components/Spinner.tsx","../src/components/DropDown.tsx","../src/components/ProgressBar.tsx","../src/components/Typed.tsx","../src/components/Preloader.tsx","../src/components/ScrollTop.tsx","../src/components/WhatsApp.tsx","../src/components/Modal.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","import React from 'react';\n\n// Button variants and sizes\ntype ButtonVariant = 'primary' | 'secondary' | 'outline';\ntype ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps {\n children: React.ReactNode;\n variant?: ButtonVariant;\n size?: ButtonSize;\n onClick?: () => void;\n disabled?: boolean;\n className?: string;\n containerClassName?: string;\n variantClassName?: string;\n sizeClassName?: string;\n}\n\n{/* onCLick default should open window.open('https://andreychaconresumereact.netlify.app/', '_blank') */ }\n\nconst Button = ({\n children,\n variant = 'primary',\n size = 'sm',\n onClick = () =>\n void 0,\n disabled = false,\n className = '',\n containerClassName = 'font-medium rounded-lg transition-colors focus:outline-none focus:ring-2',\n variantClassName = 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',\n sizeClassName = 'px-3 py-1.5 text-sm'\n}: ButtonProps) => {\n const baseClasses = containerClassName;\n\n const variantClasses = {\n primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',\n secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500',\n outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500',\n };\n\n const sizeClasses = {\n sm: 'px-3 py-1.5 text-sm',\n md: 'px-4 py-2 text-base',\n lg: 'px-6 py-3 text-lg',\n };\n\n const classes = `\n ${baseClasses}\n ${variantClasses[variant]}\n ${sizeClasses[size]}\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${className}\n `.trim();\n\n return (\n <button\n className={classes}\n onClick={onClick}\n disabled={disabled}\n >\n {children}\n </button>\n );\n};\n\nexport default Button;\n","import React from 'react';\n\n// Card padding and shadow variants\ntype CardPadding = 'none' | 'sm' | 'md' | 'lg';\ntype CardShadow = 'none' | 'sm' | 'md' | 'lg';\n\nexport interface CardProps {\n children: React.ReactNode;\n title?: string;\n className?: string;\n containerClassName?: string;\n titleClassName?: string;\n padding?: CardPadding;\n shadow?: CardShadow;\n}\n\nconst Card = ({\n children,\n title,\n className = '',\n containerClassName = 'bg-white rounded-lg border border-gray-200',\n titleClassName = 'text-lg font-semibold text-gray-900',\n padding = 'md',\n shadow = 'md',\n}: CardProps) => {\n const paddingClasses = {\n none: '',\n sm: 'p-3',\n md: 'p-4',\n lg: 'p-6',\n };\n\n const shadowClasses = {\n none: '',\n sm: 'shadow-sm',\n md: 'shadow-md',\n lg: 'shadow-lg',\n };\n\n const classes = `\n ${containerClassName}\n ${paddingClasses[padding]}\n ${shadowClasses[shadow]}\n ${className}\n `.trim();\n\n return (\n <div className={classes}>\n {title && (\n <div className=\"mb-4\">\n <h3 className={titleClassName}>{title}</h3>\n </div>\n )}\n {children}\n </div>\n );\n};\n\nexport default Card;\n","import React from 'react';\r\n\r\n// Anchor link variants and sizes\r\ntype AnchorVariant = 'none' | 'primary' | 'secondary' | 'outline';\r\ntype AnchorSize = 'sm' | 'md' | 'lg';\r\n\r\nexport interface AnchorProps {\r\n children?: React.ReactNode;\r\n variant?: AnchorVariant;\r\n size?: AnchorSize;\r\n href?: string;\r\n className?: string;\r\n containerClassName?: string;\r\n variantClassName?: string;\r\n sizeClassName?: string;\r\n target?: string;\r\n rel?: string;\r\n}\r\n\r\nconst Anchor = ({\r\n children = \"Pablo Andrey Chacon Luna\",\r\n variant = 'none',\r\n size = 'sm',\r\n href = 'https://andreychaconresumereact.netlify.app/',\r\n className,\r\n containerClassName = 'font-medium rounded-lg transition-colors focus:outline-none focus:ring-2',\r\n variantClassName = 'bg-blue-600 text-white hover:bg-blue-700',\r\n sizeClassName = 'px-3 py-1.5 text-sm',\r\n target = '_blank',\r\n rel = 'noopener noreferrer'\r\n}: AnchorProps) => {\r\n\r\n const baseClasses = containerClassName;\r\n\r\n const variantClasses = {\r\n none: '',\r\n primary: 'bg-blue-600 text-white hover:bg-blue-700',\r\n secondary: 'bg-gray-600 text-white hover:bg-gray-700',\r\n outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50',\r\n };\r\n\r\n const sizeClasses = {\r\n sm: 'px-3 py-1.5 text-sm',\r\n md: 'px-4 py-2 text-base',\r\n lg: 'px-6 py-3 text-lg',\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${variantClasses[variant]}\r\n ${sizeClasses[size]}\r\n ${variantClassName}\r\n ${sizeClassName}\r\n ${className}\r\n `.trim();\r\n\r\n return (\r\n <a href={href} target={target} rel={rel} className={classes}>\r\n {children}\r\n </a>\r\n );\r\n};\r\n\r\nexport default Anchor;","\r\nimport React from 'react';\r\n\r\n// Accordion component for collapsible content\r\ninterface AccordionProps {\r\n active: boolean;\r\n onClick: () => void;\r\n header: React.ReactNode;\r\n content: React.ReactNode;\r\n className?: string;\r\n containerClassName?: string;\r\n headerClassName?: string;\r\n contentClassName?: string;\r\n}\r\n\r\nconst Accordion = ({ active,\r\n onClick,\r\n header,\r\n content,\r\n className = '',\r\n containerClassName = 'border border-gray-200 rounded-lg overflow-hidden',\r\n headerClassName = 'w-full px-4 py-3 text-left bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition-colors duration-200 flex justify-between items-center',\r\n contentClassName = 'transition-all duration-300 ease-in-out'\r\n}: AccordionProps) => {\r\n return (\r\n <div className={`${containerClassName} ${className}`}>\r\n <button\r\n onClick={onClick}\r\n className={headerClassName}\r\n aria-expanded={active}\r\n >\r\n {header}\r\n <svg\r\n className={`w-5 h-5 text-gray-500 transition-transform duration-200 ${active ? 'transform rotate-180' : ''\r\n }`}\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M19 9l-7 7-7-7\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div\r\n className={`${contentClassName} ${active ? 'max-h-96 opacity-100' : 'max-h-0 opacity-0'\r\n } overflow-hidden`}\r\n >\r\n <div className={`p-4 bg-white border-t border-gray-200 ${contentClassName}`}>\r\n {content}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default Accordion;","import React from 'react';\n\ntype SpinnerSize = 'sm' | 'md' | 'lg';\ntype SpinnerType = 'circle' | 'dots' | 'pulse' | 'bars';\n\nexport interface SpinnerProps {\n className?: string;\n containerClassName?: string;\n dotClassName?: string;\n barClassName?: string;\n size?: SpinnerSize;\n type?: SpinnerType;\n};\n\nconst Spinner = ({\n className,\n containerClassName = 'flex gap-1',\n dotClassName = 'bg-blue-600 rounded-full animate-bounce',\n barClassName = 'bg-blue-600 animate-pulse',\n size = 'md',\n type = 'circle'\n}: SpinnerProps) => {\n const sizeClasses = {\n sm: 'w-4 h-4',\n md: 'w-6 h-6',\n lg: 'w-8 h-8'\n };\n\n const dotSizeClasses = {\n sm: 'w-1 h-1',\n md: 'w-2 h-2',\n lg: 'w-3 h-3'\n };\n\n const barSizeClasses = {\n sm: 'w-1 h-4',\n md: 'w-1 h-6',\n lg: 'w-1 h-8'\n };\n\n if (type === 'dots') {\n return (\n <div role=\"status\" className={`${containerClassName} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '0ms' }}></div>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '150ms' }}></div>\n <div className={`${dotSizeClasses[size]} ${dotClassName}`} style={{ animationDelay: '300ms' }}></div>\n </div>\n );\n }\n\n if (type === 'pulse') {\n return (\n <div role=\"status\" className={`${sizeClasses[size]} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${sizeClasses[size]} ${dotClassName}`}></div>\n </div>\n );\n }\n\n if (type === 'bars') {\n return (\n <div role=\"status\" className={`flex gap-1 items-center ${containerClassName} ${className || ''}`}>\n <span className=\"sr-only\">Loading...</span>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '0ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '200ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '400ms' }}></div>\n <div className={`${barSizeClasses[size]} ${barClassName}`} style={{ animationDelay: '600ms' }}></div>\n </div>\n );\n }\n\n // Default circle spinner\n return (\n <div\n role=\"status\"\n className={`inline-block animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className || ''}`}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n};\n\nexport default Spinner;\n","{/* Dropdown component for selecting options */ }\r\nimport React, { useState } from 'react';\r\n\r\ntype DropDownOption = {\r\n value: string;\r\n label: React.ReactNode;\r\n};\r\n\r\ntype DropDownProps = {\r\n toggle: React.ReactNode;\r\n options: React.ReactNode[] | DropDownOption[];\r\n selected: React.ReactNode;\r\n onChange: (value: React.ReactNode) => void;\r\n className?: string;\r\n containerClassName?: string;\r\n dropdownClassName?: string;\r\n optionsContainerClassName?: string;\r\n optionClassName?: string;\r\n};\r\n\r\nconst DropDown = ({\r\n toggle,\r\n options,\r\n selected,\r\n onChange,\r\n className = '',\r\n containerClassName = 'relative inline-block text-left',\r\n dropdownClassName = 'absolute z-50 mt-2 w-48 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none',\r\n optionsContainerClassName = 'py-1 flex flex-col',\r\n optionClassName = 'block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:text-gray-900'\r\n}: DropDownProps) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const handleToggle = () => {\r\n setIsOpen(!isOpen);\r\n };\r\n\r\n const handleOptionClick = (option: React.ReactNode) => {\r\n onChange(option);\r\n setIsOpen(false);\r\n };\r\n\r\n return (\r\n <div className={`${containerClassName} ${className}`}>\r\n <div onClick={handleToggle} className=\"cursor-pointer\">\r\n {toggle}\r\n </div>\r\n\r\n {isOpen && (\r\n <div className={dropdownClassName}>\r\n <div className={optionsContainerClassName}>\r\n {options.map((option, index) => {\r\n const isOptionObject = typeof option === 'object' && option !== null && 'value' in option;\r\n const optionValue = isOptionObject ? (option as DropDownOption).value : option;\r\n const optionLabel = isOptionObject ? (option as DropDownOption).label : option;\r\n\r\n return (\r\n <button\r\n key={index}\r\n onClick={() => handleOptionClick(optionValue)}\r\n className={optionClassName}\r\n >\r\n {optionLabel}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default DropDown;","import React from 'react';\r\n\r\n// Progress bar color variants\r\ntype ProgressBarVariant = 'primary' | 'success' | 'warning' | 'danger' | 'dark' | 'light';\r\n\r\n// Core progress bar props\r\ninterface ProgressBarProps {\r\n progress: number;\r\n max: number;\r\n min: number;\r\n 'aria-label': string;\r\n}\r\n\r\n// Extended props with styling options\r\ntype ProgressBarPropsWithClassName = ProgressBarProps & {\r\n className?: React.CSSProperties;\r\n style?: React.CSSProperties;\r\n containerClassName?: string;\r\n barClassName?: string;\r\n variant?: ProgressBarVariant;\r\n};\r\n\r\nconst ProgressBar = ({ progress, max, min, 'aria-label': ariaLabel, className, style, containerClassName = 'w-full bg-gray-200 rounded-full h-4 overflow-hidden', barClassName = 'h-full rounded-full transition-all duration-300 flex items-center justify-center text-xs font-medium', variant = 'primary' }: ProgressBarPropsWithClassName) => {\r\n const variantClasses = {\r\n primary: {\r\n bg: 'bg-blue-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n success: {\r\n bg: 'bg-green-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n warning: {\r\n bg: 'bg-yellow-500',\r\n text: 'text-gray-900',\r\n containerBg: 'bg-gray-200'\r\n },\r\n danger: {\r\n bg: 'bg-red-600',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-200'\r\n },\r\n dark: {\r\n bg: 'bg-gray-800',\r\n text: 'text-white',\r\n containerBg: 'bg-gray-300'\r\n },\r\n light: {\r\n bg: 'bg-gray-100',\r\n text: 'text-gray-900',\r\n containerBg: 'bg-gray-300'\r\n }\r\n };\r\n\r\n const currentVariant = variantClasses[variant];\r\n const barClasses = `${currentVariant.bg} ${barClassName} ${currentVariant.text}`;\r\n\r\n return (\r\n <div className={containerClassName}>\r\n <div\r\n role=\"progressbar\"\r\n className={barClasses}\r\n aria-valuenow={progress}\r\n aria-valuemin={min}\r\n aria-valuemax={max}\r\n style={{ width: `${progress}%`, ...className, ...style }}\r\n >\r\n {progress > 10 && `${progress}%`}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ProgressBar;","import React, { useState, useEffect, CSSProperties } from 'react';\r\n\r\n// Typing animation configuration\r\ntype TypedStyle = CSSProperties & {\r\n animation?: string;\r\n animationDelay?: string;\r\n};\r\n\r\ntype TypedProps = {\r\n strings: string[];\r\n typeSpeed?: number;\r\n backSpeed?: number;\r\n backDelay?: number;\r\n startDelay?: number;\r\n loop?: boolean;\r\n showCursor?: boolean;\r\n className?: string;\r\n containerClassName?: string;\r\n typedClassName?: string;\r\n cursorClassName?: string;\r\n style?: TypedStyle;\r\n};\r\n\r\nconst Typed = ({\r\n strings,\r\n typeSpeed = 50,\r\n backSpeed = 30,\r\n backDelay = 500,\r\n startDelay = 0,\r\n loop = true,\r\n showCursor = true,\r\n className = '',\r\n containerClassName = 'inline-block',\r\n typedClassName = 'typed',\r\n cursorClassName = 'typed-cursor ml-1 inline-block w-0.5 h-5 bg-current',\r\n style = {},\r\n}: TypedProps) => {\r\n const [currentStringIndex, setCurrentStringIndex] = useState(0);\r\n const [currentText, setCurrentText] = useState('');\r\n const [isDeleting, setIsDeleting] = useState(false);\r\n const [isPaused, setIsPaused] = useState(false);\r\n const [cursorOpacity, setCursorOpacity] = useState(1);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setIsPaused(false);\r\n }, startDelay);\r\n\r\n return () => clearTimeout(timer);\r\n }, [startDelay]);\r\n\r\n useEffect(() => {\r\n if (isPaused) return;\r\n\r\n const currentString = strings[currentStringIndex] || '';\r\n\r\n const timer = setTimeout(() => {\r\n if (!isDeleting) {\r\n // Typing\r\n if (currentText.length < currentString.length) {\r\n setCurrentText(currentText + currentString[currentText.length]);\r\n } else {\r\n // Finished typing, wait before deleting\r\n if (loop) {\r\n setIsPaused(true);\r\n setTimeout(() => {\r\n setIsPaused(false);\r\n setIsDeleting(true);\r\n }, backDelay);\r\n }\r\n }\r\n } else {\r\n // Deleting\r\n if (currentText.length > 0) {\r\n setCurrentText(currentText.slice(0, -1));\r\n } else {\r\n // Finished deleting, move to next string\r\n setIsDeleting(false);\r\n setCurrentStringIndex((prevIndex) =>\r\n prevIndex === strings.length - 1 ? 0 : prevIndex + 1\r\n );\r\n }\r\n }\r\n }, isDeleting ? backSpeed : typeSpeed);\r\n\r\n return () => clearTimeout(timer);\r\n }, [currentText, isDeleting, currentStringIndex, strings, typeSpeed, backSpeed, backDelay, loop, isPaused]);\r\n\r\n // Cursor fade effect\r\n useEffect(() => {\r\n const fadeTimer = setInterval(() => {\r\n setCursorOpacity(prev => {\r\n if (prev === 1) return 0;\r\n return 1;\r\n });\r\n }, 750);\r\n\r\n return () => clearInterval(fadeTimer);\r\n }, []);\r\n\r\n return (\r\n <span className={`${containerClassName} ${className}`} >\r\n <span className={typedClassName}>{currentText}</span>\r\n {showCursor && (\r\n <span\r\n className={cursorClassName}\r\n aria-hidden=\"true\"\r\n style={{\r\n ...style,\r\n opacity: cursorOpacity\r\n }}\r\n >\r\n\r\n </span>\r\n )}\r\n </span>\r\n );\r\n};\r\n\r\nexport default Typed;","import React, { useEffect, useState } from 'react';\n\nexport interface PreloaderProps {\n /** Loading state - if true, preloader is shown */\n isLoading?: boolean;\n /** Duration in milliseconds before auto-hide */\n duration?: number;\n /** Background color overlay */\n backgroundColor?: string;\n /** Accent color for the spinner */\n accentColor?: string;\n /** Size of the spinner in pixels */\n size?: number;\n /** Border width of the spinner */\n borderWidth?: number;\n /** Custom className for the preloader */\n className?: string;\n /** Custom className for the spinner */\n spinnerClassName?: string;\n /** Custom z-index */\n zIndex?: number;\n /** Callback when preloader finishes */\n onComplete?: () => void;\n}\n\nconst Preloader = ({\n isLoading: externalLoading,\n duration = 1000,\n backgroundColor,\n accentColor,\n size = 90,\n borderWidth = 6,\n className = '',\n spinnerClassName = '',\n zIndex = 999999,\n onComplete\n}: PreloaderProps) => {\n const [internalLoading, setInternalLoading] = useState(true);\n\n // Use external loading state if provided, otherwise use internal state\n const isLoading = externalLoading !== undefined ? externalLoading : internalLoading;\n\n useEffect(() => {\n // Only auto-hide if we're using internal loading state\n if (externalLoading === undefined) {\n const timer = setTimeout(() => {\n setInternalLoading(false);\n onComplete?.();\n }, duration);\n\n return () => clearTimeout(timer);\n }\n }, [duration, externalLoading, onComplete]);\n\n // Handle external loading state changes - auto-hide when externalLoading is true\n useEffect(() => {\n if (externalLoading === true) {\n const timer = setTimeout(() => {\n onComplete?.();\n }, duration);\n\n return () => clearTimeout(timer);\n }\n }, [externalLoading, duration, onComplete]);\n\n const preloaderStyle: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n zIndex,\n overflow: 'hidden',\n background: backgroundColor || 'var(--background-color, #00000018)',\n transition: 'all 0.6s ease-out',\n display: isLoading ? 'block' : 'none'\n };\n\n const spinnerStyle: React.CSSProperties = {\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n border: `${borderWidth}px solid #ffffff`,\n borderColor: `${accentColor || 'var(--accent-color, #007bff)'} transparent transparent transparent`,\n borderRadius: '50%',\n width: `${size}px`,\n height: `${size}px`,\n animation: 'animate-preloader 1.5s linear infinite'\n };\n\n return (\n <>\n <div\n className={`preloader-overlay ${className}`}\n style={preloaderStyle}\n >\n <div\n className={`preloader-spinner ${spinnerClassName}`}\n style={spinnerStyle}\n />\n </div>\n\n {/* Global styles for animation */}\n <style>{`\n @keyframes animate-preloader {\n 0% {\n transform: translate(-50%, -50%) rotate(0deg);\n }\n 100% {\n transform: translate(-50%, -50%) rotate(360deg);\n }\n }\n `}</style>\n </>\n );\n};\n\nexport default Preloader;\n","import React, { useEffect, useState, useRef } from 'react';\r\n\r\nexport interface ScrollTopProps {\r\n /** Scroll position threshold to show the button (in pixels) */\r\n threshold?: number;\r\n /** Custom className for the button */\r\n className?: string;\r\n /** Custom icon/content for the button */\r\n children?: React.ReactNode;\r\n /** Position of the button */\r\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';\r\n /** Size of the button */\r\n size?: 'sm' | 'md' | 'lg';\r\n /** Shape of the button */\r\n shape?: 'circle' | 'square' | 'rounded';\r\n /** Whether to show the button initially */\r\n showInitially?: boolean;\r\n /** Custom scroll behavior */\r\n scrollBehavior?: 'auto' | 'smooth';\r\n /** Custom styles */\r\n style?: React.CSSProperties;\r\n /** Callback when button is clicked */\r\n onClick?: () => void;\r\n /** Callback when visibility changes */\r\n onVisibilityChange?: (isVisible: boolean) => void;\r\n /** Element ID or selector to check visibility for showing the button */\r\n targetElement?: string;\r\n /** Percentage of page scroll to show the button (0-100) */\r\n scrollPercentage?: number;\r\n}\r\n\r\nconst ScrollTop = ({\r\n threshold = 100,\r\n className = '',\r\n children,\r\n position = 'bottom-right',\r\n size = 'md',\r\n shape = 'circle',\r\n showInitially = false,\r\n scrollBehavior = 'smooth',\r\n style,\r\n onClick,\r\n onVisibilityChange,\r\n targetElement,\r\n scrollPercentage\r\n}: ScrollTopProps) => {\r\n const [isVisible, setIsVisible] = useState(showInitially);\r\n\r\n useEffect(() => {\r\n // Show/hide scroll to top button based on scroll position\r\n const toggleVisibility = () => {\r\n let shouldBeVisible = false;\r\n\r\n // Check scroll percentage first\r\n if (scrollPercentage !== undefined) {\r\n const maxScroll = document.documentElement.scrollHeight - window.innerHeight;\r\n const currentScroll = window.scrollY;\r\n const percentage = (currentScroll / maxScroll) * 100;\r\n shouldBeVisible = percentage >= scrollPercentage;\r\n }\r\n // Check target element visibility\r\n else if (targetElement) {\r\n const element = document.querySelector(targetElement);\r\n if (element) {\r\n const rect = element.getBoundingClientRect();\r\n const isInViewport = rect.top < window.innerHeight && rect.bottom > 0;\r\n shouldBeVisible = isInViewport; // Show when element is visible\r\n } else {\r\n // If element doesn't exist, fall back to threshold behavior\r\n shouldBeVisible = window.scrollY > threshold;\r\n }\r\n }\r\n // Default threshold behavior\r\n else {\r\n shouldBeVisible = window.scrollY > threshold;\r\n }\r\n\r\n // Set visibility immediately\r\n setIsVisible(shouldBeVisible);\r\n onVisibilityChange?.(shouldBeVisible);\r\n };\r\n\r\n window.addEventListener('scroll', toggleVisibility, { passive: true });\r\n // Initial check\r\n toggleVisibility();\r\n\r\n return () => {\r\n window.removeEventListener('scroll', toggleVisibility);\r\n };\r\n }, [threshold, onVisibilityChange, targetElement, scrollPercentage]);\r\n\r\n const scrollToTop = () => {\r\n window.scrollTo({\r\n top: 0,\r\n behavior: scrollBehavior\r\n });\r\n onClick?.();\r\n };\r\n\r\n const handleClick = (e: React.MouseEvent) => {\r\n e.preventDefault();\r\n scrollToTop();\r\n };\r\n\r\n // Position classes\r\n const positionClasses = {\r\n 'bottom-right': 'fixed bottom-8 right-8',\r\n 'bottom-left': 'fixed bottom-8 left-8',\r\n 'bottom-center': 'fixed bottom-8 left-1/2 transform -translate-x-1/2',\r\n 'top-right': 'fixed top-8 right-8',\r\n 'top-left': 'fixed top-8 left-8',\r\n 'top-center': 'fixed top-8 left-1/2 transform -translate-x-1/2'\r\n };\r\n\r\n // Size classes\r\n const sizeClasses = {\r\n sm: 'w-8 h-8 text-sm',\r\n md: 'w-12 h-12 text-base',\r\n lg: 'w-16 h-16 text-lg'\r\n };\r\n\r\n // Shape classes\r\n const shapeClasses = {\r\n circle: 'rounded-full',\r\n square: 'rounded-none',\r\n rounded: 'rounded-lg'\r\n };\r\n\r\n const buttonClasses = `\r\n ${positionClasses[position]}\r\n ${sizeClasses[size]}\r\n ${shapeClasses[shape]}\r\n ${className}\r\n flex items-center justify-center\r\n bg-blue-600 hover:bg-blue-700\r\n text-white\r\n shadow-lg hover:shadow-xl\r\n transition-all duration-300 ease-in-out\r\n cursor-pointer\r\n z-50\r\n ${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4 pointer-events-none'}\r\n `;\r\n\r\n const defaultContent = (\r\n <svg\r\n className=\"w-4 h-4\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M5 10l7-7m0 0l7 7m-7-7v18\"\r\n />\r\n </svg>\r\n );\r\n\r\n return (\r\n <button\r\n className={buttonClasses}\r\n onClick={handleClick}\r\n style={style}\r\n aria-label=\"Scroll to top\"\r\n title=\"Scroll to top\"\r\n >\r\n {children || defaultContent}\r\n </button>\r\n );\r\n};\r\n\r\nexport default ScrollTop;\r\n","import React, { useState, useEffect } from 'react';\n\nexport interface WhatsAppProps {\n /** Phone number for WhatsApp (with country code, without + or spaces) */\n phone?: string;\n /** Default message to send */\n message?: string;\n /** Position of the button */\n position?: 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';\n /** Size of the button */\n size?: 'sm' | 'md' | 'lg';\n /** Show tooltip on hover */\n showTooltip?: boolean;\n /** Tooltip text */\n tooltipText?: string;\n /** Custom className for the button */\n className?: string;\n /** Custom className for the tooltip */\n tooltipClassName?: string;\n /** Custom styles */\n style?: React.CSSProperties;\n /** Callback when button is clicked */\n onClick?: () => void;\n /** Z-index for the button */\n zIndex?: number;\n /** Whether to open in new tab */\n openInNewTab?: boolean;\n}\n\nconst WhatsApp = ({\n phone = '',\n message = '¡Hola! Me gustaría obtener más información.',\n position = 'bottom-right',\n size = 'md',\n showTooltip = true,\n tooltipText = '¿En qué podemos ayudarte?',\n className = '',\n tooltipClassName = '',\n style,\n onClick,\n zIndex = 50,\n openInNewTab = true\n}: WhatsAppProps) => {\n const [isHovered, setIsHovered] = useState(false);\n\n // Don't render if no phone number provided\n if (!phone) return null;\n\n const handleWhatsAppClick = () => {\n const cleanPhone = phone.replace(/[^\\d]/g, '');\n const encodedMessage = encodeURIComponent(message);\n const whatsappUrl = `https://wa.me/${cleanPhone}?text=${encodedMessage}`;\n\n if (openInNewTab) {\n window.open(whatsappUrl, '_blank');\n } else {\n window.location.href = whatsappUrl;\n }\n\n onClick?.();\n };\n\n // Position classes\n const positionClasses = {\n 'bottom-right': 'bottom-6 right-6',\n 'bottom-left': 'bottom-6 left-6',\n 'bottom-center': 'bottom-6 left-1/2 transform -translate-x-1/2',\n 'top-right': 'top-6 right-6',\n 'top-left': 'top-6 left-6',\n 'top-center': 'top-6 left-1/2 transform -translate-x-1/2'\n };\n\n // Size classes\n const sizeClasses = {\n sm: 'w-10 h-10',\n md: 'w-14 h-14',\n lg: 'w-16 h-16'\n };\n\n // Icon size based on button size\n const iconSizes = {\n sm: 20,\n md: 32,\n lg: 40\n };\n\n const buttonClasses = `\n fixed ${positionClasses[position]}\n ${sizeClasses[size]}\n bg-[#25D366] hover:bg-[#128C7E]\n text-white rounded-full shadow-2xl\n flex items-center justify-center\n transition-all duration-300 hover:scale-110\n z-${zIndex}\n group\n ${className}\n `;\n\n return (\n <>\n <button\n className={buttonClasses}\n onClick={handleWhatsAppClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={style}\n aria-label=\"Chatear por WhatsApp\"\n title=\"Chatear por WhatsApp\"\n >\n <svg\n width={iconSizes[size]}\n height={iconSizes[size]}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\" />\n </svg>\n </button>\n\n {showTooltip && (\n <div\n className={`\n fixed ${positionClasses[position].replace('6', '20').replace('bottom-6', 'bottom-20').replace('top-6', 'top-20')}\n bg-white text-gray-800 px-3 py-1 rounded-md text-sm font-semibold\n shadow-md whitespace-nowrap pointer-events-none\n transition-opacity duration-300\n ${isHovered ? 'opacity-100' : 'opacity-0'}\n ${position.includes('right') ? 'right-20' : position.includes('left') ? 'left-20' : 'left-1/2 transform -translate-x-1/2'}\n ${tooltipClassName}\n `}\n style={{\n [position.includes('bottom') ? 'bottom' : 'top']: position.includes('bottom') ? '5.5rem' : '5.5rem'\n }}\n >\n {tooltipText}\n </div>\n )}\n </>\n );\n};\n\nexport default WhatsApp;\n","import React, { useEffect, useRef } from 'react';\n\n// Modal size variants\ntype ModalSize = 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface ModalProps {\n /** Whether the modal is visible */\n show: boolean;\n /** Callback when modal is closed */\n onHide: () => void;\n /** Modal size variant */\n size?: ModalSize;\n /** Whether to center the modal vertically */\n centered?: boolean;\n /** Whether to show backdrop overlay */\n backdrop?: boolean | 'static';\n /** Whether to close modal when backdrop is clicked */\n backdropClose?: boolean;\n /** Whether to close modal when ESC key is pressed */\n keyboard?: boolean;\n /** Whether to show modal with animation */\n animation?: boolean;\n /** Custom className for the modal */\n className?: string;\n /** Custom className for the modal dialog */\n dialogClassName?: string;\n /** Custom className for the modal content */\n contentClassName?: string;\n /** Custom className for the modal header */\n headerClassName?: string;\n /** Custom className for the modal body */\n bodyClassName?: string;\n /** Custom className for the modal footer */\n footerClassName?: string;\n /** Modal title */\n title?: React.ReactNode;\n /** Modal header content */\n header?: React.ReactNode;\n /** Modal body content */\n children: React.ReactNode;\n /** Modal footer content */\n footer?: React.ReactNode;\n /** Whether to show close button in header */\n closeButton?: boolean;\n}\n\nconst Modal = ({\n show,\n onHide,\n size = 'md',\n centered = false,\n backdrop = true,\n backdropClose = true,\n keyboard = true,\n animation = true,\n className = '',\n dialogClassName = '',\n contentClassName = '',\n headerClassName = '',\n bodyClassName = '',\n footerClassName = '',\n title,\n header,\n children,\n footer,\n closeButton = true\n}: ModalProps) => {\n const modalRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Handle ESC key press\n useEffect(() => {\n if (!show || !keyboard) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onHide();\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [show, keyboard, onHide]);\n\n // Handle backdrop click\n const handleBackdropClick = (event: React.MouseEvent) => {\n if (backdropClose) {\n // Check if click is on backdrop using data attribute\n const target = event.target as HTMLElement;\n if (target.getAttribute('data-backdrop') === 'true' || target.closest('[data-backdrop=\"true\"]')) {\n onHide();\n }\n }\n };\n\n // Focus management\n useEffect(() => {\n if (show) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n // Focus the modal dialog\n if (modalRef.current) {\n modalRef.current.focus();\n }\n // Prevent body scroll\n document.body.style.overflow = 'hidden';\n } else {\n // Restore focus and body scroll\n if (previousActiveElement.current) {\n previousActiveElement.current.focus();\n }\n document.body.style.overflow = '';\n }\n\n return () => {\n document.body.style.overflow = '';\n };\n }, [show]);\n\n // Size classes\n const sizeClasses = {\n sm: 'max-w-sm',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl'\n };\n\n const modalClasses = `\n fixed inset-0 z-60 flex items-center justify-center\n ${show ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}\n ${animation ? 'transition-opacity duration-300' : ''}\n ${className}\n `.trim();\n\n const dialogClasses = `\n relative w-full ${sizeClasses[size]} mx-auto\n ${centered ? 'flex items-center justify-center min-h-screen' : 'mt-8'}\n ${dialogClassName}\n `.trim();\n\n if (!show) return null;\n\n return (\n <div\n ref={modalRef}\n className={modalClasses}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n >\n {/* Backdrop */}\n {backdrop && (\n <div\n data-backdrop=\"true\"\n className={`absolute inset-0 bg-black bg-opacity-50 ${animation ? 'transition-opacity duration-300' : ''} ${show ? 'opacity-100' : 'opacity-0'}`}\n onClick={handleBackdropClick}\n />\n )}\n\n {/* Modal Content */}\n <div className={dialogClasses}>\n <div className={`bg-white rounded-lg shadow-xl relative z-10 ${contentClassName}`}>\n {/* Modal Header */}\n {(header || title || closeButton) && (\n <div className={`flex items-center justify-between p-4 border-b border-gray-200 ${headerClassName}`}>\n {header || (title && (\n <h3 className=\"text-lg font-semibold text-gray-900\" id=\"modal-title\">\n {title}\n </h3>\n ))}\n {closeButton && (\n <button\n type=\"button\"\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n onClick={onHide}\n aria-label=\"Close\"\n >\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Modal Body */}\n <div className={`p-4 ${bodyClassName}`}>\n {children}\n </div>\n\n {/* Modal Footer */}\n {footer && (\n <div className={`flex items-center justify-end p-4 border-t border-gray-200 space-x-2 ${footerClassName}`}>\n {footer}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Modal;\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luna-components-library",
3
- "version": "1.1.27",
3
+ "version": "1.1.28",
4
4
  "description": "A React component library with TypeScript support",
5
5
  "main": "dist/luna-components-library.js",
6
6
  "module": "dist/luna-components-library.js",