diff --git a/src/components/Nav.astro b/src/components/Nav.astro new file mode 100644 index 0000000..5a75cbc --- /dev/null +++ b/src/components/Nav.astro @@ -0,0 +1,21 @@ +--- +import Navigation from './Navigation.astro' + +/** + * Nav Component + * + * @description Main navigation wrapper that uses the accessible Navigation component + * This component provides professional-level accessibility following WCAG 2.1 guidelines + * + * Keyboard behaviors (inherited from Navigation.astro): + * - ArrowLeft/ArrowRight: Navigate between top-level menu items + * - ArrowDown: Open dropdown and navigate down through items + * - ArrowUp: Navigate up through dropdown items + * - Escape: Close dropdown/mobile menu and return focus to trigger + * - Tab: Standard tab navigation with proper focus management + */ +--- + +
+ +
diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro new file mode 100644 index 0000000..687dbd2 --- /dev/null +++ b/src/components/Navigation.astro @@ -0,0 +1,492 @@ +--- +import ResponsiveToggle from './ResponsiveToggle.astro' +import { getEntry } from 'astro:content' + +/** + * Navigation Component + * + * @description An accessible navigation component with full keyboard support + * Based on accessible-astro-starter patterns with PyCon ES styling + * + * Keyboard behaviors: + * - ArrowLeft/ArrowRight: Navigate between top-level menu items + * - ArrowDown: Open dropdown and navigate down through items + * - ArrowUp: Navigate up through dropdown items + * - Escape: Close dropdown/mobile menu and return focus + * - Tab: Standard tab navigation, closes dropdown on last item + */ + +// Load menu data +const menuData = await getEntry('menu', 'main') + +if (!menuData) { + throw new Error('No se encontró el archivo src/content/menu/main.json') +} + +const { items } = menuData.data +--- + + + + + + diff --git a/src/components/ResponsiveToggle.astro b/src/components/ResponsiveToggle.astro new file mode 100644 index 0000000..c6b9cbc --- /dev/null +++ b/src/components/ResponsiveToggle.astro @@ -0,0 +1,119 @@ +--- +/** + * ResponsiveToggle Component + * + * @description A toggle button for mobile navigation with full accessibility support + * Based on accessible-astro-starter patterns + */ +interface Props { + /** + * Additional classes to apply to the ResponsiveToggle + */ + class?: string +} + +const { class: className } = Astro.props +--- + + + + + + diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..3d238b6 --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,24 @@ +import { defineCollection, z } from 'astro:content'; + +const menuCollection = defineCollection({ + type: 'data', + schema: z.object({ + items: z.array( + z.object({ + label: z.string(), + href: z.string().optional(), + // optional + children: z.array( + z.object({ + label: z.string(), + href: z.string(), + }) + ).optional(), + }) + ) + }) +}); + +export const collections = { + 'menu': menuCollection, +}; \ No newline at end of file diff --git a/src/content/menu/main.json b/src/content/menu/main.json new file mode 100644 index 0000000..4d54c8c --- /dev/null +++ b/src/content/menu/main.json @@ -0,0 +1,42 @@ +{ + "items": [ + { + "label": "Inicio", + "href": "/" + }, + { + "label": "La Conferencia", + "children": [ + { + "label": "Speakers", + "href": "/speakers" + }, + { + "label": "Agenda", + "href": "/agenda" + }, + { + "label": "Sede", + "href": "/location" + } + ] + }, + { + "label": "Patrocinios", + "href": "/sponsorship" + }, + { + "label": "Ediciones Anteriores", + "children": [ + { + "label": "2025 (Sevilla)", + "href": "https://2025.es.pycon.org" + }, + { + "label": "2024 (Vigo)", + "href": "https://2024.es.pycon.org" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 8fe12f7..45675f0 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -2,6 +2,7 @@ import '../style/global.css' import '@fontsource-variable/jetbrains-mono' import { ClientRouter } from 'astro:transitions' +import Nav from '../components/Nav.astro' interface Props { title: string @@ -28,7 +29,10 @@ const { title, description = 'PyconES 2026' } = Astro.props - +