@jjlmoya/utils-creative 1.4.0 → 1.6.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.
@@ -1,21 +1,28 @@
1
1
  ---
2
2
  import { Icon } from 'astro-icon/components';
3
+ import type { ZalgoGeneratorUI } from './index';
4
+
5
+ interface Props {
6
+ ui: ZalgoGeneratorUI;
7
+ }
8
+
9
+ const { ui } = Astro.props;
3
10
  ---
4
11
 
5
- <section class="zg-section">
12
+ <section class="zg-section" id="zalgo-generator-root" data-ui={JSON.stringify(ui)}>
6
13
  <div class="zg-grid">
7
14
  <div class="zg-left">
8
15
  <div class="zg-config-card">
9
16
  <div class="zg-config-hover-bg"></div>
10
17
  <h3 class="zg-config-title">
11
18
  <Icon name="mdi:tune-variant" style="width:1.25rem;height:1.25rem;color:#9333ea" />
12
- Configuración
19
+ {ui.configTitle}
13
20
  </h3>
14
21
 
15
22
  <div class="zg-config-body">
16
23
  <div class="zg-field">
17
24
  <div class="zg-field-header">
18
- <label class="zg-field-label">Intensidad</label>
25
+ <label class="zg-field-label">{ui.intensity}</label>
19
26
  <span id="intensity-value" class="zg-intensity-val">50%</span>
20
27
  </div>
21
28
  <input type="range" id="intensity-slider" min="0.1" max="1.5" step="0.1" value="0.5" class="zg-slider" />
@@ -23,21 +30,21 @@ import { Icon } from 'astro-icon/components';
23
30
 
24
31
  <div class="zg-toggles">
25
32
  <label class="zg-toggle-row">
26
- <span class="zg-toggle-label">Corrupción Superior</span>
33
+ <span class="zg-toggle-label">{ui.upLabel}</span>
27
34
  <div class="zg-switch">
28
35
  <input type="checkbox" id="opt-up" checked class="zg-switch-input" />
29
36
  <div class="zg-switch-track"></div>
30
37
  </div>
31
38
  </label>
32
39
  <label class="zg-toggle-row">
33
- <span class="zg-toggle-label">Ruido Central</span>
40
+ <span class="zg-toggle-label">{ui.midLabel}</span>
34
41
  <div class="zg-switch">
35
42
  <input type="checkbox" id="opt-middle" checked class="zg-switch-input" />
36
43
  <div class="zg-switch-track"></div>
37
44
  </div>
38
45
  </label>
39
46
  <label class="zg-toggle-row">
40
- <span class="zg-toggle-label">Corrupción Inferior</span>
47
+ <span class="zg-toggle-label">{ui.downLabel}</span>
41
48
  <div class="zg-switch">
42
49
  <input type="checkbox" id="opt-down" checked class="zg-switch-input" />
43
50
  <div class="zg-switch-track"></div>
@@ -47,13 +54,13 @@ import { Icon } from 'astro-icon/components';
47
54
 
48
55
  <button id="reset-options" class="zg-reset-btn">
49
56
  <Icon name="mdi:history" style="width:1rem;height:1rem" />
50
- Restablecer Valores
57
+ {ui.resetBtn}
51
58
  </button>
52
59
  </div>
53
60
  </div>
54
61
 
55
62
  <div class="zg-warning">
56
- <p>ADVERTENCIA: El texto Zalgo utiliza caracteres combinados de Unicode que pueden desbordar visualmente su contenedor. Úsese con precaución en redes sociales.</p>
63
+ <p>{ui.warningText}</p>
57
64
  </div>
58
65
  </div>
59
66
 
@@ -68,14 +75,14 @@ import { Icon } from 'astro-icon/components';
68
75
  <textarea
69
76
  id="input-text"
70
77
  class="zg-textarea"
71
- placeholder="Escribe aquí el mensaje que deseas corromper..."
78
+ placeholder={ui.inputPlaceholder}
72
79
  ></textarea>
