@xscriptor/xcomponents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CODE_OF_CONDUCT.md +35 -0
  2. package/CONTRIBUTING.md +64 -0
  3. package/LICENSE +21 -0
  4. package/README.md +127 -0
  5. package/SECURITY.md +25 -0
  6. package/dist/chunk-2OAXRRVQ.mjs +150 -0
  7. package/dist/chunk-2OAXRRVQ.mjs.map +1 -0
  8. package/dist/chunk-42XPBYTL.mjs +186 -0
  9. package/dist/chunk-42XPBYTL.mjs.map +1 -0
  10. package/dist/chunk-5G4P2E76.mjs +66 -0
  11. package/dist/chunk-5G4P2E76.mjs.map +1 -0
  12. package/dist/chunk-FZRTAML3.mjs +1 -0
  13. package/dist/chunk-FZRTAML3.mjs.map +1 -0
  14. package/dist/chunk-NY22GB3E.mjs +311 -0
  15. package/dist/chunk-NY22GB3E.mjs.map +1 -0
  16. package/dist/chunk-QCMWPIG7.mjs +320 -0
  17. package/dist/chunk-QCMWPIG7.mjs.map +1 -0
  18. package/dist/chunk-U27ZVCP7.mjs +247 -0
  19. package/dist/chunk-U27ZVCP7.mjs.map +1 -0
  20. package/dist/components/content/index.css +132 -0
  21. package/dist/components/content/index.css.map +1 -0
  22. package/dist/components/content/index.d.mts +17 -0
  23. package/dist/components/content/index.d.ts +17 -0
  24. package/dist/components/content/index.js +102 -0
  25. package/dist/components/content/index.js.map +1 -0
  26. package/dist/components/content/index.mjs +7 -0
  27. package/dist/components/content/index.mjs.map +1 -0
  28. package/dist/components/forms/index.css +307 -0
  29. package/dist/components/forms/index.css.map +1 -0
  30. package/dist/components/forms/index.d.mts +68 -0
  31. package/dist/components/forms/index.d.ts +68 -0
  32. package/dist/components/forms/index.js +357 -0
  33. package/dist/components/forms/index.js.map +1 -0
  34. package/dist/components/forms/index.mjs +9 -0
  35. package/dist/components/forms/index.mjs.map +1 -0
  36. package/dist/components/gallery/index.css +229 -0
  37. package/dist/components/gallery/index.css.map +1 -0
  38. package/dist/components/gallery/index.d.mts +29 -0
  39. package/dist/components/gallery/index.d.ts +29 -0
  40. package/dist/components/gallery/index.js +187 -0
  41. package/dist/components/gallery/index.js.map +1 -0
  42. package/dist/components/gallery/index.mjs +9 -0
  43. package/dist/components/gallery/index.mjs.map +1 -0
  44. package/dist/components/index.css +1181 -0
  45. package/dist/components/index.css.map +1 -0
  46. package/dist/components/index.d.mts +8 -0
  47. package/dist/components/index.d.ts +8 -0
  48. package/dist/components/index.js +1317 -0
  49. package/dist/components/index.js.map +1 -0
  50. package/dist/components/index.mjs +50 -0
  51. package/dist/components/index.mjs.map +1 -0
  52. package/dist/components/layout/index.css +168 -0
  53. package/dist/components/layout/index.css.map +1 -0
  54. package/dist/components/layout/index.d.mts +55 -0
  55. package/dist/components/layout/index.d.ts +55 -0
  56. package/dist/components/layout/index.js +224 -0
  57. package/dist/components/layout/index.js.map +1 -0
  58. package/dist/components/layout/index.mjs +11 -0
  59. package/dist/components/layout/index.mjs.map +1 -0
  60. package/dist/components/navigation/index.css +229 -0
  61. package/dist/components/navigation/index.css.map +1 -0
  62. package/dist/components/navigation/index.d.mts +76 -0
  63. package/dist/components/navigation/index.d.ts +76 -0
  64. package/dist/components/navigation/index.js +347 -0
  65. package/dist/components/navigation/index.js.map +1 -0
  66. package/dist/components/navigation/index.mjs +7 -0
  67. package/dist/components/navigation/index.mjs.map +1 -0
  68. package/dist/components/social/index.css +116 -0
  69. package/dist/components/social/index.css.map +1 -0
  70. package/dist/components/social/index.d.mts +55 -0
  71. package/dist/components/social/index.d.ts +55 -0
  72. package/dist/components/social/index.js +280 -0
  73. package/dist/components/social/index.js.map +1 -0
  74. package/dist/components/social/index.mjs +21 -0
  75. package/dist/components/social/index.mjs.map +1 -0
  76. package/dist/index.css +1181 -0
  77. package/dist/index.css.map +1 -0
  78. package/dist/index.d.mts +8 -0
  79. package/dist/index.d.ts +8 -0
  80. package/dist/index.js +1317 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/index.mjs +50 -0
  83. package/dist/index.mjs.map +1 -0
  84. package/package.json +86 -0
