valtech-components 2.0.288 → 2.0.290
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 +20 -20
- package/esm2022/lib/components/atoms/text/text.component.mjs +3 -3
- package/esm2022/lib/examples/link-processing-example.component.mjs +73 -1
- package/esm2022/lib/services/link-processor.service.mjs +94 -43
- package/fesm2022/valtech-components.mjs +167 -44
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/examples/link-processing-example.component.d.ts +3 -0
- package/lib/services/link-processor.service.d.ts +17 -11
- package/package.json +1 -1
- package/src/lib/components/styles/overrides.scss +34 -0
|
@@ -1007,15 +1007,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1007
1007
|
/**
|
|
1008
1008
|
* LinkProcessorService - Service for processing text content to convert URLs and internal routes into clickable links.
|
|
1009
1009
|
*
|
|
1010
|
-
* This service automatically detects external URLs (http/https)
|
|
1011
|
-
* and converts them into HTML anchor elements with appropriate attributes.
|
|
1010
|
+
* This service automatically detects external URLs (http/https), internal routes (starting with /),
|
|
1011
|
+
* and Markdown-style links [text](url) and converts them into HTML anchor elements with appropriate attributes.
|
|
1012
1012
|
*
|
|
1013
1013
|
* @example Basic usage:
|
|
1014
1014
|
* ```typescript
|
|
1015
1015
|
* constructor(private linkProcessor: LinkProcessorService) {}
|
|
1016
1016
|
*
|
|
1017
1017
|
* processText() {
|
|
1018
|
-
* const text = 'Visit https://example.com
|
|
1018
|
+
* const text = 'Visit https://example.com, go to /profile, or [check docs](https://docs.example.com)';
|
|
1019
1019
|
* const processed = this.linkProcessor.processLinks(text);
|
|
1020
1020
|
* // Returns SafeHtml with clickable links
|
|
1021
1021
|
* }
|
|
@@ -1024,14 +1024,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1024
1024
|
class LinkProcessorService {
|
|
1025
1025
|
constructor(sanitizer) {
|
|
1026
1026
|
this.sanitizer = sanitizer;
|
|
1027
|
-
// Regex para detectar URLs completas (http/https)
|
|
1028
|
-
this.urlRegex = /(https?:\/\/[^\s]
|
|
1029
|
-
// Regex para detectar rutas internas (empiezan con / pero no son URLs completas)
|
|
1030
|
-
this.internalRouteRegex = /(\s|^)(\/[^\s]
|
|
1027
|
+
// Regex para detectar URLs completas (http/https) - permite caracteres válidos pero excluye puntuación al final
|
|
1028
|
+
this.urlRegex = /(https?:\/\/[^\s]+?)(?=[.,;!?()\s]|$)/g;
|
|
1029
|
+
// Regex para detectar rutas internas (empiezan con / pero no son URLs completas) - excluye puntuación al final
|
|
1030
|
+
this.internalRouteRegex = /(\s|^)(\/[^\s]*?)(?=[.,;!?()\s]|$)/g;
|
|
1031
|
+
// Regex para detectar enlaces estilo Markdown [texto](url)
|
|
1032
|
+
this.markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
1031
1033
|
}
|
|
1032
1034
|
/**
|
|
1033
1035
|
* Procesa texto para convertir enlaces en elementos <a> clickeables.
|
|
1034
|
-
* Detecta automáticamente URLs externas
|
|
1036
|
+
* Detecta automáticamente URLs externas, rutas internas y enlaces estilo Markdown.
|
|
1035
1037
|
*
|
|
1036
1038
|
* @param text - Texto a procesar
|
|
1037
1039
|
* @param config - Configuración del procesamiento
|
|
@@ -1040,10 +1042,11 @@ class LinkProcessorService {
|
|
|
1040
1042
|
* @example
|
|
1041
1043
|
* ```typescript
|
|
1042
1044
|
* const result = this.linkProcessor.processLinks(
|
|
1043
|
-
* 'Visit https://example.com
|
|
1045
|
+
* 'Visit https://example.com, go to /profile, or [check docs](https://docs.example.com)',
|
|
1044
1046
|
* {
|
|
1045
1047
|
* openExternalInNewTab: true,
|
|
1046
1048
|
* openInternalInNewTab: false,
|
|
1049
|
+
* processMarkdownLinks: true,
|
|
1047
1050
|
* linkClass: 'custom-link'
|
|
1048
1051
|
* }
|
|
1049
1052
|
* );
|
|
@@ -1052,33 +1055,61 @@ class LinkProcessorService {
|
|
|
1052
1055
|
processLinks(text, config = {}) {
|
|
1053
1056
|
if (!text)
|
|
1054
1057
|
return '';
|
|
1055
|
-
const { openExternalInNewTab = true, openInternalInNewTab = false, linkClass = 'processed-link', externalLinkClass = 'external-link', internalLinkClass = 'internal-link', } = config;
|
|
1058
|
+
const { openExternalInNewTab = true, openInternalInNewTab = false, linkClass = 'processed-link', externalLinkClass = 'external-link', internalLinkClass = 'internal-link', processMarkdownLinks = true, } = config;
|
|
1056
1059
|
let hasLinks = false;
|
|
1057
1060
|
let processedText = text;
|
|
1058
|
-
// Procesar
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
1061
|
-
this.
|
|
1062
|
-
|
|
1063
|
-
const
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1061
|
+
// 1. Procesar enlaces estilo Markdown [texto](url) primero
|
|
1062
|
+
if (processMarkdownLinks) {
|
|
1063
|
+
this.markdownLinkRegex.lastIndex = 0; // Reset regex
|
|
1064
|
+
processedText = processedText.replace(this.markdownLinkRegex, (match, linkText, url) => {
|
|
1065
|
+
hasLinks = true;
|
|
1066
|
+
const isExternal = /^https?:\/\//.test(url);
|
|
1067
|
+
const target = (isExternal ? openExternalInNewTab : openInternalInNewTab)
|
|
1068
|
+
? isExternal
|
|
1069
|
+
? ' target="_blank" rel="noopener noreferrer"'
|
|
1070
|
+
: ' target="_blank"'
|
|
1071
|
+
: '';
|
|
1072
|
+
const typeClass = isExternal ? externalLinkClass : internalLinkClass;
|
|
1073
|
+
const classes = `${linkClass} ${typeClass}`.trim();
|
|
1074
|
+
return `<a href="${url}"${target} class="${classes}">${linkText}</a>`;
|
|
1066
1075
|
});
|
|
1067
1076
|
}
|
|
1068
|
-
// Procesar
|
|
1069
|
-
|
|
1077
|
+
// 2. Procesar URLs externas directas (solo si no están ya en un enlace HTML)
|
|
1078
|
+
this.urlRegex.lastIndex = 0; // Reset regex
|
|
1079
|
+
processedText = processedText.replace(this.urlRegex, (fullMatch, url) => {
|
|
1080
|
+
// Verificar que no esté ya dentro de un enlace HTML existente
|
|
1081
|
+
const urlPosition = processedText.indexOf(fullMatch);
|
|
1082
|
+
const textBefore = processedText.substring(0, urlPosition);
|
|
1083
|
+
// Buscar la última apertura y cierre de enlace antes de esta posición
|
|
1084
|
+
const lastOpenTag = textBefore.lastIndexOf('<a ');
|
|
1085
|
+
const lastCloseTag = textBefore.lastIndexOf('</a>');
|
|
1086
|
+
// Si hay un tag <a abierto sin cerrar, no procesamos
|
|
1087
|
+
if (lastOpenTag > lastCloseTag) {
|
|
1088
|
+
return fullMatch; // Mantener original
|
|
1089
|
+
}
|
|
1070
1090
|
hasLinks = true;
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1091
|
+
const target = openExternalInNewTab ? ' target="_blank" rel="noopener noreferrer"' : '';
|
|
1092
|
+
const classes = `${linkClass} ${externalLinkClass}`.trim();
|
|
1093
|
+
return `<a href="${url}"${target} class="${classes}">${url}</a>`;
|
|
1094
|
+
});
|
|
1095
|
+
// 3. Procesar rutas internas (solo si no están ya en un enlace HTML)
|
|
1096
|
+
this.internalRouteRegex.lastIndex = 0; // Reset regex
|
|
1097
|
+
processedText = processedText.replace(this.internalRouteRegex, (match, prefix, route) => {
|
|
1098
|
+
// Verificar que no esté ya dentro de un enlace HTML existente
|
|
1099
|
+
const matchPosition = processedText.indexOf(match);
|
|
1100
|
+
const textBefore = processedText.substring(0, matchPosition);
|
|
1101
|
+
// Buscar la última apertura y cierre de enlace antes de esta posición
|
|
1102
|
+
const lastOpenTag = textBefore.lastIndexOf('<a ');
|
|
1103
|
+
const lastCloseTag = textBefore.lastIndexOf('</a>');
|
|
1104
|
+
// Si hay un tag <a abierto sin cerrar, no procesamos
|
|
1105
|
+
if (lastOpenTag > lastCloseTag) {
|
|
1106
|
+
return match; // Mantener original
|
|
1107
|
+
}
|
|
1108
|
+
hasLinks = true;
|
|
1109
|
+
const target = openInternalInNewTab ? ' target="_blank"' : '';
|
|
1110
|
+
const classes = `${linkClass} ${internalLinkClass}`.trim();
|
|
1111
|
+
return `${prefix}<a href="${route}"${target} class="${classes}">${route}</a>`;
|
|
1112
|
+
});
|
|
1082
1113
|
// Si hay enlaces, sanitizar el HTML
|
|
1083
1114
|
if (hasLinks) {
|
|
1084
1115
|
return this.sanitizer.bypassSecurityTrustHtml(processedText);
|
|
@@ -1086,14 +1117,14 @@ class LinkProcessorService {
|
|
|
1086
1117
|
return text;
|
|
1087
1118
|
}
|
|
1088
1119
|
/**
|
|
1089
|
-
* Detecta si un texto contiene enlaces (URLs o
|
|
1120
|
+
* Detecta si un texto contiene enlaces (URLs, rutas internas o enlaces Markdown).
|
|
1090
1121
|
*
|
|
1091
1122
|
* @param text - Texto a analizar
|
|
1092
1123
|
* @returns true si contiene enlaces
|
|
1093
1124
|
*
|
|
1094
1125
|
* @example
|
|
1095
1126
|
* ```typescript
|
|
1096
|
-
* const hasLinks = this.linkProcessor.hasLinks('Visit https://example.com');
|
|
1127
|
+
* const hasLinks = this.linkProcessor.hasLinks('Visit https://example.com or [docs](https://docs.com)');
|
|
1097
1128
|
* // Returns: true
|
|
1098
1129
|
* ```
|
|
1099
1130
|
*/
|
|
@@ -1103,20 +1134,24 @@ class LinkProcessorService {
|
|
|
1103
1134
|
// Reset regex indices
|
|
1104
1135
|
this.urlRegex.lastIndex = 0;
|
|
1105
1136
|
this.internalRouteRegex.lastIndex = 0;
|
|
1106
|
-
|
|
1137
|
+
this.markdownLinkRegex.lastIndex = 0;
|
|
1138
|
+
return (this.urlRegex.test(text) ||
|
|
1139
|
+
this.internalRouteRegex.test(text) ||
|
|
1140
|
+
this.markdownLinkRegex.test(text));
|
|
1107
1141
|
}
|
|
1108
1142
|
/**
|
|
1109
1143
|
* Extrae todos los enlaces de un texto.
|
|
1110
1144
|
*
|
|
1111
1145
|
* @param text - Texto a analizar
|
|
1112
|
-
* @returns Array de enlaces encontrados con su tipo
|
|
1146
|
+
* @returns Array de enlaces encontrados con su tipo y texto (si es Markdown)
|
|
1113
1147
|
*
|
|
1114
1148
|
* @example
|
|
1115
1149
|
* ```typescript
|
|
1116
|
-
* const links = this.linkProcessor.extractLinks('Visit https://example.com or
|
|
1150
|
+
* const links = this.linkProcessor.extractLinks('Visit https://example.com, /profile, or [docs](https://docs.com)');
|
|
1117
1151
|
* // Returns: [
|
|
1118
|
-
* // { url: 'https://example.com', type: 'external' },
|
|
1119
|
-
* // { url: '/profile', type: 'internal' }
|
|
1152
|
+
* // { url: 'https://example.com', type: 'external', text: 'https://example.com' },
|
|
1153
|
+
* // { url: '/profile', type: 'internal', text: '/profile' },
|
|
1154
|
+
* // { url: 'https://docs.com', type: 'external', text: 'docs' }
|
|
1120
1155
|
* // ]
|
|
1121
1156
|
* ```
|
|
1122
1157
|
*/
|
|
@@ -1127,14 +1162,30 @@ class LinkProcessorService {
|
|
|
1127
1162
|
// Reset regex indices
|
|
1128
1163
|
this.urlRegex.lastIndex = 0;
|
|
1129
1164
|
this.internalRouteRegex.lastIndex = 0;
|
|
1130
|
-
|
|
1165
|
+
this.markdownLinkRegex.lastIndex = 0;
|
|
1166
|
+
// Extraer enlaces Markdown primero
|
|
1131
1167
|
let match;
|
|
1168
|
+
while ((match = this.markdownLinkRegex.exec(text)) !== null) {
|
|
1169
|
+
const url = match[2];
|
|
1170
|
+
const linkText = match[1];
|
|
1171
|
+
const type = /^https?:\/\//.test(url) ? 'external' : 'internal';
|
|
1172
|
+
links.push({ url, type, text: linkText });
|
|
1173
|
+
}
|
|
1174
|
+
// Extraer URLs externas directas
|
|
1132
1175
|
while ((match = this.urlRegex.exec(text)) !== null) {
|
|
1133
|
-
|
|
1176
|
+
const url = match[1];
|
|
1177
|
+
// Verificar que no esté ya capturado como Markdown link
|
|
1178
|
+
if (!links.some(link => link.url === url)) {
|
|
1179
|
+
links.push({ url, type: 'external', text: url });
|
|
1180
|
+
}
|
|
1134
1181
|
}
|
|
1135
|
-
// Extraer rutas internas
|
|
1182
|
+
// Extraer rutas internas directas
|
|
1136
1183
|
while ((match = this.internalRouteRegex.exec(text)) !== null) {
|
|
1137
|
-
|
|
1184
|
+
const url = match[2];
|
|
1185
|
+
// Verificar que no esté ya capturado como Markdown link
|
|
1186
|
+
if (!links.some(link => link.url === url)) {
|
|
1187
|
+
links.push({ url, type: 'internal', text: url });
|
|
1188
|
+
}
|
|
1138
1189
|
}
|
|
1139
1190
|
return links;
|
|
1140
1191
|
}
|
|
@@ -2053,7 +2104,7 @@ class TextComponent {
|
|
|
2053
2104
|
<p [class]="props.size" [class.bold]="props.bold">{{ displayContent$ | async }}</p>
|
|
2054
2105
|
}
|
|
2055
2106
|
</ion-text>
|
|
2056
|
-
`, isInline: true, styles: ["
|
|
2107
|
+
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143,73,248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255,255,255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.small{font-size:.75rem;line-height:1.25rem;font-weight:400}.small.bold{font-size:.75rem;line-height:1.25rem;font-weight:700}.medium{font-size:.875rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.medium{font-size:1rem;line-height:1.5rem}}.medium.bold{font-size:.875rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.medium.bold{font-size:1rem;line-height:1.5rem}}.large{font-size:1rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.large{font-size:1.125rem;line-height:1.5rem}}.large.bold{font-size:1rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.large.bold{font-size:1.125rem;line-height:1.5rem}}.xlarge{font-size:1.125rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.xlarge{font-size:1.5rem;line-height:2rem}}.xlarge.bold{font-size:1.125rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.xlarge.bold{font-size:1.5rem;line-height:2rem}}\n"], dependencies: [{ kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: ProcessLinksPipe, name: "processLinks" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2057
2108
|
}
|
|
2058
2109
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextComponent, decorators: [{
|
|
2059
2110
|
type: Component,
|
|
@@ -2069,7 +2120,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2069
2120
|
<p [class]="props.size" [class.bold]="props.bold">{{ displayContent$ | async }}</p>
|
|
2070
2121
|
}
|
|
2071
2122
|
</ion-text>
|
|
2072
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["
|
|
2123
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143,73,248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255,255,255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.small{font-size:.75rem;line-height:1.25rem;font-weight:400}.small.bold{font-size:.75rem;line-height:1.25rem;font-weight:700}.medium{font-size:.875rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.medium{font-size:1rem;line-height:1.5rem}}.medium.bold{font-size:.875rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.medium.bold{font-size:1rem;line-height:1.5rem}}.large{font-size:1rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.large{font-size:1.125rem;line-height:1.5rem}}.large.bold{font-size:1rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.large.bold{font-size:1.125rem;line-height:1.5rem}}.xlarge{font-size:1.125rem;line-height:1.5rem;font-weight:400}@media (min-width: 768px){.xlarge{font-size:1.5rem;line-height:2rem}}.xlarge.bold{font-size:1.125rem;line-height:1.5rem;font-weight:700}@media (min-width: 768px){.xlarge.bold{font-size:1.5rem;line-height:2rem}}\n"] }]
|
|
2073
2124
|
}], ctorParameters: () => [{ type: ContentService }, { type: LinkProcessorService }], propDecorators: { props: [{
|
|
2074
2125
|
type: Input
|
|
2075
2126
|
}] } });
|
|
@@ -6572,6 +6623,48 @@ class LinkProcessingExampleComponent {
|
|
|
6572
6623
|
internalLinkClass: 'internal-same-tab',
|
|
6573
6624
|
},
|
|
6574
6625
|
};
|
|
6626
|
+
this.markdownLinksProps = {
|
|
6627
|
+
content: 'Consulta [la documentación de Angular](https://angular.io/docs) y ve a [configuración del perfil](/profile/settings) para más opciones.',
|
|
6628
|
+
size: 'medium',
|
|
6629
|
+
color: 'dark',
|
|
6630
|
+
bold: false,
|
|
6631
|
+
processLinks: true,
|
|
6632
|
+
linkConfig: {
|
|
6633
|
+
openExternalInNewTab: true,
|
|
6634
|
+
openInternalInNewTab: false,
|
|
6635
|
+
processMarkdownLinks: true,
|
|
6636
|
+
linkClass: 'markdown-link',
|
|
6637
|
+
externalLinkClass: 'markdown-external',
|
|
6638
|
+
internalLinkClass: 'markdown-internal',
|
|
6639
|
+
},
|
|
6640
|
+
};
|
|
6641
|
+
this.mixedFormatsProps = {
|
|
6642
|
+
content: 'Aquí hay [documentación oficial](https://angular.io/docs), un enlace directo https://github.com/angular/angular, y una ruta interna /dashboard/analytics. ¡Todos funcionan!',
|
|
6643
|
+
size: 'medium',
|
|
6644
|
+
color: 'dark',
|
|
6645
|
+
bold: false,
|
|
6646
|
+
processLinks: true,
|
|
6647
|
+
linkConfig: {
|
|
6648
|
+
openExternalInNewTab: true,
|
|
6649
|
+
openInternalInNewTab: false,
|
|
6650
|
+
processMarkdownLinks: true,
|
|
6651
|
+
linkClass: 'mixed-link',
|
|
6652
|
+
externalLinkClass: 'mixed-external',
|
|
6653
|
+
internalLinkClass: 'mixed-internal',
|
|
6654
|
+
},
|
|
6655
|
+
};
|
|
6656
|
+
this.punctuationTestProps = {
|
|
6657
|
+
content: 'URLs con puntuación: https://ionicframework.com/docs, revisa https://angular.io! También https://github.com/angular? Y finalmente https://typescript.org. ¡Todos deben funcionar correctamente!',
|
|
6658
|
+
size: 'medium',
|
|
6659
|
+
color: 'dark',
|
|
6660
|
+
bold: false,
|
|
6661
|
+
processLinks: true,
|
|
6662
|
+
linkConfig: {
|
|
6663
|
+
openExternalInNewTab: true,
|
|
6664
|
+
linkClass: 'punctuation-test',
|
|
6665
|
+
externalLinkClass: 'external-punct',
|
|
6666
|
+
},
|
|
6667
|
+
};
|
|
6575
6668
|
}
|
|
6576
6669
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LinkProcessingExampleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6577
6670
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LinkProcessingExampleComponent, isStandalone: true, selector: "val-link-processing-example", ngImport: i0, template: `
|
|
@@ -6602,6 +6695,21 @@ class LinkProcessingExampleComponent {
|
|
|
6602
6695
|
<h3>Enlaces sin abrir en nueva pestaña:</h3>
|
|
6603
6696
|
<val-text [props]="sameTabLinksProps"></val-text>
|
|
6604
6697
|
</div>
|
|
6698
|
+
|
|
6699
|
+
<div class="example-section">
|
|
6700
|
+
<h3>Enlaces estilo Markdown [texto](url):</h3>
|
|
6701
|
+
<val-text [props]="markdownLinksProps"></val-text>
|
|
6702
|
+
</div>
|
|
6703
|
+
|
|
6704
|
+
<div class="example-section">
|
|
6705
|
+
<h3>Mezcla de enlaces directos y Markdown:</h3>
|
|
6706
|
+
<val-text [props]="mixedFormatsProps"></val-text>
|
|
6707
|
+
</div>
|
|
6708
|
+
|
|
6709
|
+
<div class="example-section">
|
|
6710
|
+
<h3>Corrección de puntuación en URLs:</h3>
|
|
6711
|
+
<val-text [props]="punctuationTestProps"></val-text>
|
|
6712
|
+
</div>
|
|
6605
6713
|
</div>
|
|
6606
6714
|
`, isInline: true, styles: [".link-examples{padding:20px;max-width:800px}.example-section{margin-bottom:24px;padding:16px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:20px}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px;font-size:16px}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
|
|
6607
6715
|
}
|
|
@@ -6635,6 +6743,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
6635
6743
|
<h3>Enlaces sin abrir en nueva pestaña:</h3>
|
|
6636
6744
|
<val-text [props]="sameTabLinksProps"></val-text>
|
|
6637
6745
|
</div>
|
|
6746
|
+
|
|
6747
|
+
<div class="example-section">
|
|
6748
|
+
<h3>Enlaces estilo Markdown [texto](url):</h3>
|
|
6749
|
+
<val-text [props]="markdownLinksProps"></val-text>
|
|
6750
|
+
</div>
|
|
6751
|
+
|
|
6752
|
+
<div class="example-section">
|
|
6753
|
+
<h3>Mezcla de enlaces directos y Markdown:</h3>
|
|
6754
|
+
<val-text [props]="mixedFormatsProps"></val-text>
|
|
6755
|
+
</div>
|
|
6756
|
+
|
|
6757
|
+
<div class="example-section">
|
|
6758
|
+
<h3>Corrección de puntuación en URLs:</h3>
|
|
6759
|
+
<val-text [props]="punctuationTestProps"></val-text>
|
|
6760
|
+
</div>
|
|
6638
6761
|
</div>
|
|
6639
6762
|
`, styles: [".link-examples{padding:20px;max-width:800px}.example-section{margin-bottom:24px;padding:16px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:20px}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px;font-size:16px}\n"] }]
|
|
6640
6763
|
}] });
|