73
80
  <div class="zg-editor-footer">
74
- <span id="char-count" class="zg-char-count">0 CARACTERES</span>
81
+ <span id="char-count" class="zg-char-count">0 {ui.charLabel}</span>
75
82
  <div class="zg-footer-sep"></div>
76
83
  <button id="copy-btn" class="zg-copy-btn">
77
84
  <Icon name="mdi:content-copy" style="width:1.25rem;height:1.25rem" />
78
- Copiar Resultado
85
+ {ui.copyBtn}
79
86
  </button>
80
87
  <button id="clear-btn" class="zg-clear-btn">
81
88
  <Icon name="mdi:trash-can-outline" style="width:1.25rem;height:1.25rem" />
@@ -84,24 +91,28 @@ import { Icon } from 'astro-icon/components';
84
91
  </div>
85
92
 
86
93
  <div class="zg-preview-wrap">
87
- <div class="zg-preview-badge">Vista Previa en Tiempo Real</div>
94
+ <div class="zg-preview-badge">{ui.previewLabel}</div>
88
95
  <div id="fake-ui-body" class="zg-preview-body">
89
96
  <div class="zg-preview-dots"></div>
90
97
  <div id="zalgo-output" class="zg-output">
91
- <span class="zg-output-empty">Vacío</span>
98
+ <span class="zg-output-empty">{ui.emptyLabel}</span>
92
99
  </div>
93
100
  <div id="glitch-overlay" class="zg-glitch-overlay">
94
101
  <div class="zg-glitch-line zg-glitch-line-1"></div>
95
102
  <div class="zg-glitch-line zg-glitch-line-2"></div>
96
103
  </div>
97
104
  </div>
98
- <p class="zg-preview-note">Nota: Algunos navegadores pueden limitar el renderizado de caracteres combinados</p>
105
+ <p class="zg-preview-note">{ui.noteText}</p>
99
106
  </div>
100
107
  </div>
101
108
  </div>
102
109
  </section>
103
110
 
104
111
  <script>
112
+ import type { ZalgoGeneratorUI } from './index';
113
+ const root = document.getElementById('zalgo-generator-root') as HTMLElement;
114
+ const ui = JSON.parse(root.dataset.ui || '{}') as ZalgoGeneratorUI;
115
+
105
116
  const UP = ["\u030d","\u030e","\u0304","\u0305","\u033f","\u0311","\u0306","\u0310","\u0352","\u0357","\u0351","\u0307","\u0308","\u030a","\u0342","\u0343","\u0344","\u034a","\u034b","\u034c","\u0303","\u0302","\u030c","\u0350","\u0300","\u0301","\u030b","\u030f","\u0312","\u0313","\u0314","\u033d","\u0309","\u0363","\u0364","\u0365","\u0366","\u0367","\u0368","\u0369","\u036a","\u036b","\u036c","\u036d","\u036e","\u036f","\u033e","\u035b","\u0346","\u031a"];
106
117
  const MID = ["\u0315","\u031b","\u0340","\u0341","\u0358","\u0321","\u0322","\u0327","\u0328","\u0334","\u0335","\u0336","\u034f","\u035c","\u035d","\u035e","\u035f","\u0360","\u0362","\u0338","\u0337","\u0361","\u0489"];
107
118
  const DOWN = ["\u0316","\u0317","\u0318","\u0319","\u031c","\u031d","\u031e","\u031f","\u0320","\u0324","\u0325","\u0326","\u0329","\u032a","\u032b","\u032c","\u032d","\u032e","\u032f","\u0330","\u0331","\u0332","\u0333","\u0339","\u033a","\u033b","\u033c","\u0345","\u0347","\u0348","\u0349","\u034d","\u034e","\u0353","\u0354","\u0355","\u0356","\u0359","\u035a","\u0323"];
