@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.
- package/CODE_OF_CONDUCT.md +35 -0
- package/CONTRIBUTING.md +64 -0
- package/LICENSE +21 -0
- package/README.md +127 -0
- package/SECURITY.md +25 -0
- package/dist/chunk-2OAXRRVQ.mjs +150 -0
- package/dist/chunk-2OAXRRVQ.mjs.map +1 -0
- package/dist/chunk-42XPBYTL.mjs +186 -0
- package/dist/chunk-42XPBYTL.mjs.map +1 -0
- package/dist/chunk-5G4P2E76.mjs +66 -0
- package/dist/chunk-5G4P2E76.mjs.map +1 -0
- package/dist/chunk-FZRTAML3.mjs +1 -0
- package/dist/chunk-FZRTAML3.mjs.map +1 -0
- package/dist/chunk-NY22GB3E.mjs +311 -0
- package/dist/chunk-NY22GB3E.mjs.map +1 -0
- package/dist/chunk-QCMWPIG7.mjs +320 -0
- package/dist/chunk-QCMWPIG7.mjs.map +1 -0
- package/dist/chunk-U27ZVCP7.mjs +247 -0
- package/dist/chunk-U27ZVCP7.mjs.map +1 -0
- package/dist/components/content/index.css +132 -0
- package/dist/components/content/index.css.map +1 -0
- package/dist/components/content/index.d.mts +17 -0
- package/dist/components/content/index.d.ts +17 -0
- package/dist/components/content/index.js +102 -0
- package/dist/components/content/index.js.map +1 -0
- package/dist/components/content/index.mjs +7 -0
- package/dist/components/content/index.mjs.map +1 -0
- package/dist/components/forms/index.css +307 -0
- package/dist/components/forms/index.css.map +1 -0
- package/dist/components/forms/index.d.mts +68 -0
- package/dist/components/forms/index.d.ts +68 -0
- package/dist/components/forms/index.js +357 -0
- package/dist/components/forms/index.js.map +1 -0
- package/dist/components/forms/index.mjs +9 -0
- package/dist/components/forms/index.mjs.map +1 -0
- package/dist/components/gallery/index.css +229 -0
- package/dist/components/gallery/index.css.map +1 -0
- package/dist/components/gallery/index.d.mts +29 -0
- package/dist/components/gallery/index.d.ts +29 -0
- package/dist/components/gallery/index.js +187 -0
- package/dist/components/gallery/index.js.map +1 -0
- package/dist/components/gallery/index.mjs +9 -0
- package/dist/components/gallery/index.mjs.map +1 -0
- package/dist/components/index.css +1181 -0
- package/dist/components/index.css.map +1 -0
- package/dist/components/index.d.mts +8 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +1317 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +50 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/components/layout/index.css +168 -0
- package/dist/components/layout/index.css.map +1 -0
- package/dist/components/layout/index.d.mts +55 -0
- package/dist/components/layout/index.d.ts +55 -0
- package/dist/components/layout/index.js +224 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/layout/index.mjs +11 -0
- package/dist/components/layout/index.mjs.map +1 -0
- package/dist/components/navigation/index.css +229 -0
- package/dist/components/navigation/index.css.map +1 -0
- package/dist/components/navigation/index.d.mts +76 -0
- package/dist/components/navigation/index.d.ts +76 -0
- package/dist/components/navigation/index.js +347 -0
- package/dist/components/navigation/index.js.map +1 -0
- package/dist/components/navigation/index.mjs +7 -0
- package/dist/components/navigation/index.mjs.map +1 -0
- package/dist/components/social/index.css +116 -0
- package/dist/components/social/index.css.map +1 -0
- package/dist/components/social/index.d.mts +55 -0
- package/dist/components/social/index.d.ts +55 -0
- package/dist/components/social/index.js +280 -0
- package/dist/components/social/index.js.map +1 -0
- package/dist/components/social/index.mjs +21 -0
- package/dist/components/social/index.mjs.map +1 -0
- package/dist/index.css +1181 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1317 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +50 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React, { HTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
type XFooterLink = {
|
|
5
|
+
label: string;
|
|
6
|
+
href: string;
|
|
7
|
+
};
|
|
8
|
+
type CopyrightConfig = {
|
|
9
|
+
text?: string;
|
|
10
|
+
showYear?: boolean;
|
|
11
|
+
customYear?: number | string;
|
|
12
|
+
yearFirst?: boolean;
|
|
13
|
+
};
|
|
14
|
+
type XFooterProps = {
|
|
15
|
+
links: XFooterLink[];
|
|
16
|
+
copyright?: CopyrightConfig;
|
|
17
|
+
layout?: "horizontal" | "vertical";
|
|
18
|
+
columns?: 1 | 2 | 3 | 4;
|
|
19
|
+
colors?: {
|
|
20
|
+
bg?: string;
|
|
21
|
+
text?: string;
|
|
22
|
+
accent?: string;
|
|
23
|
+
border?: string;
|
|
24
|
+
};
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
declare function XFooter({ links, copyright, layout, columns, colors, className, }: XFooterProps): react_jsx_runtime.JSX.Element;
|
|
28
|
+
|
|
29
|
+
interface XSeparatorProps {
|
|
30
|
+
orientation?: 'horizontal' | 'vertical';
|
|
31
|
+
variant?: 'solid' | 'dashed' | 'dotted';
|
|
32
|
+
isFaded?: boolean;
|
|
33
|
+
hasX?: boolean;
|
|
34
|
+
xColor?: string;
|
|
35
|
+
xBg?: string;
|
|
36
|
+
thickness?: string;
|
|
37
|
+
color?: string;
|
|
38
|
+
gap?: string;
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
declare function XSeparator({ orientation, variant, isFaded, hasX, xColor, xBg, thickness, color, gap, className }: XSeparatorProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
|
|
43
|
+
type XZigZagLayoutProps = HTMLAttributes<HTMLDivElement> & {
|
|
44
|
+
children: React.ReactNode;
|
|
45
|
+
startSide?: "left" | "right";
|
|
46
|
+
gap?: number | string;
|
|
47
|
+
offset?: number | string;
|
|
48
|
+
textAlign?: "inherit" | "side" | "left" | "right";
|
|
49
|
+
showLine?: boolean;
|
|
50
|
+
lineColor?: string;
|
|
51
|
+
lineThickness?: number | string;
|
|
52
|
+
};
|
|
53
|
+
declare function XZigZagLayout({ children, className, style, startSide, gap, offset, textAlign, showLine, lineColor, lineThickness, ...rest }: XZigZagLayoutProps): react_jsx_runtime.JSX.Element;
|
|
54
|
+
|
|
55
|
+
export { type CopyrightConfig, XFooter, type XFooterLink, type XFooterProps, XSeparator, type XSeparatorProps, XZigZagLayout, type XZigZagLayoutProps };
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/components/layout/index.ts
|
|
31
|
+
var layout_exports = {};
|
|
32
|
+
__export(layout_exports, {
|
|
33
|
+
XFooter: () => XFooter,
|
|
34
|
+
XSeparator: () => XSeparator,
|
|
35
|
+
XZigZagLayout: () => XZigZagLayout
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(layout_exports);
|
|
38
|
+
|
|
39
|
+
// src/components/layout/xfooter/XFooter.tsx
|
|
40
|
+
var import_link = __toESM(require("next/link"));
|
|
41
|
+
|
|
42
|
+
// src/components/layout/xfooter/XFooter.module.css
|
|
43
|
+
var XFooter_default = {};
|
|
44
|
+
|
|
45
|
+
// src/components/layout/xfooter/XFooter.tsx
|
|
46
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
47
|
+
function XFooter({
|
|
48
|
+
links,
|
|
49
|
+
copyright,
|
|
50
|
+
layout = "horizontal",
|
|
51
|
+
columns = 1,
|
|
52
|
+
colors,
|
|
53
|
+
className = ""
|
|
54
|
+
}) {
|
|
55
|
+
const customStyles = {
|
|
56
|
+
"--xf-bg": colors?.bg,
|
|
57
|
+
"--xf-text": colors?.text,
|
|
58
|
+
"--xf-accent": colors?.accent,
|
|
59
|
+
"--xf-border": colors?.border,
|
|
60
|
+
"--xf-cols": layout === "horizontal" ? columns : 1
|
|
61
|
+
};
|
|
62
|
+
const currentYear = copyright?.customYear || (/* @__PURE__ */ new Date()).getFullYear();
|
|
63
|
+
const copyLabel = copyright?.text || "Xscriptor";
|
|
64
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("footer", { className: `${XFooter_default.XFooter} ${className}`, style: customStyles, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: XFooter_default.container, children: [
|
|
65
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: layout === "vertical" ? XFooter_default.navVertical : XFooter_default.nav, children: links.map((link, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: link.href, className: XFooter_default.link, children: link.label }, idx)) }),
|
|
66
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: XFooter_default.copyright, children: [
|
|
67
|
+
"\xA9 ",
|
|
68
|
+
copyright?.yearFirst ? `${currentYear} ${copyLabel}` : `${copyLabel} ${currentYear}`
|
|
69
|
+
] })
|
|
70
|
+
] }) });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/components/layout/xseparator/XSeparator.module.css
|
|
74
|
+
var XSeparator_default = {};
|
|
75
|
+
|
|
76
|
+
// src/components/layout/xseparator/XSeparator.tsx
|
|
77
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
78
|
+
function XSeparator({
|
|
79
|
+
orientation = "horizontal",
|
|
80
|
+
variant = "solid",
|
|
81
|
+
isFaded = false,
|
|
82
|
+
hasX = false,
|
|
83
|
+
xColor,
|
|
84
|
+
xBg = "white",
|
|
85
|
+
thickness = "1px",
|
|
86
|
+
color = "#e2e8f0",
|
|
87
|
+
gap = "1rem",
|
|
88
|
+
className = ""
|
|
89
|
+
}) {
|
|
90
|
+
const dynamicStyles = {
|
|
91
|
+
"--separator-color": color,
|
|
92
|
+
"--separator-thickness": thickness,
|
|
93
|
+
"--separator-margin": gap,
|
|
94
|
+
"--x-color": xColor || color,
|
|
95
|
+
// Si no se define xColor, usa el color de la línea
|
|
96
|
+
"--x-bg": xBg
|
|
97
|
+
};
|
|
98
|
+
const classes = [
|
|
99
|
+
XSeparator_default.separator,
|
|
100
|
+
orientation === "vertical" ? XSeparator_default.vertical : XSeparator_default.horizontal,
|
|
101
|
+
variant !== "solid" && XSeparator_default[variant],
|
|
102
|
+
isFaded && XSeparator_default.faded
|
|
103
|
+
].filter(Boolean).join(" ");
|
|
104
|
+
const line = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("hr", { className: classes, style: dynamicStyles });
|
|
105
|
+
if (!hasX) return line;
|
|
106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `${XSeparator_default.separatorContainer} ${className}`, style: dynamicStyles, children: [
|
|
107
|
+
line,
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: XSeparator_default.iconWrapper, children: "\u2715" })
|
|
109
|
+
] });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/components/layout/xzigzaglayout/XZigZagLayout.tsx
|
|
113
|
+
var import_react = require("react");
|
|
114
|
+
|
|
115
|
+
// src/components/layout/xzigzaglayout/XZigZagLayout.module.css
|
|
116
|
+
var XZigZagLayout_default = {};
|
|
117
|
+
|
|
118
|
+
// src/components/layout/xzigzaglayout/XZigZagLayout.tsx
|
|
119
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
120
|
+
function XZigZagLayout({
|
|
121
|
+
children,
|
|
122
|
+
className,
|
|
123
|
+
style,
|
|
124
|
+
startSide = "left",
|
|
125
|
+
gap,
|
|
126
|
+
offset,
|
|
127
|
+
textAlign = "inherit",
|
|
128
|
+
showLine = false,
|
|
129
|
+
lineColor = "#cccccc",
|
|
130
|
+
lineThickness = 2,
|
|
131
|
+
...rest
|
|
132
|
+
}) {
|
|
133
|
+
const items = import_react.Children.toArray(children).filter(Boolean);
|
|
134
|
+
const containerRef = (0, import_react.useRef)(null);
|
|
135
|
+
const itemsRef = (0, import_react.useRef)([]);
|
|
136
|
+
const pathRef = (0, import_react.useRef)(null);
|
|
137
|
+
const [points, setPoints] = (0, import_react.useState)([]);
|
|
138
|
+
const [pathLength, setPathLength] = (0, import_react.useState)(0);
|
|
139
|
+
const [drawProgress, setDrawProgress] = (0, import_react.useState)(0);
|
|
140
|
+
const calculatePoints = (0, import_react.useCallback)(() => {
|
|
141
|
+
if (!containerRef.current) return;
|
|
142
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
143
|
+
const newPoints = itemsRef.current.filter(Boolean).map((el) => {
|
|
144
|
+
const rect = el.getBoundingClientRect();
|
|
145
|
+
return {
|
|
146
|
+
x: rect.left + rect.width / 2 - containerRect.left,
|
|
147
|
+
y: rect.top + rect.height / 2 - containerRect.top
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
if (newPoints.length > 0) {
|
|
151
|
+
newPoints.unshift({ x: newPoints[0].x, y: 0 });
|
|
152
|
+
newPoints.push({ x: newPoints[newPoints.length - 1].x, y: containerRect.height });
|
|
153
|
+
}
|
|
154
|
+
setPoints(newPoints);
|
|
155
|
+
}, []);
|
|
156
|
+
(0, import_react.useEffect)(() => {
|
|
157
|
+
if (!showLine || !containerRef.current) return;
|
|
158
|
+
const observer = new ResizeObserver(() => calculatePoints());
|
|
159
|
+
observer.observe(containerRef.current);
|
|
160
|
+
calculatePoints();
|
|
161
|
+
return () => observer.disconnect();
|
|
162
|
+
}, [showLine, calculatePoints]);
|
|
163
|
+
(0, import_react.useEffect)(() => {
|
|
164
|
+
if (pathRef.current) setPathLength(pathRef.current.getTotalLength());
|
|
165
|
+
}, [points]);
|
|
166
|
+
(0, import_react.useEffect)(() => {
|
|
167
|
+
if (!showLine) return;
|
|
168
|
+
const handleScroll = () => {
|
|
169
|
+
if (!containerRef.current) return;
|
|
170
|
+
const { top, height } = containerRef.current.getBoundingClientRect();
|
|
171
|
+
const windowHeight = window.innerHeight;
|
|
172
|
+
const start = windowHeight / 2;
|
|
173
|
+
const progress = (start - top) / height;
|
|
174
|
+
setDrawProgress(Math.min(Math.max(progress, 0), 1));
|
|
175
|
+
};
|
|
176
|
+
window.addEventListener("scroll", handleScroll);
|
|
177
|
+
handleScroll();
|
|
178
|
+
return () => window.removeEventListener("scroll", handleScroll);
|
|
179
|
+
}, [showLine]);
|
|
180
|
+
const cssVars = {};
|
|
181
|
+
if (gap !== void 0) cssVars["--x-zigzag-gap"] = typeof gap === "number" ? `${gap}px` : gap;
|
|
182
|
+
if (offset !== void 0) cssVars["--x-zigzag-offset"] = typeof offset === "number" ? `${offset}px` : offset;
|
|
183
|
+
const mergedStyle = { ...style, ...cssVars };
|
|
184
|
+
const pathD = points.length > 0 ? `M ${points[0].x} ${points[0].y} ` + points.slice(1).map((p) => `L ${p.x} ${p.y}`).join(" ") : "";
|
|
185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
186
|
+
"div",
|
|
187
|
+
{
|
|
188
|
+
ref: containerRef,
|
|
189
|
+
...rest,
|
|
190
|
+
className: [XZigZagLayout_default.layout, className].filter(Boolean).join(" "),
|
|
191
|
+
style: mergedStyle,
|
|
192
|
+
children: [
|
|
193
|
+
showLine && points.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: XZigZagLayout_default.svgLine, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
194
|
+
"path",
|
|
195
|
+
{
|
|
196
|
+
ref: pathRef,
|
|
197
|
+
d: pathD,
|
|
198
|
+
fill: "none",
|
|
199
|
+
stroke: lineColor,
|
|
200
|
+
strokeWidth: lineThickness,
|
|
201
|
+
strokeDasharray: pathLength,
|
|
202
|
+
strokeDashoffset: pathLength - pathLength * drawProgress,
|
|
203
|
+
style: { transition: "stroke-dashoffset 0.1s ease-out" }
|
|
204
|
+
}
|
|
205
|
+
) }),
|
|
206
|
+
items.map((child, index) => {
|
|
207
|
+
const isStartLeft = startSide === "left";
|
|
208
|
+
const alignLeft = isStartLeft ? index % 2 === 0 : index % 2 !== 0;
|
|
209
|
+
const alignmentClass = textAlign === "side" ? alignLeft ? XZigZagLayout_default.textLeft : XZigZagLayout_default.textRight : textAlign === "left" ? XZigZagLayout_default.textLeft : textAlign === "right" ? XZigZagLayout_default.textRight : "";
|
|
210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `${XZigZagLayout_default.item} ${alignLeft ? XZigZagLayout_default.left : XZigZagLayout_default.right} ${alignmentClass}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: (el) => {
|
|
211
|
+
itemsRef.current[index] = el;
|
|
212
|
+
}, className: XZigZagLayout_default.contentWrapper, children: child }) }, index);
|
|
213
|
+
})
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
219
|
+
0 && (module.exports = {
|
|
220
|
+
XFooter,
|
|
221
|
+
XSeparator,
|
|
222
|
+
XZigZagLayout
|
|
223
|
+
});
|
|
224
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/index.ts","../../../src/components/layout/xfooter/XFooter.tsx","../../../src/components/layout/xfooter/XFooter.module.css","../../../src/components/layout/xseparator/XSeparator.module.css","../../../src/components/layout/xseparator/XSeparator.tsx","../../../src/components/layout/xzigzaglayout/XZigZagLayout.tsx","../../../src/components/layout/xzigzaglayout/XZigZagLayout.module.css"],"sourcesContent":["export { XFooter } from \"./xfooter\";\nexport { XSeparator } from \"./xseparator\";\nexport { XZigZagLayout } from \"./xzigzaglayout\";\nexport type { XFooterProps, XFooterLink, CopyrightConfig } from \"./xfooter\";\nexport type { XSeparatorProps } from \"./xseparator\";\nexport type { XZigZagLayoutProps } from \"./xzigzaglayout\";\n","import Link from \"next/link\";\nimport { CSSProperties } from \"react\";\nimport styles from \"./XFooter.module.css\";\n\nexport type XFooterLink = {\n label: string;\n href: string;\n};\n\nexport type CopyrightConfig = {\n text?: string;\n showYear?: boolean;\n customYear?: number | string;\n yearFirst?: boolean;\n};\n\nexport type XFooterProps = {\n links: XFooterLink[];\n copyright?: CopyrightConfig; \n layout?: \"horizontal\" | \"vertical\";\n columns?: 1 | 2 | 3 | 4;\n colors?: {\n bg?: string;\n text?: string;\n accent?: string;\n border?: string;\n };\n className?: string;\n};\nexport default function XFooter({\n links,\n copyright,\n layout = \"horizontal\",\n columns = 1,\n colors,\n className = \"\",\n}: XFooterProps) {\n \n const customStyles = {\n \"--xf-bg\": colors?.bg,\n \"--xf-text\": colors?.text,\n \"--xf-accent\": colors?.accent,\n \"--xf-border\": colors?.border,\n \"--xf-cols\": layout === \"horizontal\" ? columns : 1,\n } as CSSProperties;\n\n const currentYear = copyright?.customYear || new Date().getFullYear();\n const copyLabel = copyright?.text || \"Xscriptor\";\n\n return (\n <footer className={`${styles.XFooter} ${className}`} style={customStyles}>\n <div className={styles.container}>\n {/* Los links se organizan en el grid definido por --xf-cols */}\n <nav className={layout === \"vertical\" ? styles.navVertical : styles.nav}>\n {links.map((link, idx) => (\n <Link key={idx} href={link.href} className={styles.link}>\n {link.label}\n </Link>\n ))}\n </nav>\n\n {/* El copyright queda fuera del nav, por lo que hereda el centrado del container */}\n <div className={styles.copyright}>\n © {copyright?.yearFirst \n ? `${currentYear} ${copyLabel}` \n : `${copyLabel} ${currentYear}`}\n </div>\n </div>\n </footer>\n );\n}",".XFooter {\n width: 100%;\n background-color: var(--xf-bg, transparent);\n color: var(--xf-text, #333);\n padding: var(--xf-py, 0.9rem) 0.6rem;\n}\n\n.container {\n max-width: 1280px;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.6rem; /* Espacio entre los links y el copyright */\n}\n\n/* El nav es el que maneja las columnas de los links */\n.nav {\n display: grid;\n gap: 0.5rem 1.5rem; \n grid-template-columns: repeat(var(--xf-cols, 1), minmax(0, auto));\n justify-content: center;\n text-align: center;\n width: 100%;\n}\n\n.navVertical {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.75rem;\n}\n\n.link {\n color: var(--xf-accent, inherit);\n text-decoration: none;\n font-size: 0.9rem;\n transition: opacity 0.2s;\n white-space: nowrap; /* Evita que los links se rompan en dos líneas */\n}\n\n.link:hover {\n opacity: 0.7;\n}\n\n/* El copyright siempre irá al final y centrado por el flex del .container */\n.copyright {\n font-size: 0.75rem;\n opacity: 0.6;\n width: 100%;\n text-align: center;\n}",".separatorContainer {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n /* Variables para la X con fallbacks */\n --x-color: var(--separator-color); \n --x-bg: white;\n}\n\n.iconWrapper {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n background-color: var(--x-bg);\n padding: 0 10px;\n \n /* Aplicamos el color dinámico */\n color: var(--x-color);\n \n font-family: system-ui, sans-serif;\n font-weight: bold;\n font-size: 1.2rem;\n line-height: 1;\n user-select: none;\n}\n\n.separator {\n --separator-color: #e2e8f0;\n --separator-thickness: 1px;\n --separator-margin: 1rem;\n \n border: 0;\n background-color: var(--separator-color);\n}\n\n/* Variantes de Estilo */\n.dashed {\n background-color: transparent !important;\n border-bottom: var(--separator-thickness) dashed var(--separator-color);\n}\n\n.dotted {\n background-color: transparent !important;\n border-bottom: var(--separator-thickness) dotted var(--separator-color);\n}\n\n/* Efecto Desvanecido (Fading) */\n/* Usamos mask-image para que funcione con cualquier color de fondo */\n.faded {\n mask-image: linear-gradient(\n to right, \n transparent, \n black 20%, \n black 80%, \n transparent\n );\n}\n\n/* Ajuste para desvanecido vertical */\n.vertical.faded {\n mask-image: linear-gradient(\n to bottom, \n transparent, \n black 20%, \n black 80%, \n transparent\n );\n}\n\n.horizontal {\n width: 100%;\n height: var(--separator-thickness);\n margin: var(--separator-margin) 0;\n}\n\n.vertical {\n width: var(--separator-thickness);\n height: 100%;\n display: inline-block;\n margin: 0 var(--separator-margin);\n vertical-align: middle;\n}","import React from 'react';\nimport styles from './XSeparator.module.css';\n\nexport interface XSeparatorProps {\n orientation?: 'horizontal' | 'vertical';\n variant?: 'solid' | 'dashed' | 'dotted';\n isFaded?: boolean;\n hasX?: boolean;\n xColor?: string; // Nuevo: Color de la X\n xBg?: string; // Nuevo: Fondo detrás de la X (para el recorte)\n thickness?: string;\n color?: string;\n gap?: string;\n className?: string;\n}\n\nexport default function XSeparator({\n orientation = 'horizontal',\n variant = 'solid',\n isFaded = false,\n hasX = false,\n xColor, \n xBg = 'white',\n thickness = '1px',\n color = '#e2e8f0',\n gap = '1rem',\n className = ''\n}: XSeparatorProps) {\n \n const dynamicStyles = {\n '--separator-color': color,\n '--separator-thickness': thickness,\n '--separator-margin': gap,\n '--x-color': xColor || color, // Si no se define xColor, usa el color de la línea\n '--x-bg': xBg,\n } as React.CSSProperties;\n\n const classes = [\n styles.separator,\n orientation === 'vertical' ? styles.vertical : styles.horizontal,\n variant !== 'solid' && styles[variant],\n isFaded && styles.faded,\n ].filter(Boolean).join(' ');\n\n const line = <hr className={classes} style={dynamicStyles} />;\n\n if (!hasX) return line;\n\n return (\n <div className={`${styles.separatorContainer} ${className}`} style={dynamicStyles}>\n {line}\n <div className={styles.iconWrapper}>\n ✕\n </div>\n </div>\n );\n}","import React, { Children, HTMLAttributes, useEffect, useRef, useState, useCallback } from \"react\";\nimport styles from \"./XZigZagLayout.module.css\";\n\nexport type XZigZagLayoutProps = HTMLAttributes<HTMLDivElement> & {\n children: React.ReactNode;\n startSide?: \"left\" | \"right\";\n gap?: number | string;\n offset?: number | string;\n textAlign?: \"inherit\" | \"side\" | \"left\" | \"right\";\n showLine?: boolean;\n lineColor?: string;\n lineThickness?: number | string;\n};\n\nexport default function XZigZagLayout({\n children,\n className,\n style,\n startSide = \"left\",\n gap,\n offset,\n textAlign = \"inherit\",\n showLine = false,\n lineColor = \"#cccccc\",\n lineThickness = 2,\n ...rest\n}: XZigZagLayoutProps) {\n const items = Children.toArray(children).filter(Boolean);\n const containerRef = useRef<HTMLDivElement>(null);\n const itemsRef = useRef<(HTMLDivElement | null)[]>([]);\n const pathRef = useRef<SVGPathElement>(null);\n\n const [points, setPoints] = useState<{ x: number; y: number }[]>([]);\n const [pathLength, setPathLength] = useState(0);\n const [drawProgress, setDrawProgress] = useState(0);\n\n // Calcula el centro de cada elemento para dibujar los puntos\n const calculatePoints = useCallback(() => {\n if (!containerRef.current) return;\n const containerRect = containerRef.current.getBoundingClientRect();\n\n const newPoints = itemsRef.current.filter(Boolean).map((el) => {\n const rect = el!.getBoundingClientRect();\n return {\n x: rect.left + rect.width / 2 - containerRect.left,\n y: rect.top + rect.height / 2 - containerRect.top,\n };\n });\n\n if (newPoints.length > 0) {\n newPoints.unshift({ x: newPoints[0].x, y: 0 }); // Inicia arriba\n newPoints.push({ x: newPoints[newPoints.length - 1].x, y: containerRect.height }); // Termina abajo\n }\n\n setPoints(newPoints);\n }, []);\n\n useEffect(() => {\n if (!showLine || !containerRef.current) return;\n const observer = new ResizeObserver(() => calculatePoints());\n observer.observe(containerRef.current);\n calculatePoints();\n return () => observer.disconnect();\n }, [showLine, calculatePoints]);\n\n useEffect(() => {\n if (pathRef.current) setPathLength(pathRef.current.getTotalLength());\n }, [points]);\n\n useEffect(() => {\n if (!showLine) return;\n const handleScroll = () => {\n if (!containerRef.current) return;\n const { top, height } = containerRef.current.getBoundingClientRect();\n const windowHeight = window.innerHeight;\n const start = windowHeight / 2;\n const progress = (start - top) / height;\n\n setDrawProgress(Math.min(Math.max(progress, 0), 1));\n };\n\n window.addEventListener(\"scroll\", handleScroll);\n handleScroll();\n return () => window.removeEventListener(\"scroll\", handleScroll);\n }, [showLine]);\n\n const cssVars: Record<string, string> = {};\n if (gap !== undefined) cssVars[\"--x-zigzag-gap\"] = typeof gap === \"number\" ? `${gap}px` : gap;\n if (offset !== undefined) cssVars[\"--x-zigzag-offset\"] = typeof offset === \"number\" ? `${offset}px` : offset;\n\n const mergedStyle: React.CSSProperties = { ...style, ...cssVars };\n\n const pathD = points.length > 0\n ? `M ${points[0].x} ${points[0].y} ` + points.slice(1).map((p) => `L ${p.x} ${p.y}`).join(\" \")\n : \"\";\n\n return (\n <div\n ref={containerRef}\n {...rest}\n className={[styles.layout, className].filter(Boolean).join(\" \")}\n style={mergedStyle}\n >\n {showLine && points.length > 0 && (\n <svg className={styles.svgLine} xmlns=\"http://www.w3.org/2000/svg\">\n <path\n ref={pathRef}\n d={pathD}\n fill=\"none\"\n stroke={lineColor}\n strokeWidth={lineThickness}\n strokeDasharray={pathLength}\n strokeDashoffset={pathLength - pathLength * drawProgress}\n style={{ transition: \"stroke-dashoffset 0.1s ease-out\" }}\n />\n </svg>\n )}\n\n {items.map((child, index) => {\n const isStartLeft = startSide === \"left\";\n const alignLeft = isStartLeft ? index % 2 === 0 : index % 2 !== 0;\n const alignmentClass =\n textAlign === \"side\"\n ? alignLeft ? styles.textLeft : styles.textRight\n : textAlign === \"left\" ? styles.textLeft : textAlign === \"right\" ? styles.textRight : \"\";\n\n return (\n <div key={index} className={`${styles.item} ${alignLeft ? styles.left : styles.right} ${alignmentClass}`}>\n {/* El wrapper interno nos permite medir exactamente dónde queda el contenido */}\n <div ref={(el) => { itemsRef.current[index] = el; }} className={styles.contentWrapper}>\n {child}\n </div>\n </div>\n );\n })}\n </div>\n );\n}",".layout {\n width: min(100%, 72rem);\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: var(--x-zigzag-gap, 0.5rem);\n padding-inline: clamp(0.5rem, 2vw, 1rem);\n position: relative; \n}\n\n/* Nuevos estilos para el SVG de la línea */\n.svgLine {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 0;\n}\n\n.item {\n width: 100%;\n display: grid;\n grid-template-columns: repeat(12, minmax(0, 1fr));\n}\n\n.item > * {\n width: 100%;\n text-align: inherit;\n}\n\n/* Wrapper transparente que envuelve al child */\n.contentWrapper {\n width: 100%;\n}\n\n.textLeft > * {\n text-align: left;\n}\n\n.textRight > * {\n text-align: right;\n}\n\n.left > * {\n grid-column: 2 / 8;\n}\n\n.right > * {\n grid-column: 6 / 12;\n}\n\n@media (max-width: 768px) {\n /* En lugar de ocupar las 12 columnas, los hacemos un poco más angostos para que sus centros se desfasen */\n .left > * {\n grid-column: 1 / 11;\n }\n\n .right > * {\n grid-column: 3 / 13;\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;;;ACAjB;;;ADuDY;AA1BG,SAAR,QAAyB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,UAAU;AAAA,EACV;AAAA,EACA,YAAY;AACd,GAAiB;AAEf,QAAM,eAAe;AAAA,IACnB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,IACrB,eAAe,QAAQ;AAAA,IACvB,eAAe,QAAQ;AAAA,IACvB,aAAa,WAAW,eAAe,UAAU;AAAA,EACnD;AAEA,QAAM,cAAc,WAAW,eAAc,oBAAI,KAAK,GAAE,YAAY;AACpE,QAAM,YAAY,WAAW,QAAQ;AAErC,SACE,4CAAC,YAAO,WAAW,GAAG,gBAAO,OAAO,IAAI,SAAS,IAAI,OAAO,cAC1D,uDAAC,SAAI,WAAW,gBAAO,WAErB;AAAA,gDAAC,SAAI,WAAW,WAAW,aAAa,gBAAO,cAAc,gBAAO,KACjE,gBAAM,IAAI,CAAC,MAAM,QAChB,4CAAC,YAAAA,SAAA,EAAe,MAAM,KAAK,MAAM,WAAW,gBAAO,MAChD,eAAK,SADG,GAEX,CACD,GACH;AAAA,IAGA,6CAAC,SAAI,WAAW,gBAAO,WAAW;AAAA;AAAA,MAC7B,WAAW,YACR,GAAG,WAAW,IAAI,SAAS,KAC3B,GAAG,SAAS,IAAI,WAAW;AAAA,OACnC;AAAA,KACF,GACF;AAEJ;;;AEtEA;;;AC4Ce,IAAAC,sBAAA;AA5BA,SAAR,WAA4B;AAAA,EACjC,cAAc;AAAA,EACd,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AACd,GAAoB;AAElB,QAAM,gBAAgB;AAAA,IACpB,qBAAqB;AAAA,IACrB,yBAAyB;AAAA,IACzB,sBAAsB;AAAA,IACtB,aAAa,UAAU;AAAA;AAAA,IACvB,UAAU;AAAA,EACZ;AAEA,QAAM,UAAU;AAAA,IACd,mBAAO;AAAA,IACP,gBAAgB,aAAa,mBAAO,WAAW,mBAAO;AAAA,IACtD,YAAY,WAAW,mBAAO,OAAO;AAAA,IACrC,WAAW,mBAAO;AAAA,EACpB,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,QAAM,OAAO,6CAAC,QAAG,WAAW,SAAS,OAAO,eAAe;AAE3D,MAAI,CAAC,KAAM,QAAO;AAElB,SACE,8CAAC,SAAI,WAAW,GAAG,mBAAO,kBAAkB,IAAI,SAAS,IAAI,OAAO,eACjE;AAAA;AAAA,IACD,6CAAC,SAAI,WAAW,mBAAO,aAAa,oBAEpC;AAAA,KACF;AAEJ;;;ACxDA,mBAA0F;;;ACA1F;;;ADiGI,IAAAC,sBAAA;AAnFW,SAAR,cAA+B;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,GAAG;AACL,GAAuB;AACrB,QAAM,QAAQ,sBAAS,QAAQ,QAAQ,EAAE,OAAO,OAAO;AACvD,QAAM,mBAAe,qBAAuB,IAAI;AAChD,QAAM,eAAW,qBAAkC,CAAC,CAAC;AACrD,QAAM,cAAU,qBAAuB,IAAI;AAE3C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAqC,CAAC,CAAC;AACnE,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,CAAC;AAC9C,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,CAAC;AAGlD,QAAM,sBAAkB,0BAAY,MAAM;AACxC,QAAI,CAAC,aAAa,QAAS;AAC3B,UAAM,gBAAgB,aAAa,QAAQ,sBAAsB;AAEjE,UAAM,YAAY,SAAS,QAAQ,OAAO,OAAO,EAAE,IAAI,CAAC,OAAO;AAC7D,YAAM,OAAO,GAAI,sBAAsB;AACvC,aAAO;AAAA,QACL,GAAG,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;AAAA,QAC9C,GAAG,KAAK,MAAM,KAAK,SAAS,IAAI,cAAc;AAAA,MAChD;AAAA,IACF,CAAC;AAED,QAAI,UAAU,SAAS,GAAG;AACxB,gBAAU,QAAQ,EAAE,GAAG,UAAU,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC;AAC7C,gBAAU,KAAK,EAAE,GAAG,UAAU,UAAU,SAAS,CAAC,EAAE,GAAG,GAAG,cAAc,OAAO,CAAC;AAAA,IAClF;AAEA,cAAU,SAAS;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,YAAY,CAAC,aAAa,QAAS;AACxC,UAAM,WAAW,IAAI,eAAe,MAAM,gBAAgB,CAAC;AAC3D,aAAS,QAAQ,aAAa,OAAO;AACrC,oBAAgB;AAChB,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,8BAAU,MAAM;AACd,QAAI,QAAQ,QAAS,eAAc,QAAQ,QAAQ,eAAe,CAAC;AAAA,EACrE,GAAG,CAAC,MAAM,CAAC;AAEX,8BAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACf,UAAM,eAAe,MAAM;AACzB,UAAI,CAAC,aAAa,QAAS;AAC3B,YAAM,EAAE,KAAK,OAAO,IAAI,aAAa,QAAQ,sBAAsB;AACnE,YAAM,eAAe,OAAO;AAC5B,YAAM,QAAQ,eAAe;AAC7B,YAAM,YAAY,QAAQ,OAAO;AAEjC,sBAAgB,KAAK,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAAA,IACpD;AAEA,WAAO,iBAAiB,UAAU,YAAY;AAC9C,iBAAa;AACb,WAAO,MAAM,OAAO,oBAAoB,UAAU,YAAY;AAAA,EAChE,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,UAAkC,CAAC;AACzC,MAAI,QAAQ,OAAW,SAAQ,gBAAgB,IAAI,OAAO,QAAQ,WAAW,GAAG,GAAG,OAAO;AAC1F,MAAI,WAAW,OAAW,SAAQ,mBAAmB,IAAI,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAEtG,QAAM,cAAmC,EAAE,GAAG,OAAO,GAAG,QAAQ;AAEhE,QAAM,QAAQ,OAAO,SAAS,IAC1B,KAAK,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,MAAM,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,IAC3F;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACJ,GAAG;AAAA,MACJ,WAAW,CAAC,sBAAO,QAAQ,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC9D,OAAO;AAAA,MAEN;AAAA,oBAAY,OAAO,SAAS,KAC3B,6CAAC,SAAI,WAAW,sBAAO,SAAS,OAAM,8BACpC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,GAAG;AAAA,YACH,MAAK;AAAA,YACL,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,iBAAiB;AAAA,YACjB,kBAAkB,aAAa,aAAa;AAAA,YAC5C,OAAO,EAAE,YAAY,kCAAkC;AAAA;AAAA,QACzD,GACF;AAAA,QAGD,MAAM,IAAI,CAAC,OAAO,UAAU;AAC3B,gBAAM,cAAc,cAAc;AAClC,gBAAM,YAAY,cAAc,QAAQ,MAAM,IAAI,QAAQ,MAAM;AAChE,gBAAM,iBACJ,cAAc,SACV,YAAY,sBAAO,WAAW,sBAAO,YACrC,cAAc,SAAS,sBAAO,WAAW,cAAc,UAAU,sBAAO,YAAY;AAE1F,iBACE,6CAAC,SAAgB,WAAW,GAAG,sBAAO,IAAI,IAAI,YAAY,sBAAO,OAAO,sBAAO,KAAK,IAAI,cAAc,IAEpG,uDAAC,SAAI,KAAK,CAAC,OAAO;AAAE,qBAAS,QAAQ,KAAK,IAAI;AAAA,UAAI,GAAG,WAAW,sBAAO,gBACpE,iBACH,KAJQ,KAKV;AAAA,QAEJ,CAAC;AAAA;AAAA;AAAA,EACH;AAEJ;","names":["Link","import_jsx_runtime","import_jsx_runtime"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/* src/components/navigation/xnavbar/XNavbar.module.css */
|
|
2
|
+
.header {
|
|
3
|
+
height: 100%;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
padding: 2rem 3rem;
|
|
8
|
+
background: var(--bg);
|
|
9
|
+
color: var(--text);
|
|
10
|
+
font-size: 1.25rem;
|
|
11
|
+
z-index: 60;
|
|
12
|
+
}
|
|
13
|
+
@media (min-width: 640px) {
|
|
14
|
+
.header {
|
|
15
|
+
padding-inline: 2rem;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
@media (min-width: 768px) {
|
|
19
|
+
.header {
|
|
20
|
+
padding-inline: 3rem;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
@media (min-width: 1024px) {
|
|
24
|
+
.header {
|
|
25
|
+
padding-inline: 5rem;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
@media (min-width: 1280px) {
|
|
29
|
+
.header {
|
|
30
|
+
padding-inline: 12rem;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.desktopNav {
|
|
34
|
+
display: none;
|
|
35
|
+
align-items: center;
|
|
36
|
+
width: 100%;
|
|
37
|
+
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
38
|
+
padding-bottom: 0.5rem;
|
|
39
|
+
}
|
|
40
|
+
@media (min-width: 768px) {
|
|
41
|
+
.desktopNav {
|
|
42
|
+
display: grid;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.desktopLinksLeft,
|
|
46
|
+
.desktopLinksRight {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: 1.5rem;
|
|
50
|
+
min-width: 0;
|
|
51
|
+
}
|
|
52
|
+
.desktopLinksLeft {
|
|
53
|
+
justify-content: flex-end;
|
|
54
|
+
}
|
|
55
|
+
.desktopLinksRight {
|
|
56
|
+
justify-content: flex-start;
|
|
57
|
+
}
|
|
58
|
+
.logoSlot {
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
.logoWrapper {
|
|
64
|
+
position: relative;
|
|
65
|
+
margin-inline: 1rem;
|
|
66
|
+
display: flex;
|
|
67
|
+
align-items: center;
|
|
68
|
+
}
|
|
69
|
+
.logoBtn {
|
|
70
|
+
font-weight: 700;
|
|
71
|
+
font-size: 1.5rem;
|
|
72
|
+
line-height: 1;
|
|
73
|
+
user-select: none;
|
|
74
|
+
background: none;
|
|
75
|
+
border: none;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
color: var(--text);
|
|
78
|
+
padding: 0;
|
|
79
|
+
}
|
|
80
|
+
.iconTray {
|
|
81
|
+
position: absolute;
|
|
82
|
+
top: 50%;
|
|
83
|
+
transform: translateY(-50%);
|
|
84
|
+
pointer-events: none;
|
|
85
|
+
}
|
|
86
|
+
.iconTrayRight {
|
|
87
|
+
left: 100%;
|
|
88
|
+
padding-left: 0.75rem;
|
|
89
|
+
}
|
|
90
|
+
.iconTrayLeft {
|
|
91
|
+
right: 100%;
|
|
92
|
+
padding-right: 0.75rem;
|
|
93
|
+
}
|
|
94
|
+
.navLink {
|
|
95
|
+
padding: 0.25rem;
|
|
96
|
+
border-bottom: 2px solid transparent;
|
|
97
|
+
transition:
|
|
98
|
+
border-color 0.2s,
|
|
99
|
+
opacity 0.2s,
|
|
100
|
+
color 0.2s;
|
|
101
|
+
color: var(--xnav-link-color, var(--text));
|
|
102
|
+
text-decoration: none;
|
|
103
|
+
white-space: nowrap;
|
|
104
|
+
}
|
|
105
|
+
.navLink:hover {
|
|
106
|
+
color: var(--xnav-link-hover, var(--xnav-link-color, var(--text)));
|
|
107
|
+
opacity: var(--xnav-link-hover-opacity, 0.7);
|
|
108
|
+
}
|
|
109
|
+
.navLinkActive {
|
|
110
|
+
border-bottom-color: var(--xnav-link-active, var(--xnav-link-color, var(--text)));
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
}
|
|
113
|
+
.navLinkExternal::after {
|
|
114
|
+
content: " \2197";
|
|
115
|
+
font-size: 0.7em;
|
|
116
|
+
opacity: 0.6;
|
|
117
|
+
}
|
|
118
|
+
.mobileToggle {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
}
|
|
123
|
+
@media (min-width: 768px) {
|
|
124
|
+
.mobileToggle {
|
|
125
|
+
display: none;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
.hamburgerBtn {
|
|
129
|
+
width: 2.5rem;
|
|
130
|
+
height: 2rem;
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
align-items: center;
|
|
134
|
+
justify-content: space-between;
|
|
135
|
+
background: none;
|
|
136
|
+
border: none;
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
position: relative;
|
|
139
|
+
z-index: 80;
|
|
140
|
+
padding: 0;
|
|
141
|
+
}
|
|
142
|
+
.bar {
|
|
143
|
+
width: var(--xnav-bar-w, 2rem);
|
|
144
|
+
height: var(--xnav-bar-h, 3px);
|
|
145
|
+
background: var(--xnav-bar-color, var(--text));
|
|
146
|
+
border-radius: 2px;
|
|
147
|
+
}
|
|
148
|
+
.mobileOverlay {
|
|
149
|
+
position: fixed;
|
|
150
|
+
inset: 0;
|
|
151
|
+
width: 100vw;
|
|
152
|
+
height: 100svh;
|
|
153
|
+
background: var(--bg);
|
|
154
|
+
color: var(--text);
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
align-items: center;
|
|
158
|
+
justify-content: center;
|
|
159
|
+
gap: 2rem;
|
|
160
|
+
font-size: 2.5rem;
|
|
161
|
+
z-index: 9999;
|
|
162
|
+
}
|
|
163
|
+
.mobileCloseBtn {
|
|
164
|
+
position: fixed;
|
|
165
|
+
top: 2rem;
|
|
166
|
+
left: 1rem;
|
|
167
|
+
width: 2.5rem;
|
|
168
|
+
height: 2rem;
|
|
169
|
+
display: flex;
|
|
170
|
+
align-items: center;
|
|
171
|
+
justify-content: center;
|
|
172
|
+
background: none;
|
|
173
|
+
border: none;
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
color: var(--xnav-bar-color, var(--text));
|
|
176
|
+
z-index: 10000;
|
|
177
|
+
-webkit-tap-highlight-color: transparent;
|
|
178
|
+
}
|
|
179
|
+
.closeBar {
|
|
180
|
+
display: block;
|
|
181
|
+
position: absolute;
|
|
182
|
+
width: 2rem;
|
|
183
|
+
height: 3px;
|
|
184
|
+
border-radius: 2px;
|
|
185
|
+
background: currentColor;
|
|
186
|
+
}
|
|
187
|
+
.mobileLogo {
|
|
188
|
+
font-weight: 700;
|
|
189
|
+
font-size: 3rem;
|
|
190
|
+
user-select: none;
|
|
191
|
+
pointer-events: none;
|
|
192
|
+
}
|
|
193
|
+
.mobileNavLink {
|
|
194
|
+
font-size: 2.5rem;
|
|
195
|
+
color: var(--xnav-link-color, var(--text));
|
|
196
|
+
text-decoration: none;
|
|
197
|
+
border-bottom: 2px solid transparent;
|
|
198
|
+
transition:
|
|
199
|
+
border-color 0.2s,
|
|
200
|
+
color 0.2s,
|
|
201
|
+
opacity 0.2s;
|
|
202
|
+
padding: 0.25rem;
|
|
203
|
+
}
|
|
204
|
+
.mobileNavLink:hover {
|
|
205
|
+
color: var(--xnav-link-hover, var(--xnav-link-color, var(--text)));
|
|
206
|
+
opacity: var(--xnav-link-hover-opacity, 0.7);
|
|
207
|
+
}
|
|
208
|
+
.mobileNavLinkActive {
|
|
209
|
+
font-weight: 600;
|
|
210
|
+
border-bottom-color: var(--xnav-link-active, var(--xnav-link-color, var(--text)));
|
|
211
|
+
}
|
|
212
|
+
.themeToggleMobile {
|
|
213
|
+
margin-top: 1rem;
|
|
214
|
+
font-size: 1rem;
|
|
215
|
+
padding: 0.5rem 1rem;
|
|
216
|
+
border: 1px solid var(--border);
|
|
217
|
+
border-radius: 0.375rem;
|
|
218
|
+
display: flex;
|
|
219
|
+
align-items: center;
|
|
220
|
+
gap: 0.5rem;
|
|
221
|
+
background: none;
|
|
222
|
+
color: var(--text);
|
|
223
|
+
cursor: pointer;
|
|
224
|
+
transition: opacity 0.2s;
|
|
225
|
+
}
|
|
226
|
+
.themeToggleMobile:hover {
|
|
227
|
+
opacity: 0.7;
|
|
228
|
+
}
|
|
229
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/navigation/xnavbar/XNavbar.module.css"],"sourcesContent":["/* ────────────────────────────────────────────\n XNavbar.module.css\n Navbar completamente libre de Tailwind.\n Usa variables CSS del tema global (--bg, --text, --border, --accent).\n ──────────────────────────────────────────── */\n\n/* ── Header / contenedor raíz ── */\n.header {\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 2rem 3rem;\n background: var(--bg);\n color: var(--text);\n font-size: 1.25rem;\n z-index: 60;\n}\n\n@media (min-width: 640px) { .header { padding-inline: 2rem; } }\n@media (min-width: 768px) { .header { padding-inline: 3rem; } }\n@media (min-width: 1024px) { .header { padding-inline: 5rem; } }\n@media (min-width: 1280px) { .header { padding-inline: 12rem; } }\n\n/* ── Desktop nav ── */\n.desktopNav {\n display: none;\n align-items: center;\n width: 100%;\n grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);\n padding-bottom: 0.5rem;\n}\n\n@media (min-width: 768px) {\n .desktopNav {\n display: grid;\n }\n}\n\n.desktopLinksLeft,\n.desktopLinksRight {\n display: flex;\n align-items: center;\n gap: 1.5rem;\n min-width: 0;\n}\n\n.desktopLinksLeft {\n justify-content: flex-end;\n}\n\n.desktopLinksRight {\n justify-content: flex-start;\n}\n\n.logoSlot {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* ── Logo / botón central (desktop) ── */\n.logoWrapper {\n position: relative;\n margin-inline: 1rem;\n display: flex;\n align-items: center;\n}\n\n.logoBtn {\n font-weight: 700;\n font-size: 1.5rem;\n line-height: 1;\n user-select: none;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--text);\n padding: 0;\n}\n\n/* ── Tray de íconos hover (sun/moon) ── */\n.iconTray {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n.iconTrayRight {\n left: 100%;\n padding-left: 0.75rem;\n}\n\n.iconTrayLeft {\n right: 100%;\n padding-right: 0.75rem;\n}\n\n/* ── NavLink (desktop) ── */\n.navLink {\n padding: 0.25rem;\n border-bottom: 2px solid transparent;\n transition: border-color 0.2s, opacity 0.2s, color 0.2s;\n color: var(--xnav-link-color, var(--text));\n text-decoration: none;\n white-space: nowrap;\n}\n\n.navLink:hover {\n color: var(--xnav-link-hover, var(--xnav-link-color, var(--text)));\n opacity: var(--xnav-link-hover-opacity, 0.7);\n}\n\n.navLinkActive {\n border-bottom-color: var(--xnav-link-active, var(--xnav-link-color, var(--text)));\n font-weight: 600;\n}\n\n/* External link indicator */\n.navLinkExternal::after {\n content: \" ↗\";\n font-size: 0.7em;\n opacity: 0.6;\n}\n\n/* ── Mobile hamburger ── */\n.mobileToggle {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n@media (min-width: 768px) {\n .mobileToggle {\n display: none;\n }\n}\n\n.hamburgerBtn {\n width: 2.5rem;\n height: 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n background: none;\n border: none;\n cursor: pointer;\n position: relative;\n z-index: 80;\n padding: 0;\n}\n\n.bar {\n width: var(--xnav-bar-w, 2rem);\n height: var(--xnav-bar-h, 3px);\n background: var(--xnav-bar-color, var(--text));\n border-radius: 2px;\n}\n\n/* ── Mobile overlay (portal) ── */\n.mobileOverlay {\n position: fixed;\n inset: 0;\n width: 100vw;\n height: 100svh;\n background: var(--bg);\n color: var(--text);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2rem;\n font-size: 2.5rem;\n z-index: 9999;\n}\n\n.mobileCloseBtn {\n position: fixed;\n top: 2rem;\n left: 1rem;\n width: 2.5rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n cursor: pointer;\n /* hereda el mismo color que las barras del hamburguesa */\n color: var(--xnav-bar-color, var(--text));\n z-index: 10000;\n -webkit-tap-highlight-color: transparent;\n}\n\n.closeBar {\n display: block;\n position: absolute;\n width: 2rem;\n height: 3px;\n border-radius: 2px;\n background: currentColor;\n}\n\n.mobileLogo {\n font-weight: 700;\n font-size: 3rem;\n user-select: none;\n pointer-events: none;\n}\n\n.mobileNavLink {\n font-size: 2.5rem;\n color: var(--xnav-link-color, var(--text));\n text-decoration: none;\n border-bottom: 2px solid transparent;\n transition: border-color 0.2s, color 0.2s, opacity 0.2s;\n padding: 0.25rem;\n}\n\n.mobileNavLink:hover {\n color: var(--xnav-link-hover, var(--xnav-link-color, var(--text)));\n opacity: var(--xnav-link-hover-opacity, 0.7);\n}\n\n.mobileNavLinkActive {\n font-weight: 600;\n border-bottom-color: var(--xnav-link-active, var(--xnav-link-color, var(--text)));\n}\n\n/* ── Botón tema (móvil) ── */\n.themeToggleMobile {\n margin-top: 1rem;\n font-size: 1rem;\n padding: 0.5rem 1rem;\n border: 1px solid var(--border);\n border-radius: 0.375rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: none;\n color: var(--text);\n cursor: pointer;\n transition: opacity 0.2s;\n}\n\n.themeToggleMobile:hover {\n opacity: 0.7;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type NavLinkItem = {
|
|
5
|
+
/** Ruta destino */
|
|
6
|
+
url: string;
|
|
7
|
+
/** Texto visible */
|
|
8
|
+
title: string;
|
|
9
|
+
/** Si es true abre en pestaña nueva y muestra el indicador ↗ */
|
|
10
|
+
external?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* ReactNode estático O función de render (size, color?) => ReactNode.
|
|
14
|
+
* La función recibe el tamaño y el color vigente para que el ícono
|
|
15
|
+
* pueda adaptarse dinámicamente a los props del navbar.
|
|
16
|
+
*/
|
|
17
|
+
type IconRenderer = ReactNode | ((size: number, color?: string) => ReactNode);
|
|
18
|
+
type ThemeToggleIcons = {
|
|
19
|
+
/** Ícono/renderer hacia tema oscuro (ReactNode o función) */
|
|
20
|
+
toDark: IconRenderer;
|
|
21
|
+
/** Ícono/renderer hacia tema claro (ReactNode o función) */
|
|
22
|
+
toLight: IconRenderer;
|
|
23
|
+
};
|
|
24
|
+
type XNavbarProps = {
|
|
25
|
+
/** Links que aparecen a la izquierda del logo en desktop */
|
|
26
|
+
linksLeft?: NavLinkItem[];
|
|
27
|
+
/** Links que aparecen a la derecha del logo en desktop */
|
|
28
|
+
linksRight?: NavLinkItem[];
|
|
29
|
+
/** Contenido del botón central (texto o JSX). Por defecto: "X" */
|
|
30
|
+
logo?: ReactNode;
|
|
31
|
+
/** Si true el logo actúa como toggle de tema (comportamiento original). Default: true */
|
|
32
|
+
logoAsThemeToggle?: boolean;
|
|
33
|
+
/** Callback custom si logoAsThemeToggle es false */
|
|
34
|
+
onLogoClick?: () => void;
|
|
35
|
+
/** Íconos para el toggle de tema. Si no se pasa, no se mostrará hint de ícono */
|
|
36
|
+
themeIcons?: ThemeToggleIcons;
|
|
37
|
+
/** Tema inicial. Default: "light" */
|
|
38
|
+
defaultTheme?: "light" | "dark";
|
|
39
|
+
/** Key de localStorage para persistencia del tema. Default: "theme" */
|
|
40
|
+
storageKey?: string;
|
|
41
|
+
/** Color base de los enlaces (Inicio, Contacto, etc.). Default: var(--text) */
|
|
42
|
+
linkColor?: string;
|
|
43
|
+
/** Color al hacer hover sobre los enlaces. Default: opacidad reducida del linkColor */
|
|
44
|
+
linkHoverColor?: string;
|
|
45
|
+
/** Color del borde inferior del enlace activo. Default: linkColor */
|
|
46
|
+
linkActiveColor?: string;
|
|
47
|
+
/** Color base de los íconos. Acepta cualquier valor CSS: hex, hsl, "var(--accent)", etc.
|
|
48
|
+
* Si no se pasa, los íconos heredan el color del texto (currentColor). */
|
|
49
|
+
iconColor?: string;
|
|
50
|
+
/** Color que toman los íconos al hacer hover sobre el logo. Default: iconColor */
|
|
51
|
+
iconHoverColor?: string;
|
|
52
|
+
/** Tamaño en px que se pasa a IconRenderer cuando es función. Default: 22 */
|
|
53
|
+
iconSize?: number;
|
|
54
|
+
/** Color de las 3 barras (y la X de cierre móvil). Acepta cualquier valor CSS. Default: var(--text) */
|
|
55
|
+
hamburgerColor?: string;
|
|
56
|
+
/** Ancho de las barras. Cualquier unidad CSS. Default: "2rem" */
|
|
57
|
+
hamburgerBarWidth?: string;
|
|
58
|
+
/** Grosor (altura) de las barras. Cualquier unidad CSS. Default: "3px" */
|
|
59
|
+
hamburgerBarThickness?: string;
|
|
60
|
+
/** Inyecta variables CSS extra directamente en el style del <header>.
|
|
61
|
+
* Útil para pasar tokens del tema: { '--xnav-icon-color': 'var(--accent)' } */
|
|
62
|
+
cssVars?: Record<string, string>;
|
|
63
|
+
/** aria-label del botón hamburguesa cuando está cerrado. Default: "Abrir menú" */
|
|
64
|
+
labelOpen?: string;
|
|
65
|
+
/** aria-label del botón hamburguesa cuando está abierto. Default: "Cerrar menú" */
|
|
66
|
+
labelClose?: string;
|
|
67
|
+
/** Texto del botón de tema oscuro en menú móvil. Default: "Oscuro" */
|
|
68
|
+
labelDark?: string;
|
|
69
|
+
/** Texto del botón de tema claro en menú móvil. Default: "Claro" */
|
|
70
|
+
labelLight?: string;
|
|
71
|
+
/** className extra que se añade al <header> */
|
|
72
|
+
className?: string;
|
|
73
|
+
};
|
|
74
|
+
declare function XNavbar({ linksLeft, linksRight, logo, logoAsThemeToggle, onLogoClick, themeIcons, defaultTheme, storageKey, linkColor, linkHoverColor, linkActiveColor, iconColor, iconHoverColor, iconSize, hamburgerColor, hamburgerBarWidth, hamburgerBarThickness, cssVars, labelOpen, labelClose, labelDark, labelLight, className, }: XNavbarProps): react_jsx_runtime.JSX.Element;
|
|
75
|
+
|
|
76
|
+
export { type IconRenderer, type NavLinkItem, type ThemeToggleIcons, XNavbar, type XNavbarProps };
|