@@ -0,0 +1,35 @@
1
+ # Code of Conduct
2
+
3
+ ## Our commitment
4
+
5
+ We are committed to making participation in this project a respectful,
6
+ harassment-free experience for everyone.
7
+
8
+ ## Expected behavior
9
+
10
+ - Be respectful and constructive.
11
+ - Accept feedback with professionalism.
12
+ - Focus on what is best for the project and community.
13
+ - Show empathy toward other contributors.
14
+
15
+ ## Unacceptable behavior
16
+
17
+ - Harassment, intimidation, or discrimination.
18
+ - Trolling, insulting, or derogatory comments.
19
+ - Publishing private information without permission.
20
+ - Any other conduct that is inappropriate in a professional setting.
21
+
22
+ ## Enforcement
23
+
24
+ Project maintainers are responsible for clarifying standards and may take
25
+ appropriate action in response to unacceptable behavior.
26
+
27
+ ## Reporting
28
+
29
+ To report behavior that violates this Code of Conduct, open a private security
30
+ report as described in SECURITY.md.
31
+
32
+ ## Attribution
33
+
34
+ This document is adapted from common open-source community standards,
35
+ including the Contributor Covenant principles.
@@ -0,0 +1,64 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in improving @xscriptor/xcomponents.
4
+
5
+ ## Scope
6
+
7
+ This package contains reusable React/Next.js UI components.
8
+ Contributions should keep public APIs stable and types well documented.
9
+
10
+ ## Development setup
11
+
12
+ 1. Install dependencies:
13
+
14
+ ```bash
15
+ npm install
16
+ ```
17
+
18
+ 2. Build the package:
19
+
20
+ ```bash
21
+ npm run prepare:build
22
+ ```
23
+
24
+ 3. Validate the package content:
25
+
26
+ ```bash
27
+ npm pack --dry-run
28
+ ```
29
+
30
+ ## Contribution workflow
31
+
32
+ 1. Create a feature branch from `dev`.
33
+ 2. Keep changes focused and small.
34
+ 3. Add or update examples when behavior changes.
35
+ 4. Ensure build passes before opening a PR.
36
+ 5. Open a pull request with:
37
+ - clear summary
38
+ - screenshots or usage snippet for UI changes
39
+ - migration note if API changed
40
+
41
+ ## Coding guidelines
42
+
43
+ - Use TypeScript and exported prop types.
44
+ - Keep component names with `X` prefix.
45
+ - Prefer category barrels for exports.
46
+ - Avoid breaking changes unless explicitly discussed.
47
+
48
+ ## Commit style
49
+
50
+ Use concise, imperative commit messages, for example:
51
+
52
+ - `feat(social): add XLinkedInIcon hover fill support`
53
+ - `fix(layout): correct zigzag spacing on mobile`
54
+ - `docs(readme): update publish steps`
55
+
56
+ ## Reporting issues
57
+
58
+ Please include:
59
+
60
+ - expected behavior
61
+ - current behavior
62
+ - reproduction steps
63
+ - package version
64
+ - React/Next.js versions
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Xscriptor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ <h1 align="center">@xscriptor/xcomponents</h1>
2
+
3
+ <div align="center">
4
+
5
+ Reusable React/Next.js component package by Xscriptor.
6
+
7
+ ![npm](https://xscriptor.github.io/badges/tools/npm.svg)
8
+ ![license](https://xscriptor.github.io/badges/terminal/LICENSE.svg)
9
+ ![MIT](https://xscriptor.github.io/badges/licenses/mit.svg)
10
+ ![typescript](https://xscriptor.github.io/badges/languages/typescript.svg)
11
+ ![CSS](https://xscriptor.github.io/badges/languages/css.svg)
12
+
13
+ </div>
14
+
15
+ <br>
16
+ <hr>
17
+
18
+ <details open>
19
+ <summary><h2>Table of Contents</h2></summary>
20
+ <ul>
21
+ <li><a href="#overview">Overview</a></li>
22
+ <li><a href="#installation">Installation</a></li>
23
+ <li><a href="#usage">Usage</a></li>
24
+ <li><a href="#exports">Exports</a></li>
25
+ <li><a href="#project-structure">Project Structure</a></li>
26
+ <li><a href="#scripts">Scripts</a></li>
27
+ <li><a href="#packaging-and-publish">Packaging and Publish</a></li>
28
+ <li><a href="#related-documents">Related Documents</a></li>
29
+ </ul>
30
+ </details>
31
+
32
+ <hr>
33
+
34
+ <h2 id="overview">Overview</h2>
35
+
36
+ <p>
37
+ @xscriptor/xcomponents provides reusable UI building blocks for React and Next.js projects,
38
+ organized by category and exported with TypeScript declarations.
39
+ </p>
40
+
41
+ <h2 id="installation">Installation</h2>
42
+
43
+ ```bash
44
+ npm install @xscriptor/xcomponents
45
+ ```
46
+
47
+ <h2 id="usage">Usage</h2>
48
+
49
+ ```tsx
50
+ import { XNavbar, XSeparator } from "@xscriptor/xcomponents";
51
+ import { XContactForm } from "@xscriptor/xcomponents/forms";
52
+ import { XSocialContact, XInstagramIcon } from "@xscriptor/xcomponents/social";
53
+ ```
54
+
55
+ <h2 id="exports">Exports</h2>
56
+
57
+ <ul>
58
+ <li><code>@xscriptor/xcomponents</code> (root exports)</li>
59
+ <li><code>@xscriptor/xcomponents/forms</code></li>
60
+ <li><code>@xscriptor/xcomponents/navigation</code></li>
61
+ <li><code>@xscriptor/xcomponents/layout</code></li>
62
+ <li><code>@xscriptor/xcomponents/content</code></li>
63
+ <li><code>@xscriptor/xcomponents/gallery</code></li>
64
+ <li><code>@xscriptor/xcomponents/social</code></li>
65
+ </ul>
66
+
67
+ <h2 id="project-structure">Project Structure</h2>
68
+
69
+ <ul>
70
+ <li><code>src/components/forms</code></li>
71
+ <li><code>src/components/navigation</code></li>
72
+ <li><code>src/components/layout</code></li>
73
+ <li><code>src/components/content</code></li>
74
+ <li><code>src/components/gallery</code></li>
75
+ <li><code>src/components/social</code></li>
76
+ </ul>
77
+
78
+ <h2 id="scripts">Scripts</h2>
79
+
80
+ ```bash
81
+ npm run build
82
+ npm run clean
83
+ npm run prepare:build
84
+ ```
85
+
86
+ <h2 id="packaging-and-publish">Packaging and Publish</h2>
87
+
88
+ 1. Authenticate with npm:
89
+
90
+ ```bash
91
+ npm login
92
+ npm whoami
93
+ ```
94
+
95
+ 2. Build and validate package content:
96
+
97
+ ```bash
98
+ npm run prepare:build
99
+ npm pack --dry-run
100
+ ```
101
+
102
+ 3. Bump version:
103
+
104
+ ```bash
105
+ npm version patch
106
+ ```
107
+
108
+ 4. Publish package:
109
+
110
+ ```bash
111
+ npm publish
112
+ ```
113
+
114
+ <h2 id="related-documents">Related Documents</h2>
115
+
116
+ <ul>
117
+ <li><a href="./CONTRIBUTING.md">Contributing Guide</a></li>
118
+ <li><a href="./CODE_OF_CONDUCT.md">Code of Conduct</a></li>
119
+ <li><a href="./SECURITY.md">Security Policy</a></li>
120
+ <li><a href="./LICENSE">License (MIT)</a></li>
121
+ </ul>
122
+
123
+ <div align="center">
124
+ <h2>X</h2>
125
+
126
+ <a href="https://dev.xscriptor.com">XWeb</a> | <a href="https://dev.xscriptor.com">Profile</a>
127
+ </div>
package/SECURITY.md ADDED
@@ -0,0 +1,25 @@
1
+ # Security Policy
2
+
3
+ ## Supported versions
4
+
5
+ Security updates are applied to the latest published version of
6
+ `@xscriptor/xcomponents`.
7
+
8
+ | Version | Supported |
9
+ | --- | --- |
10
+ | latest | yes |
11
+ | older versions | no |
12
+
13
+ ## Reporting a vulnerability
14
+
15
+ If you find a security vulnerability, please do not open a public issue first.
16
+
17
+ Send a private report including:
18
+
19
+ - a short description of the issue
20
+ - reproduction steps or proof of concept
21
+ - potential impact
22
+ - suggested mitigation (if available)
23
+
24
+ Maintainers will acknowledge receipt as soon as possible and coordinate a fix
25
+ before public disclosure.
@@ -0,0 +1,150 @@
1
+ // src/components/gallery/xmicrogallerytext/XMicroGalleryText.tsx
2
+ import React, { useEffect, useRef } from "react";
3
+ import Image from "next/image";
4
+ import { motion } from "framer-motion";
5
+
6
+ // src/components/gallery/xmicrogallerytext/XMicroGalleryText.module.css
7
+ var XMicroGalleryText_default = {};
8
+
9
+ // src/components/gallery/xmicrogallerytext/XMicroGalleryText.tsx
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var DISPLAY_COUNT = 3;
12
+ var XMicroGalleryText = ({
13
+ images,
14
+ text,
15
+ textPosition = "left",
16
+ textAlign = "left",
17
+ autoShuffle = false,
18
+ shuffleInterval = 5e3
19
+ }) => {
20
+ const containerRef = useRef(null);
21
+ const [startIndex, setStartIndex] = React.useState(0);
22
+ const visibleImages = React.useMemo(() => {
23
+ const result = [];
24
+ for (let i = 0; i < DISPLAY_COUNT; i++) {
25
+ result.push(images[(startIndex + i) % images.length]);
26
+ }
27
+ return result;
28
+ }, [images, startIndex]);
29
+ React.useEffect(() => {
30
+ if (!autoShuffle || images.length <= DISPLAY_COUNT) return;
31
+ const intervalId = setInterval(() => {
32
+ setStartIndex((prev) => (prev + 1) % images.length);
33
+ }, shuffleInterval);
34
+ return () => clearInterval(intervalId);
35
+ }, [autoShuffle, shuffleInterval, images.length]);
36
+ const [isVisible, setIsVisible] = React.useState(false);
37
+ useEffect(() => {
38
+ const observer = new IntersectionObserver(
39
+ ([entry]) => {
40
+ if (entry.isIntersecting) {
41
+ setIsVisible(true);
42
+ observer.disconnect();
43
+ }
44
+ },
45
+ {
46
+ threshold: 0.1,
47
+ rootMargin: "0px 0px -50px 0px"
48
+ }
49
+ );
50
+ if (containerRef.current) {
51
+ observer.observe(containerRef.current);
52
+ }
53
+ return () => observer.disconnect();
54
+ }, []);
55
+ const isTextRight = textPosition === "right";
56
+ const alignClass = {
57
+ left: XMicroGalleryText_default.textLeft,
58
+ right: XMicroGalleryText_default.textRight,
59
+ center: XMicroGalleryText_default.textCenter
60
+ }[textAlign];
61
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: `${XMicroGalleryText_default.container} ${isTextRight ? XMicroGalleryText_default.reverse : ""}`, children: [
62
+ /* @__PURE__ */ jsx("div", { className: `${XMicroGalleryText_default.textContent} ${alignClass} ${isVisible ? XMicroGalleryText_default.visible : ""}`, children: typeof text === "string" ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: text } }) : text }),
63
+ /* @__PURE__ */ jsx("div", { className: XMicroGalleryText_default.gallery, children: /* @__PURE__ */ jsx("div", { className: XMicroGalleryText_default.artisticGrid, children: visibleImages.map((image, index) => /* @__PURE__ */ jsx(
64
+ motion.div,
65
+ {
66
+ layout: true,
67
+ className: `${XMicroGalleryText_default.imageWrapper} ${XMicroGalleryText_default[`artistic${index + 1}`]} ${isVisible ? XMicroGalleryText_default.visible : ""}`,
68
+ style: { transitionProperty: "opacity, box-shadow" },
69
+ transition: {
70
+ layout: { type: "spring", stiffness: 80, damping: 20 }
71
+ },
72
+ children: /* @__PURE__ */ jsx(
73
+ Image,
74
+ {
75
+ src: image.src,
76
+ alt: image.alt,
77
+ fill: true,
78
+ className: XMicroGalleryText_default.previewImage,
79
+ sizes: "(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
80
+ }
81
+ )
82
+ },
83
+ image.src
84
+ )) }) })
85
+ ] });
86
+ };
87
+ var XMicroGalleryText_default2 = XMicroGalleryText;
88
+
89
+ // src/components/gallery/xstaticgallery/XStaticGallery.tsx
90
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
91
+ import Image2 from "next/image";
92
+
93
+ // src/components/gallery/xstaticgallery/XStaticGallery.module.css
94
+ var XStaticGallery_default = {};
95
+
96
+ // src/components/gallery/xstaticgallery/XStaticGallery.tsx
97
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
98
+ var COLUMN_CLASSES = {
99
+ 1: XStaticGallery_default.cols1,
100
+ 2: XStaticGallery_default.cols2,
101
+ 3: XStaticGallery_default.cols3,
102
+ 4: XStaticGallery_default.cols4,
103
+ 5: XStaticGallery_default.cols5
104
+ };
105
+ function XStaticGallery({ images, columns = 4, title }) {
106
+ const containerRef = useRef2(null);
107
+ useEffect2(() => {
108
+ const observer = new IntersectionObserver(
109
+ (entries) => {
110
+ entries.forEach((entry) => {
111
+ if (entry.isIntersecting) {
112
+ entry.target.classList.add(XStaticGallery_default.visible);
113
+ }
114
+ });
115
+ },
116
+ {
117
+ threshold: 0.1,
118
+ rootMargin: "0px 0px -50px 0px"
119
+ }
120
+ );
121
+ const items = containerRef.current?.querySelectorAll(`.${XStaticGallery_default.masonryItem}`);
122
+ items?.forEach((el) => observer.observe(el));
123
+ return () => observer.disconnect();
124
+ }, []);
125
+ const colClass = COLUMN_CLASSES[columns] || COLUMN_CLASSES[4];
126
+ return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: XStaticGallery_default.galleryContainer, children: [
127
+ title && /* @__PURE__ */ jsx2("h2", { className: XStaticGallery_default.galleryTitle, children: title }),
128
+ /* @__PURE__ */ jsx2("div", { className: `${XStaticGallery_default.masonryGrid} ${colClass}`, children: images.map((image, index) => /* @__PURE__ */ jsx2("div", { className: XStaticGallery_default.masonryItem, children: /* @__PURE__ */ jsxs2("div", { className: XStaticGallery_default.imageContainer, children: [
129
+ /* @__PURE__ */ jsx2(
130
+ Image2,
131
+ {
132
+ src: image.src,
133
+ alt: image.alt,
134
+ width: 600,
135
+ height: 600,
136
+ className: XStaticGallery_default.galleryImage,
137
+ loading: "lazy",
138
+ sizes: "(max-width: 640px) 100vw, (max-width: 768px) 50vw, (max-width: 1280px) 33vw, 25vw"
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsx2("div", { className: XStaticGallery_default.imageOverlay })
142
+ ] }) }, index)) })
143
+ ] });
144
+ }
145
+
146
+ export {
147
+ XMicroGalleryText_default2 as XMicroGalleryText_default,
148
+ XStaticGallery
149
+ };
150
+ //# sourceMappingURL=chunk-2OAXRRVQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/gallery/xmicrogallerytext/XMicroGalleryText.tsx","../src/components/gallery/xmicrogallerytext/XMicroGalleryText.module.css","../src/components/gallery/xstaticgallery/XStaticGallery.tsx","../src/components/gallery/xstaticgallery/XStaticGallery.module.css"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport Image from 'next/image';\nimport { motion } from 'framer-motion';\nimport styles from './XMicroGalleryText.module.css';\n\nexport interface XMicroGalleryImage {\n src: string;\n alt: string;\n}\n\nexport interface XMicroGalleryTextProps {\n images: XMicroGalleryImage[];\n text: React.ReactNode;\n textPosition?: 'left' | 'right';\n textAlign?: 'left' | 'right' | 'center';\n autoShuffle?: boolean;\n shuffleInterval?: number;\n}\n\nconst DISPLAY_COUNT = 3;\n\nconst XMicroGalleryText: React.FC<XMicroGalleryTextProps> = ({ \n images, \n text, \n textPosition = 'left',\n textAlign = 'left',\n autoShuffle = false,\n shuffleInterval = 5000\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [startIndex, setStartIndex] = React.useState(0);\n\n const visibleImages = React.useMemo(() => {\n const result: XMicroGalleryImage[] = [];\n for (let i = 0; i < DISPLAY_COUNT; i++) {\n result.push(images[(startIndex + i) % images.length]);\n }\n return result;\n }, [images, startIndex]);\n\n React.useEffect(() => {\n if (!autoShuffle || images.length <= DISPLAY_COUNT) return;\n\n const intervalId = setInterval(() => {\n setStartIndex((prev) => (prev + 1) % images.length);\n }, shuffleInterval);\n\n return () => clearInterval(intervalId);\n }, [autoShuffle, shuffleInterval, images.length]);\n\n const [isVisible, setIsVisible] = React.useState(false);\n\n useEffect(() => {\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true);\n observer.disconnect();\n }\n },\n {\n threshold: 0.1,\n rootMargin: '0px 0px -50px 0px'\n }\n );\n\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => observer.disconnect();\n }, []);\n\n const isTextRight = textPosition === 'right';\n\n const alignClass = {\n left: styles.textLeft,\n right: styles.textRight,\n center: styles.textCenter,\n }[textAlign];\n\n return (\n <div ref={containerRef} className={`${styles.container} ${isTextRight ? styles.reverse : ''}`}>\n <div className={`${styles.textContent} ${alignClass} ${isVisible ? styles.visible : ''}`}>\n {typeof text === 'string' ? (\n <div dangerouslySetInnerHTML={{ __html: text }} />\n ) : (\n text\n )}\n </div>\n \n <div className={styles.gallery}>\n <div className={styles.artisticGrid}>\n {visibleImages.map((image, index) => (\n <motion.div \n layout\n key={image.src} \n className={`${styles.imageWrapper} ${styles[`artistic${index + 1}`]} ${isVisible ? styles.visible : ''}`}\n style={{ transitionProperty: 'opacity, box-shadow' }}\n transition={{\n layout: { type: \"spring\", stiffness: 80, damping: 20 }\n }}\n >\n <Image\n src={image.src}\n alt={image.alt}\n fill\n className={styles.previewImage}\n sizes=\"(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw\"\n />\n </motion.div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default XMicroGalleryText;\n",".container {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n width: 100%;\n align-items: center;\n margin: 2rem 0;\n}\n\n@media (min-width: 1024px) {\n .container {\n flex-direction: row;\n align-items: center;\n gap: 4rem;\n }\n \n .reverse {\n flex-direction: row-reverse;\n }\n}\n\n.textContent {\n flex: 1;\n opacity: 0;\n transform: translateY(30px);\n transition: opacity 0.8s ease-out, transform 0.8s ease-out;\n color: var(--foreground);\n}\n\n.textContent.visible {\n opacity: 1;\n transform: translateY(0);\n}\n\n.textLeft {\n text-align: left;\n}\n\n.textRight {\n text-align: right;\n}\n\n.textCenter {\n text-align: center;\n}\n\n.textContent p,\n.textContent div,\n.textContent span,\n.textContent em,\n.textContent strong,\n.textContent a {\n text-align: inherit;\n max-width: none;\n margin-left: unset;\n margin-right: unset;\n}\n\n.gallery {\n flex: 1.5;\n width: 100%;\n}\n\n.artisticGrid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n grid-template-rows: 380px 220px;\n gap: 1rem;\n}\n\n.imageWrapper {\n position: relative;\n overflow: hidden;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n border-radius: 20px;\n opacity: 0;\n transform: translateY(50px) scale(0.95);\n transition: opacity 0.6s ease-out, transform 0.6s ease-out, box-shadow 0.3s ease;\n}\n\n.imageWrapper.visible {\n opacity: 1;\n transform: translateY(0) scale(1);\n}\n\n.imageWrapper:hover {\n transform: translateY(-5px);\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);\n}\n\n.previewImage {\n object-fit: cover;\n}\n\n.artisticGrid .artistic1 .previewImage {\n object-position: center top;\n transform: translateY(0);\n}\n\n.artistic1 {\n grid-column: 1 / 4;\n grid-row: 1 / 2;\n transition-delay: 0.2s;\n}\n\n.artistic2 {\n grid-column: 1 / 2;\n grid-row: 2 / 3;\n transition-delay: 0.3s;\n}\n\n.artistic3 {\n grid-column: 2 / 4;\n grid-row: 2 / 3;\n transition-delay: 0.4s;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .artisticGrid {\n grid-template-columns: 1fr;\n grid-template-rows: 240px 180px 180px;\n }\n \n .artistic1,\n .artistic2,\n .artistic3 {\n grid-column: 1 / 2;\n }\n \n .artistic1 {\n grid-row: 1 / 2;\n }\n \n .artistic2 {\n grid-row: 2 / 3;\n }\n \n .artistic3 {\n grid-row: 3 / 4;\n }\n}\n\n@media (max-width: 480px) {\n .artisticGrid {\n grid-template-rows: 200px 140px 140px;\n }\n}\n","\"use client\";\nimport React, { useEffect, useRef } from 'react';\nimport Image from 'next/image';\nimport styles from './XStaticGallery.module.css';\n\nexport interface XStaticGalleryImage {\n src: string;\n alt: string;\n}\n\nexport interface XStaticGalleryProps {\n images: XStaticGalleryImage[];\n columns?: 1 | 2 | 3 | 4 | 5;\n title?: string;\n}\n\nconst COLUMN_CLASSES: Record<number, string> = {\n 1: styles.cols1,\n 2: styles.cols2,\n 3: styles.cols3,\n 4: styles.cols4,\n 5: styles.cols5,\n};\n\nexport default function XStaticGallery({ images, columns = 4, title }: XStaticGalleryProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n entry.target.classList.add(styles.visible);\n }\n });\n },\n {\n threshold: 0.1,\n rootMargin: '0px 0px -50px 0px',\n }\n );\n\n const items = containerRef.current?.querySelectorAll(`.${styles.masonryItem}`);\n items?.forEach((el) => observer.observe(el));\n\n return () => observer.disconnect();\n }, []);\n\n const colClass = COLUMN_CLASSES[columns] || COLUMN_CLASSES[4];\n\n return (\n <div ref={containerRef} className={styles.galleryContainer}>\n {title && <h2 className={styles.galleryTitle}>{title}</h2>}\n\n <div className={`${styles.masonryGrid} ${colClass}`}>\n {images.map((image, index) => (\n <div key={index} className={styles.masonryItem}>\n <div className={styles.imageContainer}>\n <Image\n src={image.src}\n alt={image.alt}\n width={600}\n height={600}\n className={styles.galleryImage}\n loading=\"lazy\"\n sizes=\"(max-width: 640px) 100vw, (max-width: 768px) 50vw, (max-width: 1280px) 33vw, 25vw\"\n />\n <div className={styles.imageOverlay} />\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n",".galleryContainer {\n width: 100%;\n max-width: 80rem;\n margin: 0 auto;\n padding: 1rem 1rem 3rem;\n}\n\n.galleryTitle {\n font-size: 1.875rem;\n text-align: right;\n color: var(--primary);\n margin-bottom: 3rem;\n opacity: 0.8;\n}\n\n/* Masonry via CSS columns */\n.masonryGrid {\n gap: 1rem;\n}\n\n.masonryItem {\n break-inside: avoid;\n position: relative;\n border-radius: 1rem;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n opacity: 0;\n transform: translateY(20px);\n transition: opacity 0.5s ease-out, transform 0.5s ease-out, box-shadow 0.3s ease;\n}\n\n.masonryItem.visible {\n opacity: 1;\n transform: translateY(0);\n}\n\n.masonryItem:hover {\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);\n}\n\n.imageContainer {\n position: relative;\n width: 100%;\n overflow: hidden;\n border-radius: 1rem;\n}\n\n.galleryImage {\n width: 100%;\n height: auto;\n object-fit: cover;\n display: block;\n transition: transform 0.5s ease-out;\n}\n\n.masonryItem:hover .galleryImage {\n transform: scale(1.05);\n}\n\n.imageOverlay {\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0);\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n.masonryItem:hover .imageOverlay {\n background: rgba(0, 0, 0, 0.1);\n}\n\n/* Column count via CSS custom property */\n.cols1 { columns: 1; }\n.cols2 { columns: 2; }\n.cols3 { columns: 3; }\n.cols4 { columns: 4; }\n.cols5 { columns: 5; }\n\n/* Responsive overrides */\n@media (max-width: 1280px) {\n .cols4, .cols5 { columns: 3; }\n}\n\n@media (max-width: 768px) {\n .cols3, .cols4, .cols5 { columns: 2; }\n}\n\n@media (max-width: 640px) {\n .cols2, .cols3, .cols4, .cols5 { columns: 1; }\n}\n"],"mappings":"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","names":["XMicroGalleryText_default","useEffect","useRef","Image","jsx","jsxs","useRef","useEffect","Image"]}
@@ -0,0 +1,186 @@
1
+ // src/components/layout/xfooter/XFooter.tsx
2
+ import Link from "next/link";
3
+
4
+ // src/components/layout/xfooter/XFooter.module.css
5
+ var XFooter_default = {};
6
+
7
+ // src/components/layout/xfooter/XFooter.tsx
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function XFooter({
10
+ links,
11
+ copyright,
12
+ layout = "horizontal",
13
+ columns = 1,
14
+ colors,
15
+ className = ""
16
+ }) {
17
+ const customStyles = {
18
+ "--xf-bg": colors?.bg,
19
+ "--xf-text": colors?.text,
20
+ "--xf-accent": colors?.accent,
21
+ "--xf-border": colors?.border,
22
+ "--xf-cols": layout === "horizontal" ? columns : 1
23
+ };
24
+ const currentYear = copyright?.customYear || (/* @__PURE__ */ new Date()).getFullYear();
25
+ const copyLabel = copyright?.text || "Xscriptor";
26
+ return /* @__PURE__ */ jsx("footer", { className: `${XFooter_default.XFooter} ${className}`, style: customStyles, children: /* @__PURE__ */ jsxs("div", { className: XFooter_default.container, children: [
27
+ /* @__PURE__ */ jsx("nav", { className: layout === "vertical" ? XFooter_default.navVertical : XFooter_default.nav, children: links.map((link, idx) => /* @__PURE__ */ jsx(Link, { href: link.href, className: XFooter_default.link, children: link.label }, idx)) }),
28
+ /* @__PURE__ */ jsxs("div", { className: XFooter_default.copyright, children: [
29
+ "\xA9 ",
30
+ copyright?.yearFirst ? `${currentYear} ${copyLabel}` : `${copyLabel} ${currentYear}`
31
+ ] })
32
+ ] }) });
33
+ }
34
+
35
+ // src/components/layout/xseparator/XSeparator.module.css
36
+ var XSeparator_default = {};
37
+
38
+ // src/components/layout/xseparator/XSeparator.tsx
39
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
40
+ function XSeparator({
41
+ orientation = "horizontal",
42
+ variant = "solid",
43
+ isFaded = false,
44
+ hasX = false,
45
+ xColor,
46
+ xBg = "white",
47
+ thickness = "1px",
48
+ color = "#e2e8f0",
49
+ gap = "1rem",
50
+ className = ""
51
+ }) {
52
+ const dynamicStyles = {
53
+ "--separator-color": color,
54
+ "--separator-thickness": thickness,
55
+ "--separator-margin": gap,
56
+ "--x-color": xColor || color,
57
+ // Si no se define xColor, usa el color de la línea
58
+ "--x-bg": xBg
59
+ };
60
+ const classes = [
61
+ XSeparator_default.separator,
62
+ orientation === "vertical" ? XSeparator_default.vertical : XSeparator_default.horizontal,
63
+ variant !== "solid" && XSeparator_default[variant],
64
+ isFaded && XSeparator_default.faded
65
+ ].filter(Boolean).join(" ");
66
+ const line = /* @__PURE__ */ jsx2("hr", { className: classes, style: dynamicStyles });
67
+ if (!hasX) return line;
68
+ return /* @__PURE__ */ jsxs2("div", { className: `${XSeparator_default.separatorContainer} ${className}`, style: dynamicStyles, children: [
69
+ line,
70
+ /* @__PURE__ */ jsx2("div", { className: XSeparator_default.iconWrapper, children: "\u2715" })
71
+ ] });
72
+ }
73
+
74
+ // src/components/layout/xzigzaglayout/XZigZagLayout.tsx
75
+ import { Children, useEffect, useRef, useState, useCallback } from "react";
76
+
77
+ // src/components/layout/xzigzaglayout/XZigZagLayout.module.css
78
+ var XZigZagLayout_default = {};
79
+
80
+ // src/components/layout/xzigzaglayout/XZigZagLayout.tsx
81
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
82
+ function XZigZagLayout({
83
+ children,
84
+ className,
85
+ style,
86
+ startSide = "left",
87
+ gap,
88
+ offset,
89
+ textAlign = "inherit",
90
+ showLine = false,
91
+ lineColor = "#cccccc",
92
+ lineThickness = 2,
93
+ ...rest
94
+ }) {
95
+ const items = Children.toArray(children).filter(Boolean);
96
+ const containerRef = useRef(null);
97
+ const itemsRef = useRef([]);
98
+ const pathRef = useRef(null);
99
+ const [points, setPoints] = useState([]);
100
+ const [pathLength, setPathLength] = useState(0);
101
+ const [drawProgress, setDrawProgress] = useState(0);
102
+ const calculatePoints = useCallback(() => {
103
+ if (!containerRef.current) return;
104
+ const containerRect = containerRef.current.getBoundingClientRect();
105
+ const newPoints = itemsRef.current.filter(Boolean).map((el) => {
106
+ const rect = el.getBoundingClientRect();
107
+ return {
108
+ x: rect.left + rect.width / 2 - containerRect.left,
109
+ y: rect.top + rect.height / 2 - containerRect.top
110
+ };
111
+ });
112
+ if (newPoints.length > 0) {
113
+ newPoints.unshift({ x: newPoints[0].x, y: 0 });
114
+ newPoints.push({ x: newPoints[newPoints.length - 1].x, y: containerRect.height });
115
+ }
116
+ setPoints(newPoints);
117
+ }, []);
118
+ useEffect(() => {
119
+ if (!showLine || !containerRef.current) return;
120
+ const observer = new ResizeObserver(() => calculatePoints());
121
+ observer.observe(containerRef.current);
122
+ calculatePoints();
123
+ return () => observer.disconnect();
124
+ }, [showLine, calculatePoints]);
125
+ useEffect(() => {
126
+ if (pathRef.current) setPathLength(pathRef.current.getTotalLength());
127
+ }, [points]);
128
+ useEffect(() => {
129
+ if (!showLine) return;
130
+ const handleScroll = () => {
131
+ if (!containerRef.current) return;
132
+ const { top, height } = containerRef.current.getBoundingClientRect();
133
+ const windowHeight = window.innerHeight;
134
+ const start = windowHeight / 2;
135
+ const progress = (start - top) / height;
136
+ setDrawProgress(Math.min(Math.max(progress, 0), 1));
137
+ };
138
+ window.addEventListener("scroll", handleScroll);
139
+ handleScroll();
140
+ return () => window.removeEventListener("scroll", handleScroll);
141
+ }, [showLine]);
142
+ const cssVars = {};
143
+ if (gap !== void 0) cssVars["--x-zigzag-gap"] = typeof gap === "number" ? `${gap}px` : gap;
144
+ if (offset !== void 0) cssVars["--x-zigzag-offset"] = typeof offset === "number" ? `${offset}px` : offset;
145
+ const mergedStyle = { ...style, ...cssVars };
146
+ const pathD = points.length > 0 ? `M ${points[0].x} ${points[0].y} ` + points.slice(1).map((p) => `L ${p.x} ${p.y}`).join(" ") : "";
147
+ return /* @__PURE__ */ jsxs3(
148
+ "div",
149
+ {
150
+ ref: containerRef,
151
+ ...rest,
152
+ className: [XZigZagLayout_default.layout, className].filter(Boolean).join(" "),
153
+ style: mergedStyle,
154
+ children: [
155
+ showLine && points.length > 0 && /* @__PURE__ */ jsx3("svg", { className: XZigZagLayout_default.svgLine, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx3(
156
+ "path",
157
+ {
158
+ ref: pathRef,
159
+ d: pathD,
160
+ fill: "none",
161
+ stroke: lineColor,
162
+ strokeWidth: lineThickness,
163
+ strokeDasharray: pathLength,
164
+ strokeDashoffset: pathLength - pathLength * drawProgress,
165
+ style: { transition: "stroke-dashoffset 0.1s ease-out" }
166
+ }
167
+ ) }),
168
+ items.map((child, index) => {
169
+ const isStartLeft = startSide === "left";
170
+ const alignLeft = isStartLeft ? index % 2 === 0 : index % 2 !== 0;
171
+ const alignmentClass = textAlign === "side" ? alignLeft ? XZigZagLayout_default.textLeft : XZigZagLayout_default.textRight : textAlign === "left" ? XZigZagLayout_default.textLeft : textAlign === "right" ? XZigZagLayout_default.textRight : "";
172
+ return /* @__PURE__ */ jsx3("div", { className: `${XZigZagLayout_default.item} ${alignLeft ? XZigZagLayout_default.left : XZigZagLayout_default.right} ${alignmentClass}`, children: /* @__PURE__ */ jsx3("div", { ref: (el) => {
173
+ itemsRef.current[index] = el;
174
+ }, className: XZigZagLayout_default.contentWrapper, children: child }) }, index);
175
+ })
176
+ ]
177
+ }
178
+ );
179
+ }
180
+
181
+ export {
182
+ XFooter,
183
+ XSeparator,
184
+ XZigZagLayout
185
+ };
186
+ //# sourceMappingURL=chunk-42XPBYTL.mjs.map