@dotrino/support 0.6.0 → 0.7.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/README.md +2 -0
- package/package.json +1 -1
- package/src/index.js +35 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @dotrino/support
|
|
2
2
|
|
|
3
|
+
> **Parte del ecosistema [Dotrino](https://dotrino.com).** Misión: aplicaciones que resuelven problemas comunes, respetando tu privacidad — sin anuncios, sin cookies, sin rastreo de datos, sin vender tu identidad a nadie.
|
|
4
|
+
|
|
3
5
|
Web Component (`<dotrino-support>`) con un **modal de soporte/donaciones**
|
|
4
6
|
reutilizable por **cualquier app del ecosistema Dotrino**: las hechas en
|
|
5
7
|
Vue 3 y las vanilla (HTML/JS), porque es un *custom element* estándar.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dotrino/support",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Web Component (custom element) de modal de soporte/donaciones reutilizable por cualquier app del ecosistema Dotrino. Autohosteado, sin JS de terceros ni cookies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/index.js
CHANGED
|
@@ -44,6 +44,7 @@ const I18N = {
|
|
|
44
44
|
'Si esta herramienta te resulta útil, puedes dar una pequeña contribución. Las apps del ecosistema Dotrino son gratuitas y autohosteadas. ¡Gracias!',
|
|
45
45
|
close: 'Cerrar',
|
|
46
46
|
defaultLink: 'Donar',
|
|
47
|
+
contact: 'Contacto',
|
|
47
48
|
hint: 'Donar/Compartir',
|
|
48
49
|
shareHeading: 'Compartir',
|
|
49
50
|
shareText: '¡Mira esto!',
|
|
@@ -64,6 +65,7 @@ const I18N = {
|
|
|
64
65
|
'If you find this tool useful, you can make a small contribution. The Dotrino ecosystem apps are free and self-hosted. Thank you!',
|
|
65
66
|
close: 'Close',
|
|
66
67
|
defaultLink: 'Donate',
|
|
68
|
+
contact: 'Contact',
|
|
67
69
|
hint: 'Donate/Share',
|
|
68
70
|
shareHeading: 'Share',
|
|
69
71
|
shareText: 'Check this out!',
|
|
@@ -340,6 +342,19 @@ const STYLE = `
|
|
|
340
342
|
.link-ico { display: inline-flex; width: 1.4rem; height: 1.4rem; }
|
|
341
343
|
.link-ico img { width: 100%; height: 100%; display: block; object-fit: contain; }
|
|
342
344
|
|
|
345
|
+
/* Botón de Contacto (opt-in), arriba de las donaciones. Contorno para
|
|
346
|
+
diferenciarlo del botón lleno de "Donar". */
|
|
347
|
+
.contact-cta {
|
|
348
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
349
|
+
min-width: 220px; margin: 0 auto 0.9rem; padding: 0.7rem 1.4rem;
|
|
350
|
+
font-family: inherit; font-weight: 600; font-size: 0.95rem;
|
|
351
|
+
border-radius: 50px; cursor: pointer;
|
|
352
|
+
background: transparent; color: var(--ds-accent, #3498db);
|
|
353
|
+
border: 1.5px solid var(--ds-accent, #3498db);
|
|
354
|
+
transition: all 0.25s ease;
|
|
355
|
+
}
|
|
356
|
+
.contact-cta:hover { background: var(--ds-accent, #3498db); color: #fff; transform: translateY(-2px); box-shadow: 0 6px 20px rgba(52, 152, 219, 0.3); }
|
|
357
|
+
|
|
343
358
|
/* Sección de compartir */
|
|
344
359
|
.share {
|
|
345
360
|
margin-top: 1.5rem;
|
|
@@ -477,7 +492,7 @@ function recordAppOpen(appId) {
|
|
|
477
492
|
|
|
478
493
|
class DotrinoSupport extends HTMLElement {
|
|
479
494
|
static get observedAttributes() {
|
|
480
|
-
return ['href', 'links', 'cta', 'no-trigger', 'heading', 'message', 'lang', 'variant', 'inline', 'hint', 'coin', 'no-bubble', 'bubble-timeout', 'share-url', 'share-text', 'no-share', 'repo', 'bug-href', 'discord', 'app', 'no-count']
|
|
495
|
+
return ['href', 'links', 'cta', 'no-trigger', 'heading', 'message', 'lang', 'variant', 'inline', 'hint', 'coin', 'no-bubble', 'bubble-timeout', 'share-url', 'share-text', 'no-share', 'repo', 'bug-href', 'discord', 'app', 'no-count', 'contact', 'contact-label']
|
|
481
496
|
}
|
|
482
497
|
|
|
483
498
|
constructor() {
|
|
@@ -731,6 +746,15 @@ class DotrinoSupport extends HTMLElement {
|
|
|
731
746
|
)
|
|
732
747
|
.join('')
|
|
733
748
|
|
|
749
|
+
// Botón de Contacto (opt-in con el atributo `contact`), ARRIBA de las
|
|
750
|
+
// donaciones. No abre un enlace: dispara `cc-support-contact` (la app decide
|
|
751
|
+
// qué hacer, p. ej. abrir su formulario) y cierra el modal.
|
|
752
|
+
const wantsContact = this.hasAttribute('contact')
|
|
753
|
+
const contactLabel = this.getAttribute('contact-label') || t.contact
|
|
754
|
+
const contactHtml = wantsContact
|
|
755
|
+
? `<button type="button" class="contact-cta" part="contact">${escapeHtml(contactLabel)}</button>`
|
|
756
|
+
: ''
|
|
757
|
+
|
|
734
758
|
const wantsShare = !this.hasAttribute('no-share')
|
|
735
759
|
const shareHtml = wantsShare
|
|
736
760
|
? `<div class="share" part="share">
|
|
@@ -771,6 +795,7 @@ class DotrinoSupport extends HTMLElement {
|
|
|
771
795
|
<button type="button" class="close" aria-label="${escapeAttr(t.close)}">×</button>
|
|
772
796
|
<h2 class="heading">${escapeHtml(heading)}</h2>
|
|
773
797
|
<p class="message">${escapeHtml(message)}</p>
|
|
798
|
+
${contactHtml}
|
|
774
799
|
<div class="links">${linksHtml}</div>
|
|
775
800
|
${shareHtml}
|
|
776
801
|
${discordHtml}
|
|
@@ -792,6 +817,15 @@ class DotrinoSupport extends HTMLElement {
|
|
|
792
817
|
)
|
|
793
818
|
this.shadowRoot.querySelector('.close').addEventListener('click', () => this.close())
|
|
794
819
|
|
|
820
|
+
// Botón de Contacto: cierra el modal y avisa a la app (que abre su formulario).
|
|
821
|
+
const contactBtn = this.shadowRoot.querySelector('.contact-cta')
|
|
822
|
+
if (contactBtn) {
|
|
823
|
+
contactBtn.addEventListener('click', () => {
|
|
824
|
+
this.close()
|
|
825
|
+
this.dispatchEvent(new CustomEvent('cc-support-contact', { bubbles: true, composed: true }))
|
|
826
|
+
})
|
|
827
|
+
}
|
|
828
|
+
|
|
795
829
|
// Compartir: el botón sin href (Instagram) copia el enlace al portapapeles.
|
|
796
830
|
this.shadowRoot.querySelectorAll('.share-btn[data-share]').forEach((btn) => {
|
|
797
831
|
btn.addEventListener('click', () => this._copyShareUrl())
|