luna-components-library 1.1.30 β 1.1.32
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
|
@@ -47,7 +47,7 @@ To ensure Tailwind CSS successfully generates and includes the necessary utility
|
|
|
47
47
|
## π Quick Start
|
|
48
48
|
|
|
49
49
|
```jsx
|
|
50
|
-
import { Button, Card, Anchor, Accordion, Spinner, DropDown, ProgressBar, Preloader, ScrollTop, Modal } from 'luna-components-library';
|
|
50
|
+
import { Button, Card, Anchor, Accordion, Spinner, DropDown, ProgressBar, Preloader, ScrollTop, Modal, Input } from 'luna-components-library';
|
|
51
51
|
|
|
52
52
|
function App() {
|
|
53
53
|
return (
|
|
@@ -126,6 +126,13 @@ function App() {
|
|
|
126
126
|
size="md"
|
|
127
127
|
className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
|
|
128
128
|
/>
|
|
129
|
+
|
|
130
|
+
<Input
|
|
131
|
+
inputSize="md"
|
|
132
|
+
variant="primary"
|
|
133
|
+
placeholder="Enter your text here"
|
|
134
|
+
className="border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
|
|
135
|
+
/>
|
|
129
136
|
</div>
|
|
130
137
|
);
|
|
131
138
|
}
|
|
@@ -162,7 +169,7 @@ A versatile button component with multiple variants and sizes.
|
|
|
162
169
|
|
|
163
170
|
**Types:**
|
|
164
171
|
```typescript
|
|
165
|
-
type ButtonVariant = 'primary' | 'secondary' | 'outline';
|
|
172
|
+
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'link';
|
|
166
173
|
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
167
174
|
```
|
|
168
175
|
|
|
@@ -170,6 +177,13 @@ type ButtonSize = 'sm' | 'md' | 'lg';
|
|
|
170
177
|
- `primary` - Blue background button
|
|
171
178
|
- `secondary` - Gray background button
|
|
172
179
|
- `outline` - Transparent with border
|
|
180
|
+
- `success` - Green background button
|
|
181
|
+
- `danger` - Red background button
|
|
182
|
+
- `warning` - Yellow background button
|
|
183
|
+
- `info` - Cyan background button
|
|
184
|
+
- `dark` - Dark gray background button
|
|
185
|
+
- `light` - Light gray background button
|
|
186
|
+
- `link` - Blue text link with hover effects
|
|
173
187
|
|
|
174
188
|
### Card
|
|
175
189
|
A flexible card component for displaying content with various padding and shadow options.
|
|
@@ -753,6 +767,66 @@ const MyComponent = () => {
|
|
|
753
767
|
};
|
|
754
768
|
```
|
|
755
769
|
|
|
770
|
+
### Input
|
|
771
|
+
A versatile input component with multiple variants, sizes, and types.
|
|
772
|
+
|
|
773
|
+
```jsx
|
|
774
|
+
<Input
|
|
775
|
+
inputSize="md"
|
|
776
|
+
variant="primary"
|
|
777
|
+
type="text"
|
|
778
|
+
placeholder="Enter your text here"
|
|
779
|
+
value={inputValue}
|
|
780
|
+
onChange={(value) => setInputValue(value)}
|
|
781
|
+
className="border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
|
|
782
|
+
/>
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
**Props:**
|
|
786
|
+
- `children?: React.ReactNode` - Label content for the input
|
|
787
|
+
- `variant?: InputVariant` - Input style variant (default: 'none')
|
|
788
|
+
- `inputSize?: InputSize` - Input size (default: 'md')
|
|
789
|
+
- `type?: InputType` - HTML input type (default: 'text')
|
|
790
|
+
- `placeholder?: string` - Placeholder text
|
|
791
|
+
- `value?: string` - Input value
|
|
792
|
+
- `onChange?: (value: string) => void` - Change handler
|
|
793
|
+
- `onFocus?: () => void` - Focus handler
|
|
794
|
+
- `onBlur?: () => void` - Blur handler
|
|
795
|
+
- `disabled?: boolean` - Disable input (default: false)
|
|
796
|
+
- `required?: boolean` - Required field (default: false)
|
|
797
|
+
- `readOnly?: boolean` - Read-only input (default: false)
|
|
798
|
+
- `className?: string` - Additional CSS classes
|
|
799
|
+
- `containerClassName?: string` - CSS classes for container element
|
|
800
|
+
- `inputClassName?: string` - CSS classes for input element
|
|
801
|
+
- `variantClassName?: string` - CSS classes for variant styling
|
|
802
|
+
- `sizeClassName?: string` - CSS classes for size styling
|
|
803
|
+
- `style?: React.CSSProperties` - Custom inline styles
|
|
804
|
+
- `id?: string` - HTML id attribute for label association
|
|
805
|
+
- `aria-label?: string` - ARIA label for accessibility
|
|
806
|
+
- `aria-labelledby?: string` - ARIA labelledby for accessibility
|
|
807
|
+
- `...props`: any - Additional HTML input attributes (spreads all native input props)
|
|
808
|
+
|
|
809
|
+
**Types:**
|
|
810
|
+
```typescript
|
|
811
|
+
type InputVariant = 'none' | 'primary' | 'secondary' | 'outline' | 'danger' | 'success';
|
|
812
|
+
type InputSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
813
|
+
type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'month' | 'week' | 'color' | 'file' | 'hidden' | 'image' | 'range' | 'reset' | 'submit';
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
**Variants:**
|
|
817
|
+
- `none` - Default styling with border
|
|
818
|
+
- `primary` - Blue background with white text
|
|
819
|
+
- `secondary` - Gray background with white text
|
|
820
|
+
- `outline` - Border only with gray text
|
|
821
|
+
- `danger` - Red background with white text
|
|
822
|
+
- `success` - Green background with white text
|
|
823
|
+
|
|
824
|
+
**Size Options:**
|
|
825
|
+
- `sm` - Small padding and text
|
|
826
|
+
- `md` - Medium padding and text
|
|
827
|
+
- `lg` - Large padding and text
|
|
828
|
+
- `xl` - Extra large padding and text
|
|
829
|
+
|
|
756
830
|
## π οΈ Development
|
|
757
831
|
|
|
758
832
|
### Prerequisites
|
|
@@ -795,6 +869,7 @@ luna-library/
|
|
|
795
869
|
β β βββ Preloader.tsx
|
|
796
870
|
β β βββ ScrollTop.tsx
|
|
797
871
|
β β βββ WhatsApp.tsx
|
|
872
|
+
β β βββ Input.tsx
|
|
798
873
|
β β βββ index.ts
|
|
799
874
|
β βββ index.ts
|
|
800
875
|
βββ dist/ # Build output
|
|
@@ -47,7 +47,14 @@ var Button = ({ children, variant = "primary", size = "sm", onClick = () => void
|
|
|
47
47
|
${{
|
|
48
48
|
primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
|
|
49
49
|
secondary: "bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500",
|
|
50
|
-
outline: "border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500"
|
|
50
|
+
outline: "border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500",
|
|
51
|
+
success: "bg-green-600 text-white hover:bg-green-700 focus:ring-green-500",
|
|
52
|
+
danger: "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500",
|
|
53
|
+
warning: "bg-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500",
|
|
54
|
+
info: "bg-cyan-600 text-white hover:bg-cyan-700 focus:ring-cyan-500",
|
|
55
|
+
dark: "bg-gray-900 text-white hover:bg-gray-800 focus:ring-gray-900",
|
|
56
|
+
light: "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-300",
|
|
57
|
+
link: "text-blue-600 hover:text-blue-800 hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
51
58
|
}[variant]}
|
|
52
59
|
${{
|
|
53
60
|
sm: "px-3 py-1.5 text-sm",
|
|
@@ -96,7 +103,7 @@ var Card = ({ children, title, className = "", containerClassName = "bg-white ro
|
|
|
96
103
|
};
|
|
97
104
|
//#endregion
|
|
98
105
|
//#region src/components/Anchor.tsx
|
|
99
|
-
var Anchor = ({ children = "Pablo Andrey Chacon Luna", variant = "none", size = "sm", href = "https://andreychaconresumereact.netlify.app/", className, containerClassName = "font-medium rounded-lg transition-colors focus:outline-none focus:ring-2", variantClassName = "bg-blue-600 text-white hover:bg-blue-700", sizeClassName = "px-3 py-1.5 text-sm", target = "_blank", rel = "noopener noreferrer", style, ...props }) => {
|
|
106
|
+
var Anchor = ({ children = "Pablo Andrey Chacon Luna", variant = "none", size = "sm", href = "https://andreychaconresumereact.netlify.app/", className, containerClassName = variant === "none" ? "font-medium transition-colors focus:outline-none" : "font-medium rounded-lg transition-colors focus:outline-none focus:ring-2", variantClassName = "bg-blue-600 text-white hover:bg-blue-700", sizeClassName = "px-3 py-1.5 text-sm", target = "_blank", rel = "noopener noreferrer", style, ...props }) => {
|
|
100
107
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
101
108
|
href,
|
|
102
109
|
target,
|
|
@@ -736,6 +743,64 @@ var Modal = ({ show, onHide, size = "md", centered = false, backdrop = true, bac
|
|
|
736
743
|
});
|
|
737
744
|
};
|
|
738
745
|
//#endregion
|
|
739
|
-
|
|
746
|
+
//#region src/components/Input.tsx
|
|
747
|
+
var Input = ({ children, variant = "none", type = "text", inputSize = "md", placeholder, value, onChange, onFocus, onBlur, disabled = false, required = false, readOnly = false, className = "", containerClassName = "relative inline-block", inputClassName = "border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500", variantClassName = "", sizeClassName = "", style, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props }) => {
|
|
748
|
+
const baseClasses = containerClassName;
|
|
749
|
+
const variantClasses = {
|
|
750
|
+
none: "",
|
|
751
|
+
primary: "bg-blue-600 text-white border-blue-600 focus:ring-blue-500 focus:border-blue-500",
|
|
752
|
+
secondary: "bg-gray-600 text-white border-gray-600 focus:ring-gray-500 focus:border-gray-500",
|
|
753
|
+
outline: "border-gray-300 text-gray-700 bg-white focus:ring-blue-500 focus:border-blue-500",
|
|
754
|
+
danger: "bg-red-600 text-white border-red-600 focus:ring-red-500 focus:border-red-500",
|
|
755
|
+
success: "bg-green-600 text-white border-green-600 focus:ring-green-500 focus:border-green-500"
|
|
756
|
+
};
|
|
757
|
+
const sizeClasses = {
|
|
758
|
+
sm: "px-2 py-1 text-sm",
|
|
759
|
+
md: "px-3 py-2 text-base",
|
|
760
|
+
lg: "px-4 py-3 text-lg",
|
|
761
|
+
xl: "px-6 py-4 text-xl"
|
|
762
|
+
};
|
|
763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
764
|
+
className: `
|
|
765
|
+
${baseClasses}
|
|
766
|
+
${variantClasses[variant]}
|
|
767
|
+
${sizeClasses[inputSize]}
|
|
768
|
+
${variantClassName}
|
|
769
|
+
${sizeClassName}
|
|
770
|
+
${className}
|
|
771
|
+
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
772
|
+
${readOnly ? "bg-gray-100 cursor-not-allowed" : ""}
|
|
773
|
+
`.trim(),
|
|
774
|
+
style,
|
|
775
|
+
children: [children && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
|
|
776
|
+
htmlFor: id,
|
|
777
|
+
className: "block text-sm font-medium text-gray-700 mb-1",
|
|
778
|
+
children
|
|
779
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
780
|
+
id,
|
|
781
|
+
type,
|
|
782
|
+
placeholder,
|
|
783
|
+
value,
|
|
784
|
+
onChange: (e) => onChange?.(e.target.value),
|
|
785
|
+
onFocus,
|
|
786
|
+
onBlur,
|
|
787
|
+
disabled,
|
|
788
|
+
required,
|
|
789
|
+
readOnly,
|
|
790
|
+
"aria-label": ariaLabel,
|
|
791
|
+
"aria-labelledby": ariaLabelledby,
|
|
792
|
+
className: `
|
|
793
|
+
${inputClassName}
|
|
794
|
+
${variantClasses[variant]}
|
|
795
|
+
${sizeClasses[inputSize]}
|
|
796
|
+
${variantClassName}
|
|
797
|
+
${sizeClassName}
|
|
798
|
+
`.trim(),
|
|
799
|
+
...props
|
|
800
|
+
})]
|
|
801
|
+
});
|
|
802
|
+
};
|
|
803
|
+
//#endregion
|
|
804
|
+
export { Accordion, Anchor, Button, Card, DropDown, Input, Modal, Preloader, ProgressBar, ScrollTop, Spinner, Typed, WhatsApp };
|
|
740
805
|
|
|
741
806
|
//# sourceMappingURL=luna-components-library.js.map
|
|
@@ -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\nexport type ButtonVariant = 'primary' | 'secondary' | 'outline';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type AllButtonProps = React.ComponentPropsWithoutRef<'button'>;\n\nexport type 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 style?: React.CSSProperties;\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 style,\n ...props\n}: AllButtonProps & 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 style={style}\n {...props}\n >\n {children}\n </button>\n );\n};\n\nexport default Button;\n","import React from 'react';\n\n// Card padding and shadow variants\nexport type CardPadding = 'none' | 'sm' | 'md' | 'lg';\nexport type CardShadow = 'none' | 'sm' | 'md' | 'lg';\n\nexport type CardProps = {\n children: React.ReactNode;\n title?: string;\n className?: string;\n containerClassName?: string;\n titleClassName?: string;\n padding?: CardPadding;\n shadow?: CardShadow;\n style?: React.CSSProperties;\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 style,\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} style={style}>\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\nexport type AnchorVariant = 'none' | 'primary' | 'secondary' | 'outline';\r\nexport type AnchorSize = 'sm' | 'md' | 'lg';\r\nexport type AllAnchorProps = React.ComponentPropsWithoutRef<'a'>;\r\n\r\nexport type 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 style?: React.CSSProperties;\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 style,\r\n ...props\r\n}: AnchorProps & AllAnchorProps) => {\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} style={style} {...props}>\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\nexport type 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 style?: React.CSSProperties;\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 style\r\n}: AccordionProps) => {\r\n return (\r\n <div className={`${containerClassName} ${className}`} style={style}>\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\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\nexport type SpinnerType = 'circle' | 'dots' | 'pulse' | 'bars';\n\nexport type SpinnerProps = {\n className?: string;\n containerClassName?: string;\n dotClassName?: string;\n barClassName?: string;\n size?: SpinnerSize;\n type?: SpinnerType;\n style?: React.CSSProperties;\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 style\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 style={style}\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\nexport type 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 style?: React.CSSProperties;\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 style\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}`} style={style}>\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\nexport type ProgressBarVariant = 'primary' | 'success' | 'warning' | 'danger' | 'dark' | 'light';\r\n\r\n// Core progress bar props\r\nexport type 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\nexport type 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 = ({\r\n progress,\r\n max,\r\n min,\r\n 'aria-label': ariaLabel,\r\n className,\r\n style,\r\n containerClassName = 'w-full bg-gray-200 rounded-full h-4 overflow-hidden',\r\n barClassName = 'h-full rounded-full transition-all duration-300 flex items-center justify-center text-xs font-medium',\r\n variant = 'primary'\r\n}: 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} style={style}>\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 }}\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}`} style={style}>\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 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 type 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 /** Custom inline styles */\n style?: React.CSSProperties;\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 style\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, ...style }}\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 type 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 /** Custom inline styles */\n style?: React.CSSProperties;\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 style\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 style={style}\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","../src/components/Input.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\nexport type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'link';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\nexport type AllButtonProps = React.ComponentPropsWithoutRef<'button'>;\n\nexport type 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 style?: React.CSSProperties;\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 style,\n ...props\n}: AllButtonProps & 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 success: 'bg-green-600 text-white hover:bg-green-700 focus:ring-green-500',\n danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500',\n warning: 'bg-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500',\n info: 'bg-cyan-600 text-white hover:bg-cyan-700 focus:ring-cyan-500',\n dark: 'bg-gray-900 text-white hover:bg-gray-800 focus:ring-gray-900',\n light: 'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-300',\n link: 'text-blue-600 hover:text-blue-800 hover:underline focus:outline-none focus:ring-2 focus:ring-blue-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 style={style}\n {...props}\n >\n {children}\n </button>\n );\n};\n\nexport default Button;\n","import React from 'react';\n\n// Card padding and shadow variants\nexport type CardPadding = 'none' | 'sm' | 'md' | 'lg';\nexport type CardShadow = 'none' | 'sm' | 'md' | 'lg';\n\nexport type CardProps = {\n children: React.ReactNode;\n title?: string;\n className?: string;\n containerClassName?: string;\n titleClassName?: string;\n padding?: CardPadding;\n shadow?: CardShadow;\n style?: React.CSSProperties;\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 style,\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} style={style}>\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\nexport type AnchorVariant = 'none' | 'primary' | 'secondary' | 'outline';\r\nexport type AnchorSize = 'sm' | 'md' | 'lg';\r\nexport type AllAnchorProps = React.ComponentPropsWithoutRef<'a'>;\r\n\r\nexport type 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 style?: React.CSSProperties;\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 = variant === 'none' ? 'font-medium transition-colors focus:outline-none' : '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 style,\r\n ...props\r\n}: AnchorProps & AllAnchorProps) => {\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} style={style} {...props}>\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\nexport type 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 style?: React.CSSProperties;\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 style\r\n}: AccordionProps) => {\r\n return (\r\n <div className={`${containerClassName} ${className}`} style={style}>\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\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\nexport type SpinnerType = 'circle' | 'dots' | 'pulse' | 'bars';\n\nexport type SpinnerProps = {\n className?: string;\n containerClassName?: string;\n dotClassName?: string;\n barClassName?: string;\n size?: SpinnerSize;\n type?: SpinnerType;\n style?: React.CSSProperties;\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 style\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 style={style}\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\nexport type 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 style?: React.CSSProperties;\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 style\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}`} style={style}>\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\nexport type ProgressBarVariant = 'primary' | 'success' | 'warning' | 'danger' | 'dark' | 'light';\r\n\r\n// Core progress bar props\r\nexport type 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\nexport type 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 = ({\r\n progress,\r\n max,\r\n min,\r\n 'aria-label': ariaLabel,\r\n className,\r\n style,\r\n containerClassName = 'w-full bg-gray-200 rounded-full h-4 overflow-hidden',\r\n barClassName = 'h-full rounded-full transition-all duration-300 flex items-center justify-center text-xs font-medium',\r\n variant = 'primary'\r\n}: 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} style={style}>\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 }}\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}`} style={style}>\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 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 type 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 /** Custom inline styles */\n style?: React.CSSProperties;\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 style\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, ...style }}\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 type 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 /** Custom inline styles */\n style?: React.CSSProperties;\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 style\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 style={style}\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","import React from 'react';\n\n// Input variants and sizes\nexport type InputVariant = 'none' | 'primary' | 'secondary' | 'outline' | 'danger' | 'success';\nexport type InputSize = 'sm' | 'md' | 'lg' | 'xl';\nexport type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'month' | 'week' | 'color' | 'file' | 'hidden' | 'image' | 'range' | 'reset' | 'submit';\n\nexport type AllInputProps = Omit<React.ComponentPropsWithoutRef<'input'>, 'onChange'>;\n\nexport type InputProps = {\n children?: React.ReactNode;\n variant?: InputVariant;\n inputSize?: InputSize;\n type?: InputType;\n placeholder?: string;\n value?: string;\n onChange?: (value: string) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n disabled?: boolean;\n required?: boolean;\n readOnly?: boolean;\n className?: string;\n containerClassName?: string;\n inputClassName?: string;\n variantClassName?: string;\n sizeClassName?: string;\n style?: React.CSSProperties;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n};\n\nconst Input = ({\n children,\n variant = 'none',\n type = 'text',\n inputSize = 'md',\n placeholder,\n value,\n onChange,\n onFocus,\n onBlur,\n disabled = false,\n required = false,\n readOnly = false,\n className = '',\n containerClassName = 'relative inline-block',\n inputClassName = 'border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500',\n variantClassName = '',\n sizeClassName = '',\n style,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n}: InputProps & AllInputProps) => {\n const baseClasses = containerClassName;\n\n const variantClasses: Record<InputVariant, string> = {\n none: '',\n primary: 'bg-blue-600 text-white border-blue-600 focus:ring-blue-500 focus:border-blue-500',\n secondary: 'bg-gray-600 text-white border-gray-600 focus:ring-gray-500 focus:border-gray-500',\n outline: 'border-gray-300 text-gray-700 bg-white focus:ring-blue-500 focus:border-blue-500',\n danger: 'bg-red-600 text-white border-red-600 focus:ring-red-500 focus:border-red-500',\n success: 'bg-green-600 text-white border-green-600 focus:ring-green-500 focus:border-green-500'\n };\n\n const sizeClasses: Record<InputSize, string> = {\n sm: 'px-2 py-1 text-sm',\n md: 'px-3 py-2 text-base',\n lg: 'px-4 py-3 text-lg',\n xl: 'px-6 py-4 text-xl'\n };\n\n const classes = `\n ${baseClasses}\n ${variantClasses[variant]}\n ${sizeClasses[inputSize]}\n ${variantClassName}\n ${sizeClassName}\n ${className}\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${readOnly ? 'bg-gray-100 cursor-not-allowed' : ''}\n `.trim();\n\n return (\n <div className={classes} style={style}>\n {children && (\n <label\n htmlFor={id}\n className=\"block text-sm font-medium text-gray-700 mb-1\"\n >\n {children}\n </label>\n )}\n <input\n id={id}\n type={type}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n onFocus={onFocus}\n onBlur={onBlur}\n disabled={disabled}\n required={required}\n readOnly={readOnly}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={`\n ${inputClassName}\n ${variantClasses[variant]}\n ${sizeClasses[inputSize]}\n ${variantClassName}\n ${sizeClassName}\n `.trim()}\n {...props}\n />\n </div>\n );\n};\n\nexport default Input;\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
export type ButtonVariant = 'primary' | 'secondary' | 'outline';
|
|
2
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'link';
|
|
3
3
|
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
4
4
|
export type AllButtonProps = React.ComponentPropsWithoutRef<'button'>;
|
|
5
5
|
export type ButtonProps = {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type InputVariant = 'none' | 'primary' | 'secondary' | 'outline' | 'danger' | 'success';
|
|
3
|
+
export type InputSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
4
|
+
export type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'month' | 'week' | 'color' | 'file' | 'hidden' | 'image' | 'range' | 'reset' | 'submit';
|
|
5
|
+
export type AllInputProps = Omit<React.ComponentPropsWithoutRef<'input'>, 'onChange'>;
|
|
6
|
+
export type InputProps = {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
variant?: InputVariant;
|
|
9
|
+
inputSize?: InputSize;
|
|
10
|
+
type?: InputType;
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
value?: string;
|
|
13
|
+
onChange?: (value: string) => void;
|
|
14
|
+
onFocus?: () => void;
|
|
15
|
+
onBlur?: () => void;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
readOnly?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
containerClassName?: string;
|
|
21
|
+
inputClassName?: string;
|
|
22
|
+
variantClassName?: string;
|
|
23
|
+
sizeClassName?: string;
|
|
24
|
+
style?: React.CSSProperties;
|
|
25
|
+
id?: string;
|
|
26
|
+
'aria-label'?: string;
|
|
27
|
+
'aria-labelledby'?: string;
|
|
28
|
+
};
|
|
29
|
+
declare const Input: ({ children, variant, type, inputSize, placeholder, value, onChange, onFocus, onBlur, disabled, required, readOnly, className, containerClassName, inputClassName, variantClassName, sizeClassName, style, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props }: InputProps & AllInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export default Input;
|
package/package.json
CHANGED