Imported from incluud/accessible-astro-launcher (
AGENTS.md). Install upstream withnpx skills add incluud/accessible-astro-launcher. Copyright stays with the author.
Accessible Astro Launcher
An accessible command palette/launcher component for Astro projects with keyboard navigation, search, and WCAG 2.2 AA compliance.
Project Overview
- Type: NPM package / standalone component
- Published: https://www.npmjs.com/package/accessible-astro-launcher
- Repository: https://github.com/incluud/accessible-astro-launcher
Check package.json for current version and dependencies.
Key Characteristics
- Zero dependencies: Pure Astro component
- NPM package: Can be used in any Astro project
- Shared styles: Exports
index.csswith all component styles - TypeScript: Full type definitions in
src/types/index.d.ts - Modern CSS: Uses logical properties, custom properties,
light-dark()for theming - ARIA Guidance: Uses semantic HTML and minimal ARIA for command palettes
Project Purpose
This is the command palette/launcher component for the Accessible Astro ecosystem:
- Target Audience: Developers wanting keyboard-driven navigation in their Astro sites
- Features: Quick search, navigation items, action items, preference toggles
- Integration: Works seamlessly with
accessible-astro-componentspreference toggles - WCAG 2.2 AA: Fully compliant with comprehensive accessibility features
Package Structure
accessible-astro-launcher/
├── src/
│ ├── components/
│ │ └── launcher/
│ │ ├── Launcher.astro # Main dialog component
│ │ ├── LauncherTrigger.astro # Search field trigger
│ │ ├── LauncherPreferences.astro # Fieldset wrapper for preference switches
│ │ ├── LauncherSwitch.astro # Toggle switch item
│ │ ├── LauncherNav.astro # Navigation wrapper with heading
│ │ └── LauncherLink.astro # Semantic link item
│ ├── styles/
│ │ └── index.css # All component styles
│ └── types/
│ └── index.d.ts # TypeScript definitions
├── index.js # Package exports
├── package.json
├── tsconfig.json
├── .prettierrc
├── README.md
└── LICENSE
Available Components
Launcher
The main dialog component containing search input and results.
Props:
id: string- Unique identifier (required, must matchlauncherIdon triggers)labels?: LauncherLabels- i18n labels object (exported type)class?: string- Additional CSS classes
LauncherTrigger
A trigger button that opens the launcher with keyboard shortcut display.
Props:
launcherId: string- ID of the launcher to open (required)id?: string- Optional trigger element IDplaceholder?: string- Placeholder text (default: "Search")shortcutKey?: string- Keyboard shortcut key display (default: "K")compact?: boolean- Compact mode without placeholder texticonOnly?: boolean- Icon-only modegradientBorder?: boolean- Animated gradient border effectclass?: string- Additional CSS classes
LauncherPreferences
Fieldset wrapper for preference switches.
Props:
label: string- Group heading text (required)class?: string- Additional CSS classes[key: string]: string | undefined- Additional HTML attributes to apply to the fieldset
LauncherSwitch
Toggle switch item for preferences.
Props:
label: string- Display text (required)onAction: string- Action identifier for action itemschecked?: boolean- Initial checked state (maps to aria-checked)keywords?: string[]- Additional search keywordsclass?: string- Additional CSS classes[key: string]: string | string[] | boolean | undefined- Additional HTML attributes to apply to the wrapper
LauncherNav
Navigation wrapper with heading.
Props:
label: string- Group heading text (required)headingLevel?: 2 | 3 | 4 | 5 | 6- Heading level (default: 3)class?: string- Additional CSS classes[key: string]: string | number | undefined- Additional HTML attributes to apply to the nav element
Slots:
default- LauncherLink items
LauncherLink
Semantic link item for navigation.
Props:
label: string- Display text (required)href: string- URL for navigationkeywords?: string[]- Additional search keywordstypeLabel?: string- i18n label for type indicator (default: "Go to")class?: string- Additional CSS classes[key: string]: string | string[] | undefined- Additional HTML attributes to apply to the anchor (e.g., target, rel, aria-*)
Slots:
icon- Custom icon for navigation items
Extra attributes passed to LauncherLink are forwarded to the rendered anchor element.
Dev Environment Setup
-
Install dependencies:
npm install -
Development workflow:
- This is a pure component library (no dev server)
- Test components in consuming projects (starter, dashboard, docs)
- Use symlinks for local testing (see below)
-
Link to consuming projects:
# From the launcher directory npm link # In consuming project npm link accessible-astro-launcher -
Format code:
npx prettier --write .
Testing Components
Since this is a library package, testing happens in consuming projects:
- Link the package to a consuming project (see Dev Environment Setup)
- Import and use the component in a test page
- Test accessibility:
- Keyboard navigation (CMD/CTRL+K, Arrow keys, Enter, Escape)
- Screen reader compatibility (VoiceOver, NVDA, JAWS)
- Color contrast with browser dev tools
- Focus indicators are visible
- Check
prefers-reduced-motionbehavior
- Visual testing: Check in consuming project's browser
- Live demos: Test on starter's pages that use the launcher
Making Changes
Modifying Components
- Edit component file in
src/components/launcher/ - Update styles in
src/styles/index.cssif needed - Update TypeScript types if props changed
- Test changes in consuming projects (with symlinks for live reload)
- Update AGENTS.md/README if API changed
- Check for breaking changes - bump version accordingly
Versioning
- Patch (1.0.x): Bug fixes, no API changes
- Minor (1.x.0): New features, backward-compatible changes
- Major (x.0.0): Breaking changes to existing components
Publishing to NPM
-
Update version in
package.json(follow semver) -
Test thoroughly in all consuming projects
-
Format code:
npx prettier --write . -
Commit changes: Follow conventional commits
-
Publish:
npm publish -
Update consuming projects:
cd ../accessible-astro-starter npm update accessible-astro-launcher
Code Style Guidelines
Component Architecture
- Single Responsibility: Each component has one clear purpose
- Composition: Components can be nested (Launcher > LauncherPreferences > LauncherSwitch, Launcher > LauncherNav > LauncherLink)
- Props: Use Astro props with TypeScript interfaces
- Styles: Component styles in
src/styles/index.css - No Dependencies: Pure Astro components only
TypeScript
- Type definitions in
src/types/index.d.ts - Export all component prop interfaces
- Declare custom events and global APIs
Formatting
- Prettier configured with:
prettier-plugin-astroprettier-plugin-css-order
- Run:
npx prettier --write .
CSS Guidelines
- Modern CSS: Use logical properties (
inline-start,block-end, etc.) - Custom Properties: All styling via
--launcher-*CSS variables - Dark Mode: Use
light-dark()function for automatic theming - No Frameworks: Pure CSS, no Tailwind
- Low Specificity: Use
:where()wrapper for easy overrides - Reduced Motion: Respect
prefers-reduced-motionpreference
Accessibility Requirements
This component follows WCAG 2.2 AA standards with a semantic HTML approach:
Essential Features
-
Keyboard Navigation:
CMD/CTRL + K- Open launcherArrow Up/Down- Navigate itemsEnter- Select itemEscape- Close launcherTab- Move between header elements
-
ARIA Implementation:
- Dialog with
aria-modal="true" - Input uses
aria-controls,aria-ownsandaria-activedescendantfor active item tracking - Semantic fieldset/legend for preference groups
- Live region for results count announcements
- Dialog with
-
Focus Management:
- Focus moves to input on open
- Virtual focus via
aria-activedescendant - Focus returns to trigger on close
-
Visual Indicators:
- Clear focus outlines
- Selected item highlighting
- LED indicators for toggle actions
Custom Events
launcher:action
Dispatched when an action item is selected.
document.addEventListener('launcher:action', (e) => {
switch (e.detail.action) {
case 'toggle-dark-mode':
window.darkMode?.toggle()
break
case 'logout':
window.location.href = '/logout'
break
}
})
launcher:open
Dispatched when the launcher opens (useful for syncing preference states).
Integration with accessible-astro-components
The launcher automatically syncs with preference toggles from accessible-astro-components:
darkmode:change→ updatestoggle-dark-modeaction itemshighcontrast:change→ updatestoggle-high-contrastaction itemsreducemotion:change→ updatestoggle-reduced-motionaction items
CSS Custom Properties
All styling can be customized via CSS variables:
:root {
/* Colors */
--launcher-theme-light: #fff;
--launcher-theme-dark: #090b0f;
--launcher-text-color: /* auto light/dark */;
--launcher-subtle-text-color: /* auto light/dark */;
/* Dimensions */
--launcher-width: min(90vw, 650px);
--launcher-height: min(60vh, 500px);
/* Spacing */
--launcher-space-xs: /* fluid */;
--launcher-space-sm: /* fluid */;
--launcher-space-md: /* fluid */;
/* Animation */
--launcher-animation-duration: 0.2s;
--launcher-animation-timing: cubic-bezier(0.165, 0.84, 0.44, 1);
}
Commit Guidelines
Follow conventional commits format:
type(scope): subject
Types: feat, fix, docs, style, refactor, test, chore
Scopes: launcher, trigger, preferences, switch, nav, link, styles, types
Examples:
feat(switch): add typeLabel prop for i18nfix(launcher): improve search debouncinga11y(switch): enhance LED indicator contrast
PR Instructions
- Title format:
[launcher] Brief description - Check before submitting:
- Run
npx prettier --write .- code is formatted - Test in a consuming project
- Verify keyboard navigation works
- Check screen reader compatibility
- Ensure no console errors
- Verify
prefers-reduced-motionis respected
- Run
- Include in PR description:
- What changed and why
- Which components are affected
- Breaking changes (if any)
- Accessibility considerations
Troubleshooting
Symlink Not Working
- Verify link:
ls -la ../accessible-astro-starter/node_modules/accessible-astro-launcher - Check consuming project's
astro.config.mjshas symlink detection - Restart dev server
- Clear cache:
rm -rf node_modules/.astro node_modules/.vite
Styles Not Loading
- Ensure
index.jsimports./src/styles/index.css - Check consuming project imports the component (styles auto-load)
- Verify CSS custom properties are not being overridden
Keyboard Shortcut Not Working
- Check for conflicting CMD/CTRL+K bindings
- Verify trigger has
data-launcher-targetattribute matching launcherid - Check console for initialization warnings
Consuming Projects
This package is used by:
- accessible-astro-starter: Primary consumer, showcases launcher in header
- accessible-astro-dashboard: Dashboard with launcher integration
Check each project's package.json to see which version they're currently using.
Breaking Changes Impact
When making breaking changes, consider:
- All consuming projects need to update - test in each one
- Update documentation with migration guide
- Consider deprecation warnings before removal
- Coordinate version bumps across all projects
- Follow semantic versioning strictly
Related Projects
- Accessible Astro Components: Core component library
- Accessible Astro Starter: Starter theme
- Accessible Astro Dashboard: Dashboard theme
- Accessible Astro Docs: Documentation site