@dile/ui 2.19.0 → 2.20.1
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/components/copy-markdown-url/README.md +87 -0
- package/components/copy-markdown-url/copy-markdown-url.js +3 -0
- package/components/copy-markdown-url/index.js +5 -0
- package/components/copy-markdown-url/src/DileCopyMarkdownUrl.js +101 -0
- package/components/copy-text/src/DileCopyText.js +10 -6
- package/package.json +2 -2
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# dile-copy-markdown-url
|
|
2
|
+
|
|
3
|
+
Un componente Web que permite copiar el contenido de una URL al portapapeles. Reutiliza el componente `dile-copy-text` y usa fetch para obtener el contenido de la URL de forma simple y eficiente.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @dile/ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Importación
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import '@dile/ui/components/copy-markdown-url/copy-markdown-url.js';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Uso
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<dile-copy-markdown-url
|
|
21
|
+
url="https://ejemplo.com/archivo.md"
|
|
22
|
+
>
|
|
23
|
+
Copiar markdown
|
|
24
|
+
</dile-copy-markdown-url>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Propiedades
|
|
28
|
+
|
|
29
|
+
- **url** (String): La URL del contenido a copiar
|
|
30
|
+
- **copiedDuration** (Number): Duración en milisegundos del feedback de copia (por defecto: 1000)
|
|
31
|
+
- **feedbackText** (String): Texto del feedback visual (por defecto: 'Copied!')
|
|
32
|
+
- **hideIcon** (Boolean): Ocultar el icono en el feedback (por defecto: false)
|
|
33
|
+
|
|
34
|
+
## Eventos
|
|
35
|
+
|
|
36
|
+
Hereda todos los eventos de `dile-copy-text`:
|
|
37
|
+
|
|
38
|
+
- **dile-text-copied**: Se dispara cuando el contenido se ha copiado correctamente
|
|
39
|
+
- `detail.text`: El contenido que se copió
|
|
40
|
+
|
|
41
|
+
Además, dispara:
|
|
42
|
+
|
|
43
|
+
- **dile-copy-markdown-url-error**: Se dispara cuando hay un error al obtener el contenido de la URL
|
|
44
|
+
- `detail.message`: Descripción del error
|
|
45
|
+
|
|
46
|
+
## Estilos CSS personalizables
|
|
47
|
+
|
|
48
|
+
El componente hereda los estilos de `dile-copy-text`, así que puedes usar las mismas variables CSS:
|
|
49
|
+
|
|
50
|
+
- `--dile-copy-text-text-decoration`: Decoración del texto del enlace (por defecto: none)
|
|
51
|
+
- `--dile-copy-text-color`: Color del texto del enlace (por defecto: inherit)
|
|
52
|
+
- `--dile-copy-text-transition-duration`: Duración de la transición (por defecto: 0.3s)
|
|
53
|
+
- `--dile-copy-text-hover-color`: Color del texto al hacer hover (por defecto: #0066cc)
|
|
54
|
+
- `--dile-copy-text-hover-text-decoration`: Decoración al hacer hover (por defecto: underline)
|
|
55
|
+
- `--dile-copy-text-focus-outline`: Contorno al tener enfoque (por defecto: 2px solid #0066cc)
|
|
56
|
+
|
|
57
|
+
## Ejemplo completo
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<dile-copy-markdown-url
|
|
61
|
+
url="https://raw.githubusercontent.com/user/repo/main/README.md"
|
|
62
|
+
feedbackText="¡Markdown copiado!"
|
|
63
|
+
copiedDuration="2000"
|
|
64
|
+
>
|
|
65
|
+
📋 Copiar README
|
|
66
|
+
</dile-copy-markdown-url>
|
|
67
|
+
|
|
68
|
+
<script type="module">
|
|
69
|
+
const copyBtn = document.querySelector('dile-copy-markdown-url');
|
|
70
|
+
|
|
71
|
+
copyBtn.addEventListener('dile-text-copied', (e) => {
|
|
72
|
+
console.log('Contenido copiado:', e.detail.text);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
copyBtn.addEventListener('dile-copy-markdown-url-error', (e) => {
|
|
76
|
+
console.error('Error:', e.detail.message);
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Comportamiento
|
|
82
|
+
|
|
83
|
+
1. El usuario hace click en el componente
|
|
84
|
+
2. Si es la primera vez, el componente hace un fetch a la URL especificada
|
|
85
|
+
3. Una vez obtiene el contenido, automáticamente lo copia al portapapeles
|
|
86
|
+
4. Se muestra un feedback visual indicando que el contenido se copió
|
|
87
|
+
5. En los siguientes clicks, el contenido ya está cacheado y se copia directamente
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { LitElement, html } from 'lit';
|
|
2
|
+
import '../../copy-text/copy-text.js';
|
|
3
|
+
|
|
4
|
+
export class DileCopyMarkdownUrl extends LitElement {
|
|
5
|
+
static get properties() {
|
|
6
|
+
return {
|
|
7
|
+
url: { type: String },
|
|
8
|
+
copiedDuration: { type: Number },
|
|
9
|
+
feedbackText: { type: String },
|
|
10
|
+
hideIcon: { type: Boolean },
|
|
11
|
+
loading: { type: Boolean, state: true },
|
|
12
|
+
error: { type: String, state: true },
|
|
13
|
+
content: { type: String, state: true }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.url = '';
|
|
20
|
+
this.copiedDuration = 1000;
|
|
21
|
+
this.feedbackText = 'Copied!';
|
|
22
|
+
this.hideIcon = false;
|
|
23
|
+
this.loading = false;
|
|
24
|
+
this.error = null;
|
|
25
|
+
this.content = '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
render() {
|
|
29
|
+
return html`
|
|
30
|
+
<dile-copy-text
|
|
31
|
+
id="copy-component"
|
|
32
|
+
.content="${this.content}"
|
|
33
|
+
.feedbackText="${this.feedbackText}"
|
|
34
|
+
.copiedDuration="${this.copiedDuration}"
|
|
35
|
+
?hideIcon="${this.hideIcon}"
|
|
36
|
+
>
|
|
37
|
+
<slot></slot>
|
|
38
|
+
</dile-copy-text>
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
connectedCallback() {
|
|
43
|
+
super.connectedCallback();
|
|
44
|
+
// Listen in capture phase to intercept click before dile-copy-text handles it
|
|
45
|
+
this.addEventListener('click', (e) => this.handleClickCapture(e), true);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async handleClickCapture(e) {
|
|
49
|
+
// If no content yet and URL is set, fetch before letting dile-copy-text handle the copy
|
|
50
|
+
if (!this.content && this.url) {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
|
|
54
|
+
await this.fetchContent();
|
|
55
|
+
|
|
56
|
+
// Only trigger copy if fetch was successful
|
|
57
|
+
if (this.content && !this.error) {
|
|
58
|
+
const copyComponent = this.shadowRoot.querySelector('#copy-component');
|
|
59
|
+
if (copyComponent) {
|
|
60
|
+
await copyComponent.copy();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async fetchContent() {
|
|
67
|
+
if (!this.url) {
|
|
68
|
+
this.error = 'URL is not set';
|
|
69
|
+
this.dispatchError(this.error);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.loading = true;
|
|
74
|
+
this.error = null;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(this.url);
|
|
78
|
+
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.content = await response.text();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.error = err.message || 'Error fetching content';
|
|
86
|
+
this.dispatchError(this.error);
|
|
87
|
+
} finally {
|
|
88
|
+
this.loading = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
dispatchError(message) {
|
|
93
|
+
this.dispatchEvent(
|
|
94
|
+
new CustomEvent('dile-copy-markdown-url-error', {
|
|
95
|
+
detail: { message },
|
|
96
|
+
bubbles: true,
|
|
97
|
+
composed: true
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -30,7 +30,7 @@ export class DileCopyText extends LitElement {
|
|
|
30
30
|
|
|
31
31
|
static get properties() {
|
|
32
32
|
return {
|
|
33
|
-
|
|
33
|
+
content: { type: String },
|
|
34
34
|
copiedDuration: { type: Number },
|
|
35
35
|
feedbackText: { type: String },
|
|
36
36
|
hideIcon: { type: Boolean }
|
|
@@ -39,7 +39,7 @@ export class DileCopyText extends LitElement {
|
|
|
39
39
|
|
|
40
40
|
constructor() {
|
|
41
41
|
super();
|
|
42
|
-
this.
|
|
42
|
+
this.content = '';
|
|
43
43
|
this.copiedDuration = 1000; // 2 seconds by default
|
|
44
44
|
this.feedbackText = 'Copied!';
|
|
45
45
|
this.hideIcon = false;
|
|
@@ -83,7 +83,7 @@ export class DileCopyText extends LitElement {
|
|
|
83
83
|
try {
|
|
84
84
|
// Try to use Clipboard API first (modern browsers)
|
|
85
85
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
86
|
-
await navigator.clipboard.writeText(this.
|
|
86
|
+
await navigator.clipboard.writeText(this.content);
|
|
87
87
|
} else {
|
|
88
88
|
// Fallback for older browsers
|
|
89
89
|
this.copyWithExecCommand();
|
|
@@ -92,7 +92,7 @@ export class DileCopyText extends LitElement {
|
|
|
92
92
|
// Dispatch custom event
|
|
93
93
|
this.dispatchEvent(
|
|
94
94
|
new CustomEvent('dile-text-copied', {
|
|
95
|
-
detail: { text: this.
|
|
95
|
+
detail: { text: this.content },
|
|
96
96
|
bubbles: true,
|
|
97
97
|
composed: true
|
|
98
98
|
})
|
|
@@ -107,7 +107,7 @@ export class DileCopyText extends LitElement {
|
|
|
107
107
|
this.copyWithExecCommand();
|
|
108
108
|
this.dispatchEvent(
|
|
109
109
|
new CustomEvent('dile-text-copied', {
|
|
110
|
-
detail: { text: this.
|
|
110
|
+
detail: { text: this.content },
|
|
111
111
|
bubbles: true,
|
|
112
112
|
composed: true
|
|
113
113
|
})
|
|
@@ -121,7 +121,7 @@ export class DileCopyText extends LitElement {
|
|
|
121
121
|
|
|
122
122
|
copyWithExecCommand() {
|
|
123
123
|
const textArea = document.createElement('textarea');
|
|
124
|
-
textArea.value = this.
|
|
124
|
+
textArea.value = this.content;
|
|
125
125
|
textArea.style.position = 'fixed';
|
|
126
126
|
textArea.style.left = '-999999px';
|
|
127
127
|
textArea.style.top = '-999999px';
|
|
@@ -141,4 +141,8 @@ export class DileCopyText extends LitElement {
|
|
|
141
141
|
feedback.show();
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
async copy() {
|
|
146
|
+
await this.copyToClipboard();
|
|
147
|
+
}
|
|
144
148
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dile/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.1",
|
|
4
4
|
"description": "UI Core components from dile-components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "7194ae653716358e673eb70383662cfb86247260"
|
|
30
30
|
}
|