@@ -142,10 +153,10 @@ import { Icon } from 'astro-icon/components';
142
153
  function update() {
143
154
  const text = input.value;
144
155
  const intensity = parseFloat(intensitySlider.value);
145
- if (charCount) charCount.textContent = `${text.length} CARACTERES`;
156
+ if (charCount) charCount.textContent = `${text.length} ${ui.charLabel}`;
146
157
  if (intensityValue) intensityValue.textContent = `${Math.round(intensity * 100)}%`;
147
158
  if (!text.trim()) {
148
- output.innerHTML = '<span class="zg-output-empty">Vacío</span>';
159
+ output.innerHTML = `<span class="zg-output-empty">${ui.emptyLabel}</span>`;
149
160
  glitchOverlay.style.opacity = "0";
150
161
  fakeUiBody.style.borderColor = "";
151
162
  fakeUiBody.style.boxShadow = "";
@@ -174,10 +185,10 @@ import { Icon } from 'astro-icon/components';
174
185
 
175
186
  copyBtn?.addEventListener("click", () => {
176
187
  const text = output.textContent || "";
177
- if (text && text !== "Vacío") {
188
+ if (text && text !== ui.emptyLabel) {
178
189
  navigator.clipboard.writeText(text);
179
190
  const orig = copyBtn.innerHTML;
180
- copyBtn.innerHTML = "¡Copiado!";
191
+ copyBtn.innerHTML = ui.copied || '¡Copiado!';
181
192
  setTimeout(() => { copyBtn.innerHTML = orig; }, 2000);
182
193
  }
183
194
  });
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
15
15
  copyBtn: 'Copy Chaos',
16
16
  copied: 'Copied!',
17
17
  faqTitle: 'FAQ',
18
- bibliographyTitle: 'References'
18
+ bibliographyTitle: 'References',
19
+ configTitle: 'Configuration',
20
+ intensity: 'Intensity',
21
+ upLabel: 'Upper Corruption',
22
+ midLabel: 'Middle Noise',
23
+ downLabel: 'Lower Corruption',
24
+ resetBtn: 'Reset Values',
25
+ warningText: 'WARNING: Zalgo text uses combined Unicode characters that may visually overflow their container. Use with caution on social media.',
26
+ previewLabel: 'Real-time Preview',
27
+ emptyLabel: 'Empty',
28
+ charLabel: 'CHARACTERS',
29
+ noteText: 'Note: Some browsers may limit the rendering of combined characters'
19
30
  },
20
31
  seo: [
21
32
  { type: 'title', text: 'What Is Zalgo Text and How Does Visual Corruption Work?', level: 2 },
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
15
15
  copyBtn: 'Copiar Caos',
16
16
  copied: '¡Copiado!',
17
17
  faqTitle: 'FAQ',
18
- bibliographyTitle: 'Referencias'
18
+ bibliographyTitle: 'Referencias',
19
+ configTitle: 'Configuración',
20
+ intensity: 'Intensidad',
21
+ upLabel: 'Corrupción Superior',
22
+ midLabel: 'Ruido Central',
23
+ downLabel: 'Corrupción Inferior',
24
+ resetBtn: 'Restablecer Valores',
25
+ warningText: 'ADVERTENCIA: El texto Zalgo utiliza caracteres combinados de Unicode que pueden desbordar visualmente su contenedor. Úsese con precaución en redes sociales.',
26
+ previewLabel: 'Vista Previa en Tiempo Real',
27
+ emptyLabel: 'Vacío',
28
+ charLabel: 'CARACTERES',
29
+ noteText: 'Nota: Algunos navegadores pueden limitar el renderizado de caracteres combinados'
19
30
  },
20
31
  seo: [
21
32
  { type: 'title', text: '¿Qué es el Texto Zalgo y cómo funciona la corrupción visual?', level: 2 },
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
15
15
  copyBtn: 'Copier le Chaos',
16
16
  copied: 'Copié !',
17
17
  faqTitle: 'FAQ',
18
- bibliographyTitle: 'Références'
18
+ bibliographyTitle: 'Références',
19
+ configTitle: 'Configuration',
20
+ intensity: 'Intensité',
21
+ upLabel: 'Corruption Supérieure',
22
+ midLabel: 'Bruit Central',
23
+ downLabel: 'Corruption Inférieure',
24
+ resetBtn: 'Réinitialiser les Valeurs',
25
+ warningText: 'AVERTISSEMENT : Le texte Zalgo utilise des caractères combinés Unicode qui peuvent déborder visuellement de leur conteneur. À utiliser avec précaution sur les réseaux sociaux.',
26
+ previewLabel: 'Aperçu en Temps Réel',
27
+ emptyLabel: 'Vide',
28
+ charLabel: 'CARACTÈRES',
29
+ noteText: 'Note : Certains navigateurs peuvent limiter le rendu des caractères combinés'
19
30
  },
20
31
  seo: [
21
32
  { type: 'title', text: 'Qu\'est-ce que le Texte Zalgo et comment fonctionne la corruption visuelle ?', level: 2 },
@@ -14,6 +14,17 @@ export interface ZalgoGeneratorUI {
14
14
  copied: string;
15
15
  faqTitle: string;
16
16
  bibliographyTitle: string;
17
+ configTitle: string;
18
+ intensity: string;
19
+ upLabel: string;
20
+ midLabel: string;
21
+ downLabel: string;
22
+ resetBtn: string;
23
+ warningText: string;
24
+ previewLabel: string;
25
+ emptyLabel: string;
26
+ charLabel: string;
27
+ noteText: string;
17
28
  }
18
29
 
19
30
  export type ZalgoGeneratorLocaleContent = ToolLocaleContent<ZalgoGeneratorUI>;
@@ -1,316 +0,0 @@
1
- .excuse-generator {
2
- --excuse-generator-bg: #fff;
3
- --excuse-generator-bg-transparent: rgba(255, 255, 255, 0.8);
4
- --excuse-generator-bg-muted: #f1f5f9;
5
- --excuse-generator-text: #0f172a;
6
- --excuse-generator-text-muted: #475569;
7
- --excuse-generator-text-dim: #64748b;
8
- --excuse-generator-border: #e2e8f0;
9
- --excuse-generator-shadow: rgba(0, 0, 0, 0.05);
10
- --excuse-generator-primary: #ec4899;
11
- --excuse-generator-primary-on: #fff;
12
- --excuse-generator-accent: #f43f5e;
13
- --excuse-generator-success: #10b981;
14
- --excuse-generator-warning: #f59e0b;
15
- --excuse-generator-error: #f43f5e;
16
- --excuse-generator-ring: rgba(236, 72, 153, 0.2);
17
- }
18
-
19
- .theme-dark .excuse-generator {
20
- --excuse-generator-bg: #0f172a;
21
- --excuse-generator-bg-transparent: rgba(15, 23, 42, 0.8);
22
- --excuse-generator-bg-muted: #1e293b;
23
- --excuse-generator-text: #f8fafc;
24
- --excuse-generator-text-muted: #94a3b8;
25
- --excuse-generator-text-dim: #64748b;
26
- --excuse-generator-border: #334155;
27
- --excuse-generator-shadow: rgba(0, 0, 0, 0.3);
28
- --excuse-generator-primary: #f472b6;
29
- --excuse-generator-primary-on: #fff;
30
- --excuse-generator-accent: #fb7185;
31
- --excuse-generator-success: #34d399;
32
- --excuse-generator-warning: #fbbf24;
33
- --excuse-generator-error: #fb7185;
34
- --excuse-generator-ring: rgba(244, 114, 182, 0.2);
35
- }
36
-
37
- .excuse-generator-root {
38
- max-width: 64rem;
39
- margin-left: auto;
40
- margin-right: auto;
41
- padding: 1rem;
42
- }
43
-
44
- @media (min-width: 768px) {
45
- .excuse-generator-root {
46
- padding: 2rem;
47
- }
48
- }
49
-
50
- .excuse-generator-card {
51
- position: relative;
52
- background-color: var(--excuse-generator-bg-transparent);
53
- backdrop-filter: blur(24px);
54
- border-radius: 2rem;
55
- padding: 2rem;
56
- box-shadow: 0 25px 50px -12px var(--excuse-generator-shadow);
57
- border: 1px solid var(--excuse-generator-border);
58
- min-height: 500px;
59
- display: flex;
60
- flex-direction: column;
61
- align-items: center;
62
- justify-content: center;
63
- text-align: center;
64
- overflow: hidden;
65
- }
66
-
67
- @media (min-width: 768px) {
68
- .excuse-generator-card {
69
- padding: 3rem;
70
- }
71
- }
72
-
73
- .excuse-generator-blob {
74
- position: absolute;
75
- width: 24rem;
76
- height: 24rem;
77
- border-radius: 9999px;
78
- filter: blur(64px);
79
- pointer-events: none;
80
- }
81
-
82
- .excuse-generator-blob-1 {
83
- top: 0;
84
- right: 0;
85
- transform: translate(50%, -50%);
86
- background-color: rgba(244, 114, 182, 0.2);
87
- }
88
-
89
- .excuse-generator-blob-2 {
90
- bottom: 0;
91
- left: 0;
92
- transform: translate(-50%, 50%);
93
- background-color: rgba(251, 113, 133, 0.2);
94
- }
95
-
96
- .excuse-generator-slots {
97
- position: relative;
98
- z-index: 10;
99
- width: 100%;
100
- max-width: 80rem;
101
- min-height: 200px;
102
- display: flex;
103
- flex-direction: column;
104
- gap: 1rem;
105
- margin-bottom: 3rem;
106
- }
107
-
108
- @media (min-width: 1024px) {
109
- .excuse-generator-slots {
110
- flex-direction: row;
111
- align-items: center;
112
- }
113
- }
114
-
115
- .excuse-generator-slot {
116
- position: relative;
117
- flex: 1;
118
- min-width: 200px;
119
- background-color: rgba(255, 255, 255, 0.6);
120
- backdrop-filter: blur(4px);
121
- border-radius: 1rem;
122
- padding: 1.5rem;
123
- border: 2px solid var(--excuse-generator-border);
124
- box-shadow: 0 10px 15px -3px var(--excuse-generator-shadow);
125
- display: flex;
126
- align-items: center;
127
- justify-content: center;
128
- text-align: center;
129
- transition-property: all;
130
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
131
- transition-duration: 300ms;
132
- }
133
-
134
- .theme-dark .excuse-generator-slot {
135
- background-color: rgba(15, 23, 42, 0.6);
136
- }
137
-
138
- .excuse-generator-slot:hover {
139
- transform: scale(1.05);
140
- background-color: var(--excuse-generator-bg);
141
- border-color: var(--excuse-generator-primary);
142
- }
143
-
144
- .excuse-generator-slot-label {
145
- position: absolute;
146
- top: 0.5rem;
147
- left: 50%;
148
- transform: translateX(-50%);
149
- color: var(--excuse-generator-text-dim);
150
- font-size: 0.75rem;
151
- line-height: 1rem;
152
- text-transform: uppercase;
153
- letter-spacing: 0.1em;
154
- opacity: 0.5;
155
- }
156
-
157
- .excuse-generator-slot-text {
158
- font-size: 1.5rem;
159
- font-weight: 900;
160
- color: var(--excuse-generator-primary);
161
- line-height: 1.25;
162
- overflow-wrap: break-word;
163
- width: 100%;
164
- transition-property: all;
165
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
166
- transition-duration: 100ms;
167
- }
168
-
169
- @media (min-width: 768px) {
170
- .excuse-generator-slot-text {
171
- font-size: 1.875rem;
172
- line-height: 2.25rem;
173
- }
174
- }
175
-
176
- .excuse-generator-slot-text.blur {
177
- filter: blur(3px);
178
- opacity: 0.7;
179
- transform: scale(0.95);
180
- }
181
-
182
- .excuse-generator-separator {
183
- display: none;
184
- font-size: 2rem;
185
- color: var(--excuse-generator-border);
186
- }
187
-
188
- @media (min-width: 1024px) {
189
- .excuse-generator-separator {
190
- display: block;
191
- }
192
- }
193
-
194
- .excuse-generator-separator-mobile {
195
- display: flex;
196
- justify-content: center;
197
- color: var(--excuse-generator-border);
198
- }
199
-
200
- @media (min-width: 1024px) {
201
- .excuse-generator-separator-mobile {
202
- display: none;
203
- }
204
- }
205
-
206
- .excuse-generator-actions {
207
- position: relative;
208
- z-index: 10;
209
- display: flex;
210
- flex-direction: column;
211
- gap: 1.5rem;
212
- align-items: center;
213
- }
214
-
215
- .excuse-generator-btn {
216
- position: relative;
217
- padding-left: 2.5rem;
218
- padding-right: 2.5rem;
219
- padding-top: 1.25rem;
220
- padding-bottom: 1.25rem;
221
- background-color: #0f172a;
222
- border-radius: 1rem;
223
- color: #fff;
224
- font-weight: 900;
225
- font-size: 1.25rem;
226
- line-height: 1.75rem;
227
- box-shadow: 0 25px 50px -12px rgba(236, 72, 153, 0.2);
228
- border: none;
229
- cursor: pointer;
230
- overflow: hidden;
231
- transition-property: all;
232
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
233
- transition-duration: 300ms;
234
- }
235
-
236
- .theme-dark .excuse-generator-btn {
237
- background-color: #f8fafc;
238
- color: #0f172a;
239
- }
240
-
241
- .excuse-generator-btn:hover {
242
- transform: translateY(-0.25rem);
243
- box-shadow: 0 25px 50px -12px rgba(236, 72, 153, 0.4);
244
- }
245
-
246
- .excuse-generator-btn:active {
247
- transform: translateY(0);
248
- }
249
-
250
- .excuse-generator-btn:disabled {
251
- opacity: 0.7;
252
- cursor: not-allowed;
253
- }
254
-
255
- .excuse-generator-btn-content {
256
- position: relative;
257
- z-index: 10;
258
- display: flex;
259
- align-items: center;
260
- gap: 0.75rem;
261
- }
262
-
263
- .excuse-generator-btn-gradient {
264
- position: absolute;
265
- inset: 0;
266
- background-image: linear-gradient(to right, var(--excuse-generator-primary), var(--excuse-generator-accent), var(--excuse-generator-primary));
267
- opacity: 0;
268
- transition-property: opacity;
269
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
270
- transition-duration: 300ms;
271
- }
272
-
273
- .excuse-generator-btn:hover .excuse-generator-btn-gradient {
274
- opacity: 1;
275
- }
276
-
277
- .excuse-generator-btn:hover .excuse-generator-btn-content {
278
- color: var(--excuse-generator-primary-on);
279
- }
280
-
281
- .excuse-generator-copy {
282
- background: none;
283
- border: none;
284
- cursor: pointer;
285
- color: var(--excuse-generator-text-dim);
286
- font-size: 0.875rem;
287
- line-height: 1.25rem;
288
- font-weight: 700;
289
- display: flex;
290
- align-items: center;
291
- gap: 0.5rem;
292
- transition-property: all;
293
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
294
- transition-duration: 200ms;
295
- opacity: 0;
296
- pointer-events: none;
297
- transform: translateY(0.5rem);
298
- }
299
-
300
- .excuse-generator-copy.visible {
301
- opacity: 1;
302
- pointer-events: auto;
303
- transform: translateY(0);
304
- }
305
-
306
- .excuse-generator-copy:hover {
307
- color: var(--excuse-generator-primary);
308
- }
309
-
310
- .excuse-generator-copy-success {
311
- color: var(--excuse-generator-success);
312
- font-weight: 700;
313
- display: flex;
314
- align-items: center;
315
- gap: 0.5rem;
316
- }