@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,320 @@
1
+ // src/components/forms/xcontactform/XContactForm.tsx
2
+ import { useState } from "react";
3
+
4
+ // src/components/forms/xcontactform/XContactForm.module.css
5
+ var XContactForm_default = {};
6
+
7
+ // src/components/forms/xcontactform/XContactForm.tsx
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function XContactForm({
10
+ showName = true,
11
+ showEmail = true,
12
+ showPhone = true,
13
+ showSubject = true,
14
+ showMessage = true,
15
+ namePlaceholder = "Tu nombre",
16
+ emailPlaceholder = "tucorreo@ejemplo.com",
17
+ phonePlaceholder = "+34 600 000 000",
18
+ subjectPlaceholder = "Tema del mensaje",
19
+ messagePlaceholder = "Cu\xE9ntame qu\xE9 necesitas\u2026",
20
+ labelColor,
21
+ wrapperBackgroundColor,
22
+ wrapperBorderColor,
23
+ wrapperBorderWidth,
24
+ wrapperBorderRadius = "rounded",
25
+ wrapperBorderStyle = "solid",
26
+ fieldBorderColor,
27
+ fieldBorderWidth,
28
+ fieldBorderRadius = "rounded",
29
+ fieldBorderStyle = "solid",
30
+ buttonColor,
31
+ buttonBorderColor,
32
+ buttonBorderWidth,
33
+ buttonBorderRadius = "rounded",
34
+ buttonBorderStyle = "solid",
35
+ buttonHoverColor,
36
+ buttonHoverTextColor,
37
+ buttonHoverBorderColor,
38
+ buttonTextColor,
39
+ buttonAlignment = "left",
40
+ requiredFieldsMessage = "Rellena los campos obligatorios.",
41
+ honeypotMessage = "Gracias.",
42
+ submitSuccessMessage = "Abriendo tu aplicaci\xF3n de correo\u2026",
43
+ statusSuccessColor,
44
+ statusErrorColor,
45
+ decorativeX = false,
46
+ decorativeXColor = "currentColor",
47
+ size = "medium",
48
+ layout = "grid"
49
+ }) {
50
+ const [status, setStatus] = useState(null);
51
+ function onSubmit(e) {
52
+ e.preventDefault();
53
+ setStatus(null);
54
+ const form = e.currentTarget;
55
+ const fd = new FormData(form);
56
+ if (fd.get("website")?.length) {
57
+ setStatus({ ok: true, msg: honeypotMessage });
58
+ form.reset();
59
+ return;
60
+ }
61
+ const name = showName ? String(fd.get("name") || "").trim() : "";
62
+ const email = showEmail ? String(fd.get("email") || "").trim() : "";
63
+ const phone = showPhone ? String(fd.get("phone") || "").trim() : "";
64
+ const subject = showSubject ? String(fd.get("subject") || "Contacto desde web").trim() : "Contacto desde web";
65
+ const message = showMessage ? String(fd.get("message") || "").trim() : "";
66
+ if (showName && !name || showEmail && !email || showPhone && !phone || showMessage && !message) {
67
+ setStatus({ ok: false, msg: requiredFieldsMessage });
68
+ return;
69
+ }
70
+ const bodyLines = [];
71
+ if (showName) bodyLines.push(`Nombre: ${name}`);
72
+ if (showEmail) bodyLines.push(`Email: ${email}`);
73
+ if (showPhone) bodyLines.push(`Tel\xE9fono: ${phone}`);
74
+ bodyLines.push("");
75
+ if (showMessage) bodyLines.push(message);
76
+ const body = bodyLines.join("\n");
77
+ const to = "x@xscriptor.com";
78
+ const mailto = `mailto:${encodeURIComponent(to)}?subject=${encodeURIComponent(
79
+ subject
80
+ )}&body=${encodeURIComponent(body)}`;
81
+ window.location.href = mailto;
82
+ setStatus({ ok: true, msg: submitSuccessMessage });
83
+ }
84
+ const radiusMap = {
85
+ rounded: "0.5rem",
86
+ square: "0"
87
+ };
88
+ const alignmentMap = {
89
+ left: "flex-start",
90
+ right: "flex-end"
91
+ };
92
+ const customStyles = {
93
+ ...decorativeXColor && { "--decorative-x-color": decorativeXColor },
94
+ ...labelColor && { "--label-color": labelColor },
95
+ ...wrapperBackgroundColor && { "--wrapper-bg-color": wrapperBackgroundColor },
96
+ ...wrapperBorderColor && { "--wrapper-border-color": wrapperBorderColor },
97
+ ...wrapperBorderWidth && { "--wrapper-border-width": wrapperBorderWidth },
98
+ "--wrapper-radius": radiusMap[wrapperBorderRadius],
99
+ "--wrapper-border-style": wrapperBorderStyle,
100
+ ...fieldBorderColor && { "--field-border-color": fieldBorderColor },
101
+ ...fieldBorderWidth && { "--field-border-width": fieldBorderWidth },
102
+ "--field-radius": radiusMap[fieldBorderRadius],
103
+ "--field-border-style": fieldBorderStyle,
104
+ ...buttonColor && { "--btn-bg-color": buttonColor },
105
+ ...buttonBorderColor && { "--btn-border-color": buttonBorderColor },
106
+ ...buttonBorderWidth && { "--btn-border-width": buttonBorderWidth },
107
+ "--btn-radius": radiusMap[buttonBorderRadius],
108
+ "--btn-border-style": buttonBorderStyle,
109
+ "--btn-alignment": alignmentMap[buttonAlignment],
110
+ ...buttonHoverColor && { "--btn-hover-bg-color": buttonHoverColor },
111
+ ...buttonHoverTextColor && { "--btn-hover-text-color": buttonHoverTextColor },
112
+ ...buttonHoverBorderColor && { "--btn-hover-border-color": buttonHoverBorderColor },
113
+ ...buttonTextColor && { "--btn-text-color": buttonTextColor },
114
+ ...statusSuccessColor && { "--status-ok-color": statusSuccessColor },
115
+ ...statusErrorColor && { "--status-error-color": statusErrorColor }
116
+ };
117
+ return /* @__PURE__ */ jsxs("div", { className: `${XContactForm_default.wrapper} ${XContactForm_default[size]} ${decorativeX ? XContactForm_default.withDecorativeX : ""}`, style: customStyles, children: [
118
+ decorativeX && /* @__PURE__ */ jsx("div", { className: XContactForm_default.decorativeXTop, children: "\u2715" }),
119
+ /* @__PURE__ */ jsxs("form", { onSubmit, className: `${XContactForm_default.form} ${XContactForm_default[layout]}`, noValidate: true, children: [
120
+ /* @__PURE__ */ jsxs("div", { className: XContactForm_default.honeypot, "aria-hidden": "true", children: [
121
+ /* @__PURE__ */ jsx("label", { htmlFor: "website", children: "Tu web" }),
122
+ /* @__PURE__ */ jsx("input", { id: "website", name: "website", type: "text", tabIndex: -1, autoComplete: "off" })
123
+ ] }),
124
+ (showName || showEmail || showPhone) && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.row, children: [
125
+ showName && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.field, children: [
126
+ /* @__PURE__ */ jsx("label", { htmlFor: "name", children: "Nombre" }),
127
+ /* @__PURE__ */ jsx("input", { id: "name", name: "name", type: "text", placeholder: namePlaceholder, required: true, maxLength: 80 })
128
+ ] }),
129
+ showEmail && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.field, children: [
130
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", children: "Email" }),
131
+ /* @__PURE__ */ jsx("input", { id: "email", name: "email", type: "email", inputMode: "email", placeholder: emailPlaceholder, required: true })
132
+ ] }),
133
+ showPhone && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.field, children: [
134
+ /* @__PURE__ */ jsx("label", { htmlFor: "phone", children: "Tel\xE9fono" }),
135
+ /* @__PURE__ */ jsx("input", { id: "phone", name: "phone", type: "tel", inputMode: "tel", placeholder: phonePlaceholder, required: true, maxLength: 20 })
136
+ ] })
137
+ ] }),
138
+ showSubject && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.field, children: [
139
+ /* @__PURE__ */ jsx("label", { htmlFor: "subject", children: "Asunto" }),
140
+ /* @__PURE__ */ jsx("input", { id: "subject", name: "subject", type: "text", placeholder: subjectPlaceholder, required: true, maxLength: 120 })
141
+ ] }),
142
+ showMessage && /* @__PURE__ */ jsxs("div", { className: XContactForm_default.field, children: [
143
+ /* @__PURE__ */ jsx("label", { htmlFor: "message", children: "Mensaje" }),
144
+ /* @__PURE__ */ jsx("textarea", { id: "message", name: "message", rows: 6, placeholder: messagePlaceholder, required: true, maxLength: 3e3 })
145
+ ] }),
146
+ /* @__PURE__ */ jsx("div", { className: XContactForm_default.buttoncontainer, children: /* @__PURE__ */ jsx("button", { type: "submit", className: XContactForm_default.button, children: "Enviar" }) }),
147
+ /* @__PURE__ */ jsx("p", { className: `${XContactForm_default.status} ${status?.ok ? XContactForm_default.statusOk : status === null ? "" : XContactForm_default.statusError}`, role: "status", "aria-live": "polite", children: status?.msg })
148
+ ] }),
149
+ decorativeX && /* @__PURE__ */ jsx("div", { className: XContactForm_default.decorativeXBottom, children: "\u2715" })
150
+ ] });
151
+ }
152
+
153
+ // src/components/forms/xnewsletter/XNewsletter.tsx
154
+ import { useState as useState2 } from "react";
155
+ import Link from "next/link";
156
+
157
+ // src/components/forms/xnewsletter/XNewsletter.module.css
158
+ var XNewsletter_default = {};
159
+
160
+ // src/components/forms/xnewsletter/XNewsletter.tsx
161
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
162
+ function XNewsletter({
163
+ title = "Recibe poes\xEDa y reflexiones",
164
+ placeholder = "tu@email.com",
165
+ buttonText = "Suscribirse",
166
+ termsText = "Acepto",
167
+ termsLinkText = "t\xE9rminos",
168
+ successMessage = "\xA1Bienvenido(a)!",
169
+ errorMessage = "Algo sali\xF3 mal. Por favor, intenta de nuevo.",
170
+ termsErrorMessage = "Debes aceptar los t\xE9rminos y condiciones para suscribirte...",
171
+ termsLink = "/terminos-y-condiciones",
172
+ apiRoute,
173
+ method = "POST",
174
+ payloadType = "formData",
175
+ layout = "horizontal",
176
+ accentColor = "var(--accent)",
177
+ textColor = "var(--text)",
178
+ borderColor = "var(--border)",
179
+ buttonTextColor = "var(--accent-text)",
180
+ containerClassName = "w-full max-w-4xl mx-auto px-4 py-6"
181
+ }) {
182
+ const [email, setEmail] = useState2("");
183
+ const [acceptedTerms, setAcceptedTerms] = useState2(false);
184
+ const [message, setMessage] = useState2("");
185
+ const [isLoading, setIsLoading] = useState2(false);
186
+ const handleSubmit = async (e) => {
187
+ e.preventDefault();
188
+ setMessage("");
189
+ if (!acceptedTerms) {
190
+ setMessage(termsErrorMessage);
191
+ return;
192
+ }
193
+ setIsLoading(true);
194
+ try {
195
+ let bodyData = null;
196
+ let headers = {};
197
+ if (payloadType === "formData") {
198
+ const formData = new FormData();
199
+ formData.append("email", email);
200
+ bodyData = formData;
201
+ } else if (payloadType === "json") {
202
+ bodyData = JSON.stringify({ email });
203
+ headers = { "Content-Type": "application/json" };
204
+ }
205
+ const response = await fetch(apiRoute, {
206
+ method,
207
+ headers,
208
+ body: method !== "GET" ? bodyData : void 0,
209
+ cache: "no-store"
210
+ });
211
+ const data = await response.json();
212
+ if (response.ok && data.success) {
213
+ setMessage(data.message || successMessage);
214
+ setEmail("");
215
+ setAcceptedTerms(false);
216
+ } else {
217
+ setMessage(data.error || errorMessage);
218
+ }
219
+ } catch {
220
+ setMessage(errorMessage);
221
+ } finally {
222
+ setIsLoading(false);
223
+ }
224
+ };
225
+ const customCssVariables = {
226
+ "--nws-accent": accentColor,
227
+ "--nws-text": textColor,
228
+ "--nws-border": borderColor,
229
+ "--nws-btn-text": buttonTextColor
230
+ };
231
+ return /* @__PURE__ */ jsxs2(
232
+ "div",
233
+ {
234
+ className: `${XNewsletter_default.container} ${containerClassName}`,
235
+ style: customCssVariables,
236
+ children: [
237
+ /* @__PURE__ */ jsxs2(
238
+ "form",
239
+ {
240
+ onSubmit: handleSubmit,
241
+ className: `${XNewsletter_default.form} ${XNewsletter_default[layout]}`,
242
+ children: [
243
+ title && /* @__PURE__ */ jsx2("span", { className: XNewsletter_default.title, children: title }),
244
+ /* @__PURE__ */ jsx2(
245
+ "input",
246
+ {
247
+ type: "email",
248
+ placeholder,
249
+ className: XNewsletter_default.input,
250
+ "aria-label": "email",
251
+ value: email,
252
+ onChange: (e) => setEmail(e.target.value),
253
+ required: true,
254
+ disabled: isLoading
255
+ }
256
+ ),
257
+ /* @__PURE__ */ jsxs2(
258
+ "div",
259
+ {
260
+ className: `${XNewsletter_default.actions} ${layout === "horizontal" ? XNewsletter_default.actionsHorizontal : XNewsletter_default.actionsVertical}`,
261
+ children: [
262
+ /* @__PURE__ */ jsxs2("label", { className: XNewsletter_default.checkboxLabel, children: [
263
+ /* @__PURE__ */ jsx2(
264
+ "input",
265
+ {
266
+ type: "checkbox",
267
+ className: XNewsletter_default.checkbox,
268
+ checked: acceptedTerms,
269
+ onChange: (e) => setAcceptedTerms(e.target.checked),
270
+ required: true,
271
+ disabled: isLoading
272
+ }
273
+ ),
274
+ /* @__PURE__ */ jsxs2("span", { children: [
275
+ termsText,
276
+ " ",
277
+ /* @__PURE__ */ jsx2(
278
+ Link,
279
+ {
280
+ href: termsLink,
281
+ target: "_blank",
282
+ rel: "noopener noreferrer",
283
+ className: XNewsletter_default.termsLink,
284
+ children: termsLinkText
285
+ }
286
+ )
287
+ ] })
288
+ ] }),
289
+ /* @__PURE__ */ jsx2(
290
+ "button",
291
+ {
292
+ type: "submit",
293
+ disabled: isLoading,
294
+ className: XNewsletter_default.button,
295
+ children: isLoading ? "Enviando..." : buttonText
296
+ }
297
+ )
298
+ ]
299
+ }
300
+ )
301
+ ]
302
+ }
303
+ ),
304
+ message && /* @__PURE__ */ jsx2(
305
+ "p",
306
+ {
307
+ className: `${XNewsletter_default.message} ${layout === "horizontal" ? XNewsletter_default.messageHorizontal : XNewsletter_default.messageVertical}`,
308
+ children: message
309
+ }
310
+ )
311
+ ]
312
+ }
313
+ );
314
+ }
315
+
316
+ export {
317
+ XContactForm,
318
+ XNewsletter
319
+ };
320
+ //# sourceMappingURL=chunk-QCMWPIG7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/forms/xcontactform/XContactForm.tsx","../src/components/forms/xcontactform/XContactForm.module.css","../src/components/forms/xnewsletter/XNewsletter.tsx","../src/components/forms/xnewsletter/XNewsletter.module.css"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport styles from \"./XContactForm.module.css\";\n\ntype Status = { ok: boolean; msg: string } | null;\n\nexport interface XContactFormProps {\n // Visibilidad\n showName?: boolean;\n showEmail?: boolean;\n showPhone?: boolean;\n showSubject?: boolean;\n showMessage?: boolean;\n \n // Placeholders\n namePlaceholder?: string;\n emailPlaceholder?: string;\n phonePlaceholder?: string;\n subjectPlaceholder?: string;\n messagePlaceholder?: string;\n\n // Diseño\n labelColor?: string;\n wrapperBackgroundColor?: string;\n wrapperBorderColor?: string;\n wrapperBorderWidth?: string;\n wrapperBorderRadius?: \"rounded\" | \"square\";\n wrapperBorderStyle?: \"solid\" | \"dashed\" | \"dotted\";\n fieldBorderColor?: string;\n fieldBorderWidth?: string;\n fieldBorderRadius?: \"rounded\" | \"square\";\n fieldBorderStyle?: \"solid\" | \"dashed\" | \"dotted\";\n buttonColor?: string;\n buttonBorderColor?: string;\n buttonBorderWidth?: string;\n buttonBorderRadius?: \"rounded\" | \"square\";\n buttonBorderStyle?: \"solid\" | \"dashed\" | \"dotted\";\n buttonHoverColor?: string;\n buttonHoverTextColor?: string;\n buttonHoverBorderColor?: string;\n buttonTextColor?: string;\n buttonAlignment?: \"left\" | \"right\";\n\n // Mensajes de estado\n requiredFieldsMessage?: string;\n honeypotMessage?: string;\n submitSuccessMessage?: string;\n statusSuccessColor?: string;\n statusErrorColor?: string;\n\n // Decorativos\n decorativeX?: boolean;\n decorativeXColor?: string;\n\n size?: \"small\" | \"medium\" | \"large\";\n layout?: \"vertical\" | \"grid\";\n}\n\nexport default function XContactForm({\n showName = true,\n showEmail = true,\n showPhone = true,\n showSubject = true,\n showMessage = true,\n namePlaceholder = \"Tu nombre\",\n emailPlaceholder = \"tucorreo@ejemplo.com\",\n phonePlaceholder = \"+34 600 000 000\",\n subjectPlaceholder = \"Tema del mensaje\",\n messagePlaceholder = \"Cuéntame qué necesitas…\",\n labelColor,\n wrapperBackgroundColor,\n wrapperBorderColor,\n wrapperBorderWidth,\n wrapperBorderRadius = \"rounded\",\n wrapperBorderStyle = \"solid\",\n fieldBorderColor,\n fieldBorderWidth,\n fieldBorderRadius = \"rounded\",\n fieldBorderStyle = \"solid\",\n buttonColor,\n buttonBorderColor,\n buttonBorderWidth,\n buttonBorderRadius = \"rounded\",\n buttonBorderStyle = \"solid\",\n buttonHoverColor,\n buttonHoverTextColor,\n buttonHoverBorderColor,\n buttonTextColor,\n buttonAlignment = \"left\",\n requiredFieldsMessage = \"Rellena los campos obligatorios.\",\n honeypotMessage = \"Gracias.\",\n submitSuccessMessage = \"Abriendo tu aplicación de correo…\",\n statusSuccessColor,\n statusErrorColor,\n decorativeX = false,\n decorativeXColor = \"currentColor\",\n size = \"medium\",\n layout = \"grid\",\n}: XContactFormProps) {\n const [status, setStatus] = useState<Status>(null);\n\n function onSubmit(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setStatus(null);\n\n const form = e.currentTarget;\n const fd = new FormData(form);\n\n if ((fd.get(\"website\") as string)?.length) {\n setStatus({ ok: true, msg: honeypotMessage });\n form.reset();\n return;\n }\n\n const name = showName ? String(fd.get(\"name\") || \"\").trim() : \"\";\n const email = showEmail ? String(fd.get(\"email\") || \"\").trim() : \"\";\n const phone = showPhone ? String(fd.get(\"phone\") || \"\").trim() : \"\";\n const subject = showSubject\n ? String(fd.get(\"subject\") || \"Contacto desde web\").trim()\n : \"Contacto desde web\";\n const message = showMessage ? String(fd.get(\"message\") || \"\").trim() : \"\";\n\n if (\n (showName && !name) ||\n (showEmail && !email) ||\n (showPhone && !phone) ||\n (showMessage && !message)\n ) {\n setStatus({ ok: false, msg: requiredFieldsMessage });\n return;\n }\n\n const bodyLines = [];\n if (showName) bodyLines.push(`Nombre: ${name}`);\n if (showEmail) bodyLines.push(`Email: ${email}`);\n if (showPhone) bodyLines.push(`Teléfono: ${phone}`);\n bodyLines.push(\"\");\n if (showMessage) bodyLines.push(message);\n\n const body = bodyLines.join(\"\\n\");\n const to = \"x@xscriptor.com\";\n const mailto = `mailto:${encodeURIComponent(to)}?subject=${encodeURIComponent(\n subject\n )}&body=${encodeURIComponent(body)}`;\n\n window.location.href = mailto;\n setStatus({ ok: true, msg: submitSuccessMessage });\n }\n\n const radiusMap = {\n rounded: \"0.5rem\",\n square: \"0\",\n } as const;\n\n const alignmentMap = {\n left: \"flex-start\",\n right: \"flex-end\",\n } as const;\n\n // Variables CSS dinámicas para estilos configurables\n const customStyles = {\n ...(decorativeXColor && { \"--decorative-x-color\": decorativeXColor }),\n ...(labelColor && { \"--label-color\": labelColor }),\n ...(wrapperBackgroundColor && { \"--wrapper-bg-color\": wrapperBackgroundColor }),\n ...(wrapperBorderColor && { \"--wrapper-border-color\": wrapperBorderColor }),\n ...(wrapperBorderWidth && { \"--wrapper-border-width\": wrapperBorderWidth }),\n \"--wrapper-radius\": radiusMap[wrapperBorderRadius],\n \"--wrapper-border-style\": wrapperBorderStyle,\n ...(fieldBorderColor && { \"--field-border-color\": fieldBorderColor }),\n ...(fieldBorderWidth && { \"--field-border-width\": fieldBorderWidth }),\n \"--field-radius\": radiusMap[fieldBorderRadius],\n \"--field-border-style\": fieldBorderStyle,\n ...(buttonColor && { \"--btn-bg-color\": buttonColor }),\n ...(buttonBorderColor && { \"--btn-border-color\": buttonBorderColor }),\n ...(buttonBorderWidth && { \"--btn-border-width\": buttonBorderWidth }),\n \"--btn-radius\": radiusMap[buttonBorderRadius],\n \"--btn-border-style\": buttonBorderStyle,\n \"--btn-alignment\": alignmentMap[buttonAlignment],\n ...(buttonHoverColor && { \"--btn-hover-bg-color\": buttonHoverColor }),\n ...(buttonHoverTextColor && { \"--btn-hover-text-color\": buttonHoverTextColor }),\n ...(buttonHoverBorderColor && { \"--btn-hover-border-color\": buttonHoverBorderColor }),\n ...(buttonTextColor && { \"--btn-text-color\": buttonTextColor }),\n ...(statusSuccessColor && { \"--status-ok-color\": statusSuccessColor }),\n ...(statusErrorColor && { \"--status-error-color\": statusErrorColor }),\n } as React.CSSProperties;\n\n return (\n <div className={`${styles.wrapper} ${styles[size]} ${decorativeX ? styles.withDecorativeX : \"\"}`} style={customStyles}>\n {decorativeX && <div className={styles.decorativeXTop}>✕</div>}\n <form onSubmit={onSubmit} className={`${styles.form} ${styles[layout]}`} noValidate>\n <div className={styles.honeypot} aria-hidden=\"true\">\n <label htmlFor=\"website\">Tu web</label>\n <input id=\"website\" name=\"website\" type=\"text\" tabIndex={-1} autoComplete=\"off\" />\n </div>\n\n {(showName || showEmail || showPhone) && (\n <div className={styles.row}>\n {showName && (\n <div className={styles.field}>\n <label htmlFor=\"name\">Nombre</label>\n <input id=\"name\" name=\"name\" type=\"text\" placeholder={namePlaceholder} required maxLength={80} />\n </div>\n )}\n {showEmail && (\n <div className={styles.field}>\n <label htmlFor=\"email\">Email</label>\n <input id=\"email\" name=\"email\" type=\"email\" inputMode=\"email\" placeholder={emailPlaceholder} required />\n </div>\n )}\n {showPhone && (\n <div className={styles.field}>\n <label htmlFor=\"phone\">Teléfono</label>\n <input id=\"phone\" name=\"phone\" type=\"tel\" inputMode=\"tel\" placeholder={phonePlaceholder} required maxLength={20} />\n </div>\n )}\n </div>\n )}\n\n {showSubject && (\n <div className={styles.field}>\n <label htmlFor=\"subject\">Asunto</label>\n <input id=\"subject\" name=\"subject\" type=\"text\" placeholder={subjectPlaceholder} required maxLength={120} />\n </div>\n )}\n\n {showMessage && (\n <div className={styles.field}>\n <label htmlFor=\"message\">Mensaje</label>\n <textarea id=\"message\" name=\"message\" rows={6} placeholder={messagePlaceholder} required maxLength={3000} />\n </div>\n )}\n\n <div className={styles.buttoncontainer}>\n <button type=\"submit\" className={styles.button}>\n Enviar\n </button>\n </div>\n\n <p className={`${styles.status} ${status?.ok ? styles.statusOk : status === null ? \"\" : styles.statusError}`} role=\"status\" aria-live=\"polite\">\n {status?.msg}\n </p>\n </form>\n {decorativeX && <div className={styles.decorativeXBottom}>✕</div>}\n </div>\n );\n}","/* Tamaños dinámicos base */\n.wrapper {\n --input-padding: .65rem .9rem;\n --font-size: 16px;\n --form-gap: 1.25rem;\n --row-gap: .85rem;\n --field-gap: .45rem;\n --button-min-width: 140px;\n --label-color: inherit;\n --wrapper-bg-color: transparent;\n --wrapper-border-color: transparent;\n --wrapper-border-width: 0px;\n --wrapper-border-style: solid;\n --wrapper-radius: .5rem;\n --field-border-color: var(--border, #ccc);\n --field-border-width: 1px;\n --field-border-style: solid;\n --field-radius: .5rem;\n --btn-bg-color: var(--bg, #333);\n --btn-text-color: var(--text, #fff);\n --btn-border-color: transparent;\n --btn-border-width: 0px;\n --btn-border-style: solid;\n --btn-radius: .5rem;\n --btn-alignment: flex-start;\n --btn-hover-bg-color: var(--btn-bg-color);\n --btn-hover-text-color: var(--btn-text-color);\n --btn-hover-border-color: var(--btn-border-color);\n --status-ok-color: #1fa37a;\n --status-error-color: #d16a6a;\n \n max-width: 900px;\n margin: 0 auto;\n padding: 2rem 1rem;\n background-color: var(--wrapper-bg-color);\n border: var(--wrapper-border-width) var(--wrapper-border-style) var(--wrapper-border-color);\n border-radius: var(--wrapper-radius);\n}\n\n/* Modificadores de tamaño */\n.small {\n --input-padding: .35rem .55rem;\n --font-size: 13px;\n --form-gap: .75rem;\n --row-gap: .6rem;\n --field-gap: .3rem;\n --button-min-width: 118px;\n}\n.medium {\n --input-padding: .5rem .7rem;\n --font-size: 15px;\n --form-gap: 1rem;\n --row-gap: .7rem;\n --field-gap: .4rem;\n --button-min-width: 130px;\n}\n.large {\n --input-padding: 1rem 1.2rem;\n --font-size: 18px;\n --form-gap: 1.5rem;\n --row-gap: 1rem;\n --field-gap: .5rem;\n --button-min-width: 150px;\n}\n\n.form {\n display: grid;\n gap: var(--form-gap);\n max-width: 100%;\n}\n\n/* Layouts */\n.row {\n display: grid;\n gap: var(--row-gap);\n}\n\n.grid .row {\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n}\n\n.vertical .row {\n grid-template-columns: 1fr;\n}\n\n.field {\n display: flex;\n flex-direction: column;\n gap: var(--field-gap);\n}\n\n.field label {\n font-size: calc(var(--font-size) - 2px);\n font-weight: 500;\n color: var(--label-color);\n}\n\n.field input,\n.field textarea {\n width: 100%;\n padding: var(--input-padding);\n border: var(--field-border-width) var(--field-border-style) var(--field-border-color);\n border-radius: var(--field-radius);\n font-size: var(--font-size);\n box-sizing: border-box;\n font-family: inherit;\n}\n\n.field input::placeholder,\n.field textarea::placeholder {\n color: #888;\n}\n\n.buttoncontainer {\n display: flex;\n justify-content: var(--btn-alignment);\n margin-top: 0.25rem;\n}\n\n.button {\n padding: var(--input-padding);\n border-radius: var(--btn-radius);\n border: var(--btn-border-width) var(--btn-border-style) var(--btn-border-color);\n background-color: var(--btn-bg-color);\n color: var(--btn-text-color);\n cursor: pointer;\n font-size: var(--font-size);\n font-weight: 600;\n min-width: var(--button-min-width);\n transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;\n}\n\n.button:hover {\n background-color: var(--btn-hover-bg-color);\n color: var(--btn-hover-text-color);\n border-color: var(--btn-hover-border-color);\n opacity: 0.95;\n}\n\n.status {\n min-height: 1.5rem;\n font-size: calc(var(--font-size) - 2px);\n margin-top: 0.25rem;\n}\n\n.statusOk { color: var(--status-ok-color); }\n.statusError { color: var(--status-error-color); }\n\n.honeypot {\n position: absolute;\n left: -9999px;\n top: -9999px;\n}\n\n.withDecorativeX {\n position: relative;\n padding-top: 2.5rem;\n padding-bottom: 2.5rem;\n}\n\n.decorativeXTop,\n.decorativeXBottom {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n font-size: 0.5rem;\n font-weight: 300;\n color: var(--decorative-x-color, currentColor);\n opacity: 1;\n pointer-events: none;\n background-color: var(--wrapper-bg-color, transparent);\n padding: 0 0.3rem;\n line-height: 1;\n z-index: 1;\n}\n\n.decorativeXTop {\n top: 0;\n transform: translate(-50%, -50%);\n}\n\n.decorativeXBottom {\n bottom: 0;\n transform: translate(-50%, 50%);\n}","\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport styles from \"./XNewsletter.module.css\";\n\nexport interface XNewsletterProps {\n title?: string;\n placeholder?: string;\n buttonText?: string;\n termsText?: string;\n termsLinkText?: string;\n successMessage?: string;\n errorMessage?: string;\n termsErrorMessage?: string;\n termsLink?: string;\n apiRoute: string;\n method?: \"POST\" | \"GET\" | \"PUT\";\n payloadType?: \"formData\" | \"json\";\n layout?: \"horizontal\" | \"vertical\";\n accentColor?: string;\n textColor?: string;\n borderColor?: string;\n buttonTextColor?: string;\n containerClassName?: string; // Para clases extra desde afuera si las necesitas\n}\n\nexport default function XNewsletter({\n title = \"Recibe poesía y reflexiones\",\n placeholder = \"tu@email.com\",\n buttonText = \"Suscribirse\",\n termsText = \"Acepto\",\n termsLinkText = \"términos\",\n successMessage = \"¡Bienvenido(a)!\",\n errorMessage = \"Algo salió mal. Por favor, intenta de nuevo.\",\n termsErrorMessage = \"Debes aceptar los términos y condiciones para suscribirte...\",\n termsLink = \"/terminos-y-condiciones\",\n apiRoute,\n method = \"POST\",\n payloadType = \"formData\",\n layout = \"horizontal\",\n accentColor = \"var(--accent)\",\n textColor = \"var(--text)\",\n borderColor = \"var(--border)\",\n buttonTextColor = \"var(--accent-text)\",\n containerClassName = \"w-full max-w-4xl mx-auto px-4 py-6\",\n}: XNewsletterProps) {\n const [email, setEmail] = useState(\"\");\n const [acceptedTerms, setAcceptedTerms] = useState(false);\n const [message, setMessage] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setMessage(\"\");\n\n if (!acceptedTerms) {\n setMessage(termsErrorMessage);\n return;\n }\n\n setIsLoading(true);\n\n try {\n let bodyData: BodyInit | null | undefined = null;\n let headers: HeadersInit = {};\n\n if (payloadType === \"formData\") {\n const formData = new FormData();\n formData.append(\"email\", email);\n bodyData = formData;\n } else if (payloadType === \"json\") {\n bodyData = JSON.stringify({ email });\n headers = { \"Content-Type\": \"application/json\" };\n }\n\n const response = await fetch(apiRoute, {\n method,\n headers,\n body: method !== \"GET\" ? bodyData : undefined,\n cache: \"no-store\",\n });\n\n const data = await response.json();\n\n if (response.ok && data.success) {\n setMessage(data.message || successMessage);\n setEmail(\"\");\n setAcceptedTerms(false);\n } else {\n setMessage(data.error || errorMessage);\n }\n } catch {\n setMessage(errorMessage);\n } finally {\n setIsLoading(false);\n }\n };\n\n // Convertimos las props de colores a Variables CSS nativas.\n const customCssVariables = {\n \"--nws-accent\": accentColor,\n \"--nws-text\": textColor,\n \"--nws-border\": borderColor,\n \"--nws-btn-text\": buttonTextColor,\n } as React.CSSProperties;\n\n return (\n <div\n className={`${styles.container} ${containerClassName}`}\n style={customCssVariables}\n >\n <form\n onSubmit={handleSubmit}\n className={`${styles.form} ${styles[layout]}`}\n >\n {/* Título */}\n {title && <span className={styles.title}>{title}</span>}\n\n {/* Input */}\n <input\n type=\"email\"\n placeholder={placeholder}\n className={styles.input}\n aria-label=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n disabled={isLoading}\n />\n\n {/* Grupo Acciones (Checkbox + Botón) */}\n <div\n className={`${styles.actions} ${\n layout === \"horizontal\"\n ? styles.actionsHorizontal\n : styles.actionsVertical\n }`}\n >\n {/* Checkbox */}\n <label className={styles.checkboxLabel}>\n <input\n type=\"checkbox\"\n className={styles.checkbox}\n checked={acceptedTerms}\n onChange={(e) => setAcceptedTerms(e.target.checked)}\n required\n disabled={isLoading}\n />\n <span>\n {termsText}{\" \"}\n <Link\n href={termsLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.termsLink}\n >\n {termsLinkText}\n </Link>\n </span>\n </label>\n\n {/* Botón */}\n <button\n type=\"submit\"\n disabled={isLoading}\n className={styles.button}\n >\n {isLoading ? \"Enviando...\" : buttonText}\n </button>\n </div>\n </form>\n\n {/* Mensaje */}\n {message && (\n <p\n className={`${styles.message} ${\n layout === \"horizontal\"\n ? styles.messageHorizontal\n : styles.messageVertical\n }`}\n >\n {message}\n </p>\n )}\n </div>\n );\n}","/* XNewsletter.module.css */\n\n.container {\n /* Estas variables recibirán sus valores desde React */\n --nws-accent: var(--accent);\n --nws-text: var(--text);\n --nws-border: var(--border);\n --nws-btn-text: var(--accent-text);\n \n width: 100%;\n font-family: \"EB Garamond\", serif;\n}\n\n/* --- Layouts Base --- */\n.form {\n display: flex;\n gap: 1rem;\n}\n\n.horizontal {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n@media (min-width: 768px) {\n .horizontal {\n flex-direction: row;\n }\n}\n\n.vertical {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n max-width: 24rem; /* equivalente a max-w-sm */\n margin: 0 auto;\n}\n\n/* --- Elementos --- */\n.title {\n font-size: 0.875rem;\n white-space: nowrap;\n font-weight: 500;\n color: var(--nws-text);\n}\n\n.input {\n width: 100%;\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n border-radius: 0.5rem;\n border: 1px solid var(--nws-border);\n background-color: transparent;\n outline: none;\n transition: border-color 0.2s ease;\n color: var(--nws-text);\n caret-color: var(--nws-accent);\n font-family: inherit;\n}\n\n.horizontal .input {\n /* En escritorio, el input horizontal es de tamaño fijo (md:w-64) */\n}\n@media (min-width: 768px) {\n .horizontal .input {\n width: 16rem; \n }\n}\n\n.input:focus {\n border-color: var(--nws-accent);\n}\n\n/* --- Checkbox y Botón --- */\n.actions {\n display: flex;\n gap: 1rem;\n}\n\n.actionsHorizontal {\n flex-direction: row;\n align-items: center;\n}\n\n.actionsVertical {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n}\n\n.checkboxLabel {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n white-space: nowrap;\n cursor: pointer;\n color: var(--nws-text);\n}\n\n.checkboxLabel span {\n opacity: 0.7;\n}\n\n.checkbox {\n height: 0.875rem;\n width: 0.875rem;\n border-radius: 0.125rem;\n cursor: pointer;\n accent-color: var(--nws-accent);\n}\n\n.termsLink {\n text-decoration: underline;\n color: var(--nws-accent);\n transition: opacity 0.2s ease;\n}\n\n.termsLink:hover {\n opacity: 1;\n}\n\n.button {\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n border-radius: 0.5rem;\n border: 1px solid var(--nws-accent);\n color: var(--nws-accent);\n background-color: transparent;\n transition: all 0.2s ease;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.button:hover:not(:disabled) {\n background-color: var(--nws-accent);\n color: var(--nws-btn-text);\n}\n\n.button:disabled, .input:disabled, .checkbox:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.actionsVertical .button {\n width: 100%;\n}\n\n/* --- Feedback Message --- */\n.message {\n margin-top: 0.75rem;\n font-size: 0.75rem;\n color: var(--nws-accent);\n}\n\n.messageHorizontal {\n text-align: center;\n}\n\n.messageVertical {\n text-align: left;\n}"],"mappings":"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","names":["useState","jsx","jsxs","useState"]}
@@ -0,0 +1,247 @@
1
+ // src/components/social/xsocialcontact/XSocialContact.module.css
2
+ var XSocialContact_default = {};
3
+
4
+ // src/components/social/xsocialcontact/XSocialContact.tsx
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function XSocialContact({
7
+ items,
8
+ columns = 3,
9
+ rows,
10
+ size = "medium",
11
+ alignment = "center",
12
+ gap,
13
+ backgroundColor,
14
+ iconDefaultColor,
15
+ iconDefaultHoverColor,
16
+ borderColor,
17
+ borderWidth,
18
+ borderStyle = "solid",
19
+ borderRadius = "rounded",
20
+ padding,
21
+ textAlign = "center",
22
+ textColor,
23
+ textSize
24
+ }) {
25
+ const sizeMap = {
26
+ small: "1rem",
27
+ medium: "1.5rem",
28
+ large: "2rem"
29
+ };
30
+ const alignmentMap = {
31
+ left: "flex-start",
32
+ center: "center",
33
+ right: "flex-end"
34
+ };
35
+ const textAlignMap = {
36
+ left: "left",
37
+ center: "center",
38
+ right: "right"
39
+ };
40
+ const radiusMap = {
41
+ rounded: "0.5rem",
42
+ square: "0"
43
+ };
44
+ const defaultGap = gap || (size === "small" ? "1rem" : size === "medium" ? "1.5rem" : "2rem");
45
+ const defaultPadding = padding || (size === "small" ? "1rem" : size === "medium" ? "1.5rem" : "2rem");
46
+ const defaultTextSize = textSize || (size === "small" ? "0.875rem" : size === "medium" ? "1rem" : "1.125rem");
47
+ const customStyles = {
48
+ "--columns": columns.toString(),
49
+ "--gap": defaultGap,
50
+ "--padding": defaultPadding,
51
+ "--text-size": defaultTextSize,
52
+ "--alignment": alignmentMap[alignment],
53
+ "--text-align": textAlignMap[textAlign],
54
+ "--icon-gap": sizeMap[size],
55
+ "--border-radius": radiusMap[borderRadius],
56
+ ...backgroundColor && { "--bg-color": backgroundColor },
57
+ ...iconDefaultColor && { "--icon-color": iconDefaultColor },
58
+ ...iconDefaultHoverColor && { "--icon-hover-color": iconDefaultHoverColor },
59
+ ...borderColor && { "--border-color": borderColor },
60
+ ...borderWidth && { "--border-width": borderWidth },
61
+ ...textColor && { "--text-color": textColor },
62
+ "--border-style": borderStyle
63
+ };
64
+ let containerClass = XSocialContact_default.container;
65
+ if (rows) {
66
+ containerClass += ` ${XSocialContact_default[`rows${rows}`]}`;
67
+ }
68
+ return /* @__PURE__ */ jsx(
69
+ "div",
70
+ {
71
+ className: `${containerClass} ${XSocialContact_default[size]}`,
72
+ style: customStyles,
73
+ children: items.map((item) => /* @__PURE__ */ jsxs(
74
+ "a",
75
+ {
76
+ href: item.href,
77
+ target: "_blank",
78
+ rel: "noopener noreferrer",
79
+ className: XSocialContact_default.item,
80
+ title: item.label,
81
+ style: {
82
+ ...item.iconColor && { "--item-icon-color": item.iconColor },
83
+ ...item.iconHoverColor && { "--item-icon-hover-color": item.iconHoverColor }
84
+ },
85
+ children: [
86
+ /* @__PURE__ */ jsx("div", { className: XSocialContact_default.iconWrapper, children: item.icon }),
87
+ item.text && /* @__PURE__ */ jsx("span", { className: XSocialContact_default.text, children: item.text })
88
+ ]
89
+ },
90
+ item.id
91
+ ))
92
+ }
93
+ );
94
+ }
95
+
96
+ // src/components/social/xsocialcontact/XSocialIcons.tsx
97
+ import { useState } from "react";
98
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
99
+ function XSocialIconShell({
100
+ size = 24,
101
+ color = "currentColor",
102
+ hoverColor,
103
+ fillColor,
104
+ hoverFillColor,
105
+ backgroundColor,
106
+ badgeColor,
107
+ badgeBackgroundColor,
108
+ strokeWidth = 1.8,
109
+ showBadge = true,
110
+ title,
111
+ style,
112
+ children,
113
+ ...rest
114
+ }) {
115
+ const [isHovered, setIsHovered] = useState(false);
116
+ const stroke = isHovered && hoverColor ? hoverColor : color;
117
+ const fill = isHovered && hoverFillColor ? hoverFillColor : fillColor || stroke;
118
+ const badgeStroke = badgeColor || stroke;
119
+ const badgeFill = badgeBackgroundColor || "transparent";
120
+ const palette = {
121
+ stroke,
122
+ fill,
123
+ badgeStroke,
124
+ badgeFill
125
+ };
126
+ return /* @__PURE__ */ jsxs2(
127
+ "svg",
128
+ {
129
+ xmlns: "http://www.w3.org/2000/svg",
130
+ width: size,
131
+ height: size,
132
+ viewBox: "0 0 24 24",
133
+ fill: "none",
134
+ role: title ? "img" : "presentation",
135
+ "aria-label": title,
136
+ "aria-hidden": title ? void 0 : true,
137
+ onPointerEnter: () => setIsHovered(true),
138
+ onPointerLeave: () => setIsHovered(false),
139
+ style: { color: stroke, ...style ?? {} },
140
+ ...rest,
141
+ children: [
142
+ title ? /* @__PURE__ */ jsx2("title", { children: title }) : null,
143
+ /* @__PURE__ */ jsx2(
144
+ "circle",
145
+ {
146
+ cx: "12",
147
+ cy: "12",
148
+ r: "10.5",
149
+ fill: backgroundColor || "none",
150
+ stroke: backgroundColor ? "none" : stroke,
151
+ strokeOpacity: backgroundColor ? void 0 : 0.14,
152
+ strokeWidth: backgroundColor ? void 0 : strokeWidth
153
+ }
154
+ ),
155
+ children({ palette }),
156
+ showBadge && /* @__PURE__ */ jsxs2("g", { children: [
157
+ /* @__PURE__ */ jsx2("circle", { cx: "18", cy: "18", r: "2.6", fill: badgeFill, stroke: badgeStroke, strokeWidth: "1" }),
158
+ /* @__PURE__ */ jsx2("path", { d: "M17.05 17.05L18.95 18.95M18.95 17.05L17.05 18.95", stroke: badgeStroke, strokeWidth: "1.15", strokeLinecap: "round" })
159
+ ] })
160
+ ]
161
+ }
162
+ );
163
+ }
164
+ function XTelegramIcon(props) {
165
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.8, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
166
+ /* @__PURE__ */ jsx2(
167
+ "path",
168
+ {
169
+ d: "M9.2 12.4l2.15 2.15 5.1-5.1M20.6 4.2L4 12l6.45 1.8 1.8 6.45 2.55-4.2 4.2 2.55 1.6-14.4z",
170
+ stroke: palette.stroke,
171
+ strokeWidth: "1.8",
172
+ strokeLinecap: "round",
173
+ strokeLinejoin: "round",
174
+ fill: "none"
175
+ }
176
+ ),
177
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "9.75", fill: "none", stroke: palette.stroke, strokeOpacity: "0.18", strokeWidth: "1" })
178
+ ] }) });
179
+ }
180
+ function XInstagramIcon(props) {
181
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.6, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
182
+ /* @__PURE__ */ jsx2("rect", { x: "6.2", y: "6.2", width: "11.6", height: "11.6", rx: "3.2", ry: "3.2", stroke: palette.stroke, strokeWidth: "1.6", fill: "none" }),
183
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3.15", stroke: palette.stroke, strokeWidth: "1.6", fill: "none" }),
184
+ /* @__PURE__ */ jsx2("circle", { cx: "16.3", cy: "7.7", r: "0.7", fill: palette.fill })
185
+ ] }) });
186
+ }
187
+ function XWhatsappIcon(props) {
188
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.5, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
189
+ /* @__PURE__ */ jsx2(
190
+ "path",
191
+ {
192
+ d: "M16.72 13.06c-.29-.15-1.71-.84-1.98-.94-.26-.1-.45-.15-.64.14-.19.29-.74.94-.9 1.13-.16.19-.33.22-.62.08-.29-.15-1.23-.45-2.35-1.45-.87-.77-1.45-1.72-1.62-2.01-.16-.29-.02-.45.12-.59.13-.13.29-.33.43-.49.14-.16.18-.28.27-.47.09-.19.04-.36-.02-.51-.07-.15-.64-1.54-.88-2.1-.23-.55-.47-.48-.64-.49-.16-.01-.36-.01-.55-.01-.19 0-.5.07-.76.36-.26.29-1 1.01-1 2.47 0 1.45 1.04 2.85 1.19 3.05.15.19 2.05 3.12 5.2 4.38.73.31 1.3.49 1.74.63.73.23 1.4.2 1.92.12.59-.09 1.71-.7 1.95-1.37.24-.67.24-1.25.17-1.37-.07-.11-.26-.18-.55-.32z",
193
+ fill: palette.fill
194
+ }
195
+ ),
196
+ /* @__PURE__ */ jsx2(
197
+ "path",
198
+ {
199
+ d: "M12 3.2C7.13 3.2 3.2 7.13 3.2 12c0 1.56.41 3.02 1.13 4.29L3.2 20.8l4.59-1.09A8.77 8.77 0 0 0 12 20.8c4.87 0 8.8-3.93 8.8-8.8s-3.93-8.8-8.8-8.8z",
200
+ stroke: palette.stroke,
201
+ strokeWidth: "1.2",
202
+ fill: "none",
203
+ opacity: "0.18"
204
+ }
205
+ )
206
+ ] }) });
207
+ }
208
+ function XEmailIcon(props) {
209
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.6, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
210
+ /* @__PURE__ */ jsx2("rect", { x: "4.5", y: "7", width: "15", height: "10", rx: "1.4", stroke: palette.stroke, strokeWidth: "1.6", fill: "none" }),
211
+ /* @__PURE__ */ jsx2("path", { d: "M4.6 7.1l7.4 5.5 7.4-5.5", stroke: palette.stroke, strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })
212
+ ] }) });
213
+ }
214
+ function XLinkedInIcon(props) {
215
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.6, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
216
+ /* @__PURE__ */ jsx2("path", { d: "M8.1 9.1l2.6 2.6 4.1-4.1", stroke: palette.stroke, strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
217
+ /* @__PURE__ */ jsx2("path", { d: "M6.8 10.2c1.6-1.6 4.3-1.6 5.9 0", stroke: palette.stroke, strokeWidth: "1.6", strokeLinecap: "round", fill: "none" }),
218
+ /* @__PURE__ */ jsx2("rect", { x: "5", y: "5", width: "14", height: "14", rx: "3", ry: "3", stroke: palette.stroke, strokeWidth: "1.4", fill: "none", opacity: "0.12" })
219
+ ] }) });
220
+ }
221
+ function XTwitterIcon(props) {
222
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.6, children: ({ palette }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
223
+ /* @__PURE__ */ jsx2("path", { d: "M7 4l7 8.7L7 21h2.2l7-8.7L21 4h-2.2l-7 8.7L7 4z", fill: palette.fill }),
224
+ /* @__PURE__ */ jsx2("path", { d: "M8 4h2.2l6.2 7.7", stroke: palette.stroke, strokeWidth: "1.2", strokeLinecap: "round", fill: "none", opacity: "0.2" })
225
+ ] }) });
226
+ }
227
+ function XGitHubIcon(props) {
228
+ return /* @__PURE__ */ jsx2(XSocialIconShell, { ...props, strokeWidth: props.strokeWidth ?? 1.35, children: ({ palette }) => /* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2(
229
+ "path",
230
+ {
231
+ d: "M12 2c5.52 0 10 4.48 10 10 0 4.42-2.87 8.17-6.84 9.49.5.09.68-.22.68-.48 0-.24-.01-.87-.01-1.7 2.78.6 3.37-1.34 3.37-1.34.45-1.16 1.11-1.46 1.11-1.46.91-.62-.07-.61-.07-.61-1 .07-1.53 1.03-1.53 1.03-.89 1.53-2.34 1.54-2.91 1.19-.09-.92-.35-1.54-.63-1.9 2.22-.25 4.55-1.11 4.55-4.94 0-1.09-.39-1.98-1.03-2.68.1-.25.45-1.27-.1-2.65 0 0-.84-.27-2.75 1.03A9.58 9.58 0 0 0 12 6.84c-.85 0-1.7.12-2.51.34-1.91-1.3-2.75-1.03-2.75-1.03-.54 1.38-.2 2.4-.1 2.65-.63.7-1.03 1.59-1.03 2.68 0 3.84 2.33 4.69 4.54 4.94-.29.36-.55.97-.64 1.9-.57.35-2.02.34-2.91-1.19 0 0-.52-.96-1.53-1.03 0 0-.98-.01-.07.61 0 0 .66.3 1.11 1.46 0 0 .59 1.94 3.37 1.34 0 .83-.01 1.46-.01 1.7 0 .26.18.57.68.48C5.87 20.17 3 16.42 3 12 3 6.48 7.48 2 12 2z",
232
+ fill: palette.fill
233
+ }
234
+ ) }) });
235
+ }
236
+
237
+ export {
238
+ XSocialContact,
239
+ XTelegramIcon,
240
+ XInstagramIcon,
241
+ XWhatsappIcon,
242
+ XEmailIcon,
243
+ XLinkedInIcon,
244
+ XTwitterIcon,
245
+ XGitHubIcon
246
+ };
247
+ //# sourceMappingURL=chunk-U27ZVCP7.mjs.map