@jjlmoya/utils-shared 1.0.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 +69 -0
- package/package.json +60 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +24 -0
- package/src/pages/_components/PreviewSection.astro +13 -0
- package/src/pages/_components/PreviewSidebar.astro +52 -0
- package/src/pages/_components/preview/GroupAdvanced.astro +55 -0
- package/src/pages/_components/preview/GroupBasic.astro +49 -0
- package/src/pages/_components/preview/GroupContent.astro +57 -0
- package/src/pages/_components/preview/layout.css +104 -0
- package/src/pages/index.astro +42 -0
- package/src/seo/CategorySchema.astro +37 -0
- package/src/seo/SEOArticle.astro +45 -0
- package/src/seo/SEOCard.astro +84 -0
- package/src/seo/SEOCode.astro +60 -0
- package/src/seo/SEOComparative.astro +163 -0
- package/src/seo/SEODiagnostic.astro +167 -0
- package/src/seo/SEOGlossary.astro +92 -0
- package/src/seo/SEOGrid.astro +49 -0
- package/src/seo/SEOList.astro +123 -0
- package/src/seo/SEOMessageTemplate.astro +54 -0
- package/src/seo/SEOProsCons.astro +153 -0
- package/src/seo/SEORenderer.astro +87 -0
- package/src/seo/SEOStats.astro +140 -0
- package/src/seo/SEOSummary.astro +166 -0
- package/src/seo/SEOTable.astro +154 -0
- package/src/seo/SEOTip.astro +36 -0
- package/src/seo/SEOTitle.astro +59 -0
- package/src/styles/theme.css +48 -0
- package/src/types/index.ts +64 -0
- package/src/ui/Bibliography.astro +158 -0
- package/src/ui/FAQSection.astro +117 -0
- package/src/ui/UtilityHeader.astro +83 -0
- package/src/ui/UtilityStructuredData.astro +149 -0
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @jjlmoya/utils-shared
|
|
2
|
+
|
|
3
|
+
Library of common components and utilities for jjlmoya projects, built with Astro and TypeScript.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @jjlmoya/utils-shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Ensure you have `astro-icon` configured in your `astro.config.mjs`:
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { defineConfig } from "astro/config";
|
|
17
|
+
import icon from "astro-icon";
|
|
18
|
+
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
integrations: [icon()]
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Main Components
|
|
25
|
+
|
|
26
|
+
### SEO Components
|
|
27
|
+
|
|
28
|
+
- **SEOCard**: A premium card with icon support for highlighting information.
|
|
29
|
+
- **SEOList**: A stylistic list with custom icons and hover effects.
|
|
30
|
+
- **SEOStats**: Displays metrics and status with trend indicators.
|
|
31
|
+
- **SEOCode**: A custom code block with syntax highlighting and aria-labels.
|
|
32
|
+
- **SEOComparative**: Used for comparing features or options.
|
|
33
|
+
- **SEODiagnostic**: Shows status, success, or warning messages in a diagnostic format.
|
|
34
|
+
- **SEOTip**: Short informative boxes for advice.
|
|
35
|
+
- **SEOSummary**: A checklist-style list for wrapping up key points.
|
|
36
|
+
|
|
37
|
+
### UI Components
|
|
38
|
+
|
|
39
|
+
- **UtilityHeader**: A modern header for utility pages with gradient backgrounds.
|
|
40
|
+
- **Bibliography**: A list of links for further reading or citations.
|
|
41
|
+
|
|
42
|
+
## Usage Example
|
|
43
|
+
|
|
44
|
+
```astro
|
|
45
|
+
---
|
|
46
|
+
import { SEOCard, UtilityHeader } from "@jjlmoya/utils-shared";
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
<UtilityHeader
|
|
50
|
+
titleHighlight="My"
|
|
51
|
+
titleBase="Utility"
|
|
52
|
+
description="This is a description."
|
|
53
|
+
/>
|
|
54
|
+
|
|
55
|
+
<SEOCard title="Ready to go" icon="mdi:rocket-launch">
|
|
56
|
+
<p>This is a custom card content.</p>
|
|
57
|
+
</SEOCard>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Development
|
|
61
|
+
|
|
62
|
+
To preview components in development:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm run dev
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Then visit `http://localhost:51000/` to see the showroom.
|
|
69
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jjlmoya/utils-shared",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared SEO primitives and UI components for jjlmoya ecosystem",
|
|
5
|
+
"author": "jjlmoya",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Game-Bob/jjlmoya-utils-shared.git"
|
|
10
|
+
},
|
|
11
|
+
"main": "./src/index.ts",
|
|
12
|
+
"types": "./src/index.ts",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": "./src/index.ts",
|
|
19
|
+
"./theme.css": "./src/styles/theme.css",
|
|
20
|
+
"./seo/*": "./src/seo/*",
|
|
21
|
+
"./types": "./src/types/index.ts",
|
|
22
|
+
"./ui/*": "./src/ui/*",
|
|
23
|
+
"./styles/*": "./src/styles/*"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"src"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"dev": "astro dev",
|
|
30
|
+
"start": "astro dev",
|
|
31
|
+
"check": "astro check",
|
|
32
|
+
"lint": "eslint src --ext .ts,.astro",
|
|
33
|
+
"lint:css": "stylelint \"src/**/*.{astro,css}\"",
|
|
34
|
+
"lint:all": "npm run check && npm run lint && npm run lint:css",
|
|
35
|
+
"prepublishOnly": "npm run lint:all"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@iconify-json/mdi": "^1.0.0",
|
|
39
|
+
"astro": "^5.0.0",
|
|
40
|
+
"astro-icon": "^1.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@astrojs/check": "^0.9.2",
|
|
44
|
+
"@iconify-json/mdi": "^1.2.3",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
46
|
+
"@typescript-eslint/parser": "^8.58.0",
|
|
47
|
+
"astro": "^5.15.9",
|
|
48
|
+
"astro-eslint-parser": "^1.4.0",
|
|
49
|
+
"astro-icon": "^1.1.5",
|
|
50
|
+
"eslint": "^9.39.4",
|
|
51
|
+
"eslint-plugin-astro": "^1.6.0",
|
|
52
|
+
"eslint-plugin-no-comments": "^1.1.10",
|
|
53
|
+
"postcss-html": "^1.8.1",
|
|
54
|
+
"stylelint": "^17.6.0",
|
|
55
|
+
"stylelint-config-standard": "^40.0.0",
|
|
56
|
+
"stylelint-declaration-strict-value": "^1.11.1",
|
|
57
|
+
"typescript": "^5.0.0",
|
|
58
|
+
"typescript-eslint": "^8.58.0"
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { default as CategorySchema } from './seo/CategorySchema.astro';
|
|
2
|
+
export { default as SEOArticle } from './seo/SEOArticle.astro';
|
|
3
|
+
export { default as SEOCard } from './seo/SEOCard.astro';
|
|
4
|
+
export { default as SEOCode } from './seo/SEOCode.astro';
|
|
5
|
+
export { default as SEOComparative } from './seo/SEOComparative.astro';
|
|
6
|
+
export { default as SEODiagnostic } from './seo/SEODiagnostic.astro';
|
|
7
|
+
export { default as SEOGlossary } from './seo/SEOGlossary.astro';
|
|
8
|
+
export { default as SEOGrid } from './seo/SEOGrid.astro';
|
|
9
|
+
export { default as SEOList } from './seo/SEOList.astro';
|
|
10
|
+
export { default as SEOMessageTemplate } from './seo/SEOMessageTemplate.astro';
|
|
11
|
+
export { default as SEOProsCons } from './seo/SEOProsCons.astro';
|
|
12
|
+
export { default as SEORenderer } from './seo/SEORenderer.astro';
|
|
13
|
+
export { default as SEOStats } from './seo/SEOStats.astro';
|
|
14
|
+
export { default as SEOSummary } from './seo/SEOSummary.astro';
|
|
15
|
+
export { default as SEOTable } from './seo/SEOTable.astro';
|
|
16
|
+
export { default as SEOTip } from './seo/SEOTip.astro';
|
|
17
|
+
export { default as SEOTitle } from './seo/SEOTitle.astro';
|
|
18
|
+
|
|
19
|
+
export { default as Bibliography } from './ui/Bibliography.astro';
|
|
20
|
+
export { default as FAQSection } from './ui/FAQSection.astro';
|
|
21
|
+
export { default as UtilityHeader } from './ui/UtilityHeader.astro';
|
|
22
|
+
export { default as UtilityStructuredData } from './ui/UtilityStructuredData.astro';
|
|
23
|
+
|
|
24
|
+
export * from './types/index';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from "astro-icon/components";
|
|
3
|
+
|
|
4
|
+
interface Section {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
sections: Section[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { sections } = Astro.props;
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<nav class="sidebar">
|
|
17
|
+
<div class="sidebar-header">
|
|
18
|
+
<h2>Componentes</h2>
|
|
19
|
+
<button id="themeToggle" class="theme-btn" aria-label="Cambiar tema">
|
|
20
|
+
<Icon name="mdi:theme-light-dark" class="theme-icon" />
|
|
21
|
+
</button>
|
|
22
|
+
</div>
|
|
23
|
+
<ul>
|
|
24
|
+
{sections.map((s: Section) => (
|
|
25
|
+
<li><a href={`#${s.id}`}>{s.name}</a></li>
|
|
26
|
+
))}
|
|
27
|
+
</ul>
|
|
28
|
+
</nav>
|
|
29
|
+
|
|
30
|
+
<script is:inline>
|
|
31
|
+
const setupTheme = () => {
|
|
32
|
+
const btn = document.getElementById('themeToggle');
|
|
33
|
+
const body = document.body;
|
|
34
|
+
const savedTheme = localStorage.getItem('preview-theme') || 'theme-light';
|
|
35
|
+
|
|
36
|
+
body.classList.add(savedTheme);
|
|
37
|
+
if (savedTheme === 'theme-light') body.classList.remove('theme-dark');
|
|
38
|
+
else body.classList.remove('theme-light');
|
|
39
|
+
|
|
40
|
+
btn?.addEventListener('click', () => {
|
|
41
|
+
if (body.classList.contains('theme-light')) {
|
|
42
|
+
body.classList.replace('theme-light', 'theme-dark');
|
|
43
|
+
localStorage.setItem('preview-theme', 'theme-dark');
|
|
44
|
+
} else {
|
|
45
|
+
body.classList.replace('theme-dark', 'theme-light');
|
|
46
|
+
localStorage.setItem('preview-theme', 'theme-light');
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
document.addEventListener('DOMContentLoaded', setupTheme);
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
import SEOCode from "../../../seo/SEOCode.astro";
|
|
3
|
+
import SEOComparative from "../../../seo/SEOComparative.astro";
|
|
4
|
+
import SEODiagnostic from "../../../seo/SEODiagnostic.astro";
|
|
5
|
+
import SEOProsCons from "../../../seo/SEOProsCons.astro";
|
|
6
|
+
import SEOGrid from "../../../seo/SEOGrid.astro";
|
|
7
|
+
import SEOCard from "../../../seo/SEOCard.astro";
|
|
8
|
+
import PreviewSection from "../PreviewSection.astro";
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<PreviewSection id="code" label="SEO Code">
|
|
12
|
+
<SEOCode
|
|
13
|
+
code={`import { SEOTip } from "@game-bob/utils-shared";`}
|
|
14
|
+
ariaLabel="Ejemplo de Importación"
|
|
15
|
+
/>
|
|
16
|
+
</PreviewSection>
|
|
17
|
+
|
|
18
|
+
<PreviewSection id="comparative" label="SEO Comparative">
|
|
19
|
+
<SEOComparative
|
|
20
|
+
items={[
|
|
21
|
+
{ title: "Versión 1", description: "Básica y rudimentaria", points: ["Sin tipos", "Sin estilos"], highlight: false },
|
|
22
|
+
{ title: "Versión 2", description: "Premium y robusta", points: ["TypeScript", "Design System"], highlight: true }
|
|
23
|
+
]}
|
|
24
|
+
/>
|
|
25
|
+
</PreviewSection>
|
|
26
|
+
|
|
27
|
+
<PreviewSection id="diagnostic" label="SEO Diagnostic">
|
|
28
|
+
<SEODiagnostic
|
|
29
|
+
title="Estado del Repositorio"
|
|
30
|
+
type="success"
|
|
31
|
+
icon="mdi:check-circle"
|
|
32
|
+
>
|
|
33
|
+
<p>Todos los linters han pasado correctamente. El código es seguro y sigue las guías de estilo.</p>
|
|
34
|
+
</SEODiagnostic>
|
|
35
|
+
</PreviewSection>
|
|
36
|
+
|
|
37
|
+
<PreviewSection id="proscons" label="SEO Pros & Cons">
|
|
38
|
+
<SEOProsCons
|
|
39
|
+
items={[
|
|
40
|
+
{ pro: "Fácil de usar", con: "Requiere Astro" },
|
|
41
|
+
{ pro: "Sólidos principios", con: "Aprender el sistema" }
|
|
42
|
+
]}
|
|
43
|
+
/>
|
|
44
|
+
</PreviewSection>
|
|
45
|
+
|
|
46
|
+
<PreviewSection id="grid" label="SEO Grid">
|
|
47
|
+
<SEOGrid columns={2}>
|
|
48
|
+
<SEOCard title="Caja 1">
|
|
49
|
+
<p>Contenido de la primera caja del grid.</p>
|
|
50
|
+
</SEOCard>
|
|
51
|
+
<SEOCard title="Caja 2">
|
|
52
|
+
<p>Contenido de la segunda caja del grid.</p>
|
|
53
|
+
</SEOCard>
|
|
54
|
+
</SEOGrid>
|
|
55
|
+
</PreviewSection>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
import UtilityHeader from "../../../ui/UtilityHeader.astro";
|
|
3
|
+
import SEOList from "../../../seo/SEOList.astro";
|
|
4
|
+
import SEOTip from "../../../seo/SEOTip.astro";
|
|
5
|
+
import SEOCard from "../../../seo/SEOCard.astro";
|
|
6
|
+
import SEOStats from "../../../seo/SEOStats.astro";
|
|
7
|
+
import PreviewSection from "../PreviewSection.astro";
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<PreviewSection id="header" label="Utility Header">
|
|
11
|
+
<UtilityHeader
|
|
12
|
+
titleHighlight="Shared"
|
|
13
|
+
titleBase="Library Components"
|
|
14
|
+
description="Vista previa de todos los componentes disponibles en la librería."
|
|
15
|
+
/>
|
|
16
|
+
</PreviewSection>
|
|
17
|
+
|
|
18
|
+
<PreviewSection id="list" label="SEO List">
|
|
19
|
+
<SEOList
|
|
20
|
+
items={[
|
|
21
|
+
"Totalmente tipados con TypeScript",
|
|
22
|
+
"Accesibles y semánticos",
|
|
23
|
+
"Estilos modernos y consistentes",
|
|
24
|
+
"Fáciles de integrar en Astro"
|
|
25
|
+
]}
|
|
26
|
+
icon="mdi:check"
|
|
27
|
+
/>
|
|
28
|
+
</PreviewSection>
|
|
29
|
+
|
|
30
|
+
<PreviewSection id="tip" label="SEO Tip">
|
|
31
|
+
<SEOTip title="Consejo de Implementación">
|
|
32
|
+
<p>Usa estos componentes para mejorar el SEO y la legibilidad de tus utilitarios de forma rápida.</p>
|
|
33
|
+
</SEOTip>
|
|
34
|
+
</PreviewSection>
|
|
35
|
+
|
|
36
|
+
<PreviewSection id="card" label="SEO Card">
|
|
37
|
+
<SEOCard title="Componentes Optimizados" icon="mdi:rocket-launch">
|
|
38
|
+
<p>Nuestra librería está diseñada para ser ligera y eficiente en cualquier proyecto Astro.</p>
|
|
39
|
+
</SEOCard>
|
|
40
|
+
</PreviewSection>
|
|
41
|
+
|
|
42
|
+
<PreviewSection id="stats" label="SEO Stats">
|
|
43
|
+
<SEOStats
|
|
44
|
+
stats={[
|
|
45
|
+
{ label: "Velocidad", value: "99%", icon: "mdi:speedometer" },
|
|
46
|
+
{ label: "Accesibilidad", value: "100/100", icon: "mdi:accessibility" }
|
|
47
|
+
]}
|
|
48
|
+
/>
|
|
49
|
+
</PreviewSection>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
import SEOMessageTemplate from "../../../seo/SEOMessageTemplate.astro";
|
|
3
|
+
import SEOSummary from "../../../seo/SEOSummary.astro";
|
|
4
|
+
import SEOTable from "../../../seo/SEOTable.astro";
|
|
5
|
+
import SEOGlossary from "../../../seo/SEOGlossary.astro";
|
|
6
|
+
import Bibliography from "../../../ui/Bibliography.astro";
|
|
7
|
+
import PreviewSection from "../PreviewSection.astro";
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<PreviewSection id="message" label="SEO Message Template">
|
|
11
|
+
<SEOMessageTemplate title="Mensaje Informativo">
|
|
12
|
+
Este es un ejemplo de mensaje que utiliza el template genérico.
|
|
13
|
+
</SEOMessageTemplate>
|
|
14
|
+
</PreviewSection>
|
|
15
|
+
|
|
16
|
+
<PreviewSection id="summary" label="SEO Summary">
|
|
17
|
+
<SEOSummary
|
|
18
|
+
title="Puntos Clave"
|
|
19
|
+
items={[
|
|
20
|
+
"<strong>Consistencia:</strong> Visualmente unificado.",
|
|
21
|
+
"<strong>Mantenimiento:</strong> Componentes desacoplados."
|
|
22
|
+
]}
|
|
23
|
+
/>
|
|
24
|
+
</PreviewSection>
|
|
25
|
+
|
|
26
|
+
<PreviewSection id="table" label="SEO Table">
|
|
27
|
+
<SEOTable headers={["Componente", "Tipo", "Estado"]}>
|
|
28
|
+
<tr>
|
|
29
|
+
<td>SEOTable</td>
|
|
30
|
+
<td>Maquetación</td>
|
|
31
|
+
<td>Listo</td>
|
|
32
|
+
</tr>
|
|
33
|
+
<tr>
|
|
34
|
+
<td>SEOStats</td>
|
|
35
|
+
<td>Visualización</td>
|
|
36
|
+
<td>Listo</td>
|
|
37
|
+
</tr>
|
|
38
|
+
</SEOTable>
|
|
39
|
+
</PreviewSection>
|
|
40
|
+
|
|
41
|
+
<PreviewSection id="glossary" label="SEO Glossary">
|
|
42
|
+
<SEOGlossary
|
|
43
|
+
items={[
|
|
44
|
+
{ term: "Astro", definition: "Framework web moderno para construir sitios rápidos cargando menos JavaScript." },
|
|
45
|
+
{ term: "SOLID", definition: "Cinco principios de diseño orientado a objetos destinados a hacer que los diseños de software sean más comprensibles, flexibles y fáciles de mantener." }
|
|
46
|
+
]}
|
|
47
|
+
/>
|
|
48
|
+
</PreviewSection>
|
|
49
|
+
|
|
50
|
+
<PreviewSection id="bibliography" label="Bibliography">
|
|
51
|
+
<Bibliography
|
|
52
|
+
links={[
|
|
53
|
+
{ name: "Astro Documentation", url: "https://docs.astro.build" },
|
|
54
|
+
{ name: "GitHub Organization", url: "https://github.com/Game-Bob" }
|
|
55
|
+
]}
|
|
56
|
+
/>
|
|
57
|
+
</PreviewSection>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
body {
|
|
2
|
+
font-family: Inter, system-ui, sans-serif;
|
|
3
|
+
background: var(--bg-page);
|
|
4
|
+
color: var(--text-base);
|
|
5
|
+
margin: 0;
|
|
6
|
+
display: flex;
|
|
7
|
+
transition: background 0.3s ease, color 0.3s ease;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.sidebar {
|
|
11
|
+
width: 260px;
|
|
12
|
+
height: 100vh;
|
|
13
|
+
background: var(--bg-surface);
|
|
14
|
+
border-right: 1px solid var(--border-base);
|
|
15
|
+
padding: 2rem 1.5rem;
|
|
16
|
+
position: fixed;
|
|
17
|
+
overflow-y: auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.sidebar-header {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: space-between;
|
|
24
|
+
margin-bottom: 2rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.sidebar h2 {
|
|
28
|
+
font-size: 0.75rem;
|
|
29
|
+
text-transform: uppercase;
|
|
30
|
+
letter-spacing: 0.1em;
|
|
31
|
+
color: var(--text-dimmed);
|
|
32
|
+
margin: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.theme-btn {
|
|
36
|
+
background: var(--bg-muted);
|
|
37
|
+
border: 1px solid var(--border-base);
|
|
38
|
+
color: var(--text-base);
|
|
39
|
+
width: 32px;
|
|
40
|
+
height: 32px;
|
|
41
|
+
border-radius: 8px;
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
transition: all 0.2s;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.theme-btn:hover {
|
|
50
|
+
background: var(--border-base);
|
|
51
|
+
transform: scale(1.05);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.theme-icon {
|
|
55
|
+
width: 18px;
|
|
56
|
+
height: 18px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sidebar ul {
|
|
60
|
+
list-style: none;
|
|
61
|
+
padding: 0;
|
|
62
|
+
margin: 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.sidebar li {
|
|
66
|
+
margin-bottom: 0.5rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.sidebar a {
|
|
70
|
+
text-decoration: none;
|
|
71
|
+
color: var(--text-muted);
|
|
72
|
+
font-size: 0.95rem;
|
|
73
|
+
font-weight: 500;
|
|
74
|
+
display: block;
|
|
75
|
+
padding: 0.5rem 0.75rem;
|
|
76
|
+
border-radius: 8px;
|
|
77
|
+
transition: all 0.2s;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.sidebar a:hover {
|
|
81
|
+
background: var(--bg-muted);
|
|
82
|
+
color: var(--text-base);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.main {
|
|
86
|
+
flex: 1;
|
|
87
|
+
margin-left: 260px;
|
|
88
|
+
padding: 4rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.component-section {
|
|
92
|
+
margin-bottom: 8rem;
|
|
93
|
+
scroll-margin-top: 4rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.section-label {
|
|
97
|
+
font-size: 0.7rem;
|
|
98
|
+
font-weight: 800;
|
|
99
|
+
color: var(--primary);
|
|
100
|
+
text-transform: uppercase;
|
|
101
|
+
letter-spacing: 0.1em;
|
|
102
|
+
margin-bottom: 1rem;
|
|
103
|
+
display: block;
|
|
104
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
import PreviewSidebar from "./_components/PreviewSidebar.astro";
|
|
3
|
+
import GroupBasic from "./_components/preview/GroupBasic.astro";
|
|
4
|
+
import GroupAdvanced from "./_components/preview/GroupAdvanced.astro";
|
|
5
|
+
import GroupContent from "./_components/preview/GroupContent.astro";
|
|
6
|
+
import "./_components/preview/layout.css";
|
|
7
|
+
import "../styles/theme.css";
|
|
8
|
+
|
|
9
|
+
const sections = [
|
|
10
|
+
{ id: "header", name: "Utility Header" },
|
|
11
|
+
{ id: "list", name: "SEO List" },
|
|
12
|
+
{ id: "tip", name: "SEO Tip" },
|
|
13
|
+
{ id: "card", name: "SEO Card" },
|
|
14
|
+
{ id: "stats", name: "SEO Stats" },
|
|
15
|
+
{ id: "code", name: "SEO Code" },
|
|
16
|
+
{ id: "comparative", name: "SEO Comparative" },
|
|
17
|
+
{ id: "diagnostic", name: "SEO Diagnostic" },
|
|
18
|
+
{ id: "proscons", name: "SEO Pros & Cons" },
|
|
19
|
+
{ id: "grid", name: "SEO Grid" },
|
|
20
|
+
{ id: "message", name: "SEO Message Template" },
|
|
21
|
+
{ id: "summary", name: "SEO Summary" },
|
|
22
|
+
{ id: "table", name: "SEO Table" },
|
|
23
|
+
{ id: "glossary", name: "SEO Glossary" },
|
|
24
|
+
{ id: "bibliography", name: "Bibliography" },
|
|
25
|
+
];
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<html lang="es">
|
|
29
|
+
<head>
|
|
30
|
+
<meta charset="utf-8" />
|
|
31
|
+
<meta name="viewport" content="width=device-width" />
|
|
32
|
+
<title>Component Library Preview</title>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<PreviewSidebar sections={sections} />
|
|
36
|
+
<main class="main">
|
|
37
|
+
<GroupBasic />
|
|
38
|
+
<GroupAdvanced />
|
|
39
|
+
<GroupContent />
|
|
40
|
+
</main>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { SectionData } from "../types/index.ts";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
section: SectionData;
|
|
6
|
+
baseUrl?: string | undefined;
|
|
7
|
+
categoryPath?: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
section,
|
|
12
|
+
baseUrl = "https://www.jjlmoya.es",
|
|
13
|
+
categoryPath = "/utilidades/categorias/",
|
|
14
|
+
} = Astro.props;
|
|
15
|
+
|
|
16
|
+
const categorySchema = {
|
|
17
|
+
"@context": "https://schema.org",
|
|
18
|
+
"@type": "CollectionPage",
|
|
19
|
+
name: section.title,
|
|
20
|
+
url: `${baseUrl}${categoryPath}${section.slug}/`,
|
|
21
|
+
hasPart: section.utilities.map((u) => ({
|
|
22
|
+
"@context": "https://schema.org",
|
|
23
|
+
"@type": "WebApplication",
|
|
24
|
+
name: u.title,
|
|
25
|
+
description: u.description,
|
|
26
|
+
url: `${baseUrl}${u.href}`,
|
|
27
|
+
applicationCategory: "UtilityApplication",
|
|
28
|
+
operatingSystem: "Any",
|
|
29
|
+
})),
|
|
30
|
+
};
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<script
|
|
34
|
+
is:inline
|
|
35
|
+
type="application/ld+json"
|
|
36
|
+
set:html={JSON.stringify(categorySchema)}
|
|
37
|
+
/>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { class: className } = Astro.props;
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<article class:list={["seo-article", className]}>
|
|
10
|
+
<slot />
|
|
11
|
+
</article>
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
.seo-article {
|
|
15
|
+
line-height: 1.8;
|
|
16
|
+
color: var(--text-muted);
|
|
17
|
+
font-size: 1.125rem;
|
|
18
|
+
max-width: 48rem;
|
|
19
|
+
margin: 0 auto;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.seo-article :global(p) {
|
|
23
|
+
margin-bottom: 1.5rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.seo-article :global(strong) {
|
|
27
|
+
color: var(--text-base);
|
|
28
|
+
font-weight: 700;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.seo-article :global(code:not(pre code)) {
|
|
32
|
+
background: var(--bg-muted);
|
|
33
|
+
color: var(--primary);
|
|
34
|
+
padding: 0.2rem 0.4rem;
|
|
35
|
+
border-radius: 0.375rem;
|
|
36
|
+
font-size: 0.875em;
|
|
37
|
+
font-weight: 600;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@media (max-width: 768px) {
|
|
41
|
+
.seo-article {
|
|
42
|
+
font-size: 1rem;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</style>
|