diff --git a/app/components/BaseCard.vue b/app/components/BaseCard.vue new file mode 100644 index 0000000000..4203f1b0de --- /dev/null +++ b/app/components/BaseCard.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/components/Filter/Panel.vue b/app/components/Filter/Panel.vue index e244829df6..349b174da0 100644 --- a/app/components/Filter/Panel.vue +++ b/app/components/Filter/Panel.vue @@ -228,7 +228,7 @@ const hasActiveFilters = computed(() => !!filterSummary.value) :value="filters.text" :placeholder="searchPlaceholder" autocomplete="off" - class="input-base" + class="w-full bg-bg-subtle border border-border rounded-md px-4 py-3 font-mono text-sm text-fg placeholder:text-fg-subtle transition-all duration-200 focus:(border-fg/40 outline-none ring-1 ring-fg/10)" @input="handleTextInput" /> diff --git a/app/components/Package/Card.vue b/app/components/Package/Card.vue index 28f39ae99e..44259da478 100644 --- a/app/components/Package/Card.vue +++ b/app/components/Package/Card.vue @@ -29,18 +29,7 @@ const pkgDescription = useMarkdown(() => ({ diff --git a/app/components/Package/Skeleton.vue b/app/components/Package/Skeleton.vue index 0b0c66e95b..89f429c1d0 100644 --- a/app/components/Package/Skeleton.vue +++ b/app/components/Package/Skeleton.vue @@ -12,20 +12,20 @@

- +

- - - + + +
- + @@ -36,7 +36,7 @@ {{ $t('package.skeleton.license') }}
- +
@@ -46,7 +46,7 @@ {{ $t('package.skeleton.weekly') }}
- +
@@ -56,7 +56,7 @@ {{ $t('package.skeleton.size') }}
- +
@@ -66,7 +66,7 @@ {{ $t('package.skeleton.deps') }}
- +
@@ -76,7 +76,7 @@ {{ $t('package.skeleton.published') }}
- +
@@ -85,16 +85,16 @@ @@ -110,10 +110,12 @@
-
- +
+
- +
@@ -131,20 +133,20 @@
- + - - - + + + - - - - + + + + -
- - + + +
@@ -161,10 +163,10 @@
  • - +
  • - +
@@ -179,12 +181,12 @@
    -
  • -
  • -
  • -
  • -
  • -
  • +
  • +
  • +
  • +
  • +
  • +
@@ -199,24 +201,24 @@
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -232,20 +234,20 @@
  • - - + +
  • - - + +
  • - - + +
  • - - + +
diff --git a/app/components/Package/WeeklyDownloadStats.vue b/app/components/Package/WeeklyDownloadStats.vue index 3cb4b93daf..057fe9f17b 100644 --- a/app/components/Package/WeeklyDownloadStats.vue +++ b/app/components/Package/WeeklyDownloadStats.vue @@ -221,20 +221,20 @@ const config = computed(() => {
- +
- +
-
diff --git a/app/components/SearchSuggestionCard.vue b/app/components/SearchSuggestionCard.vue index 9060f16ebb..5c0beff9e8 100644 --- a/app/components/SearchSuggestionCard.vue +++ b/app/components/SearchSuggestionCard.vue @@ -12,18 +12,7 @@ defineProps<{ diff --git a/app/components/Settings/Toggle.server.vue b/app/components/Settings/Toggle.server.vue index 71d4e4ee93..293618c67e 100644 --- a/app/components/Settings/Toggle.server.vue +++ b/app/components/Settings/Toggle.server.vue @@ -10,7 +10,7 @@ defineProps<{ {{ label }} - +

{{ description }} diff --git a/app/components/SkeletonBlock.vue b/app/components/SkeletonBlock.vue new file mode 100644 index 0000000000..7467e4c103 --- /dev/null +++ b/app/components/SkeletonBlock.vue @@ -0,0 +1,3 @@ + diff --git a/app/components/SkeletonInline.vue b/app/components/SkeletonInline.vue new file mode 100644 index 0000000000..3ac496f76b --- /dev/null +++ b/app/components/SkeletonInline.vue @@ -0,0 +1,3 @@ + diff --git a/app/pages/package-code/[...path].vue b/app/pages/package-code/[...path].vue index 268221d223..9ef07ae6ac 100644 --- a/app/pages/package-code/[...path].vue +++ b/app/pages/package-code/[...path].vue @@ -493,31 +493,31 @@ defineOgImageComponent('Default', {

- +
-
-
-
+ + +
-
-
-
-
+ + + +
-
-
-
-
+ + + +
-
-
-
-
-
-
+ + + + + +
diff --git a/app/pages/package-docs/[...path].vue b/app/pages/package-docs/[...path].vue index 6c25bc7534..eb3b862794 100644 --- a/app/pages/package-docs/[...path].vue +++ b/app/pages/package-docs/[...path].vue @@ -166,10 +166,10 @@ const showEmptyState = computed(() => docsData.value?.status !== 'ok')
-
-
-
-
+ + + +
diff --git a/app/pages/package/[...package].vue b/app/pages/package/[...package].vue index 2d1301ea89..7b0c1c8384 100644 --- a/app/pages/package/[...package].vue +++ b/app/pages/package/[...package].vue @@ -476,10 +476,10 @@ defineOgImageComponent('Package', { class="self-baseline ms-1 sm:ms-2" /> diff --git a/app/pages/~[username]/orgs.vue b/app/pages/~[username]/orgs.vue index b3320d1826..5cad2bba46 100644 --- a/app/pages/~[username]/orgs.vue +++ b/app/pages/~[username]/orgs.vue @@ -208,10 +208,7 @@ defineOgImageComponent('Default', { > {{ org.role }} - +
@@ -228,7 +225,7 @@ defineOgImageComponent('Default', { ) }} - +
diff --git a/test/nuxt/a11y.spec.ts b/test/nuxt/a11y.spec.ts index 1d0c50dc3c..277599977c 100644 --- a/test/nuxt/a11y.spec.ts +++ b/test/nuxt/a11y.spec.ts @@ -57,6 +57,7 @@ afterEach(() => { import { AppFooter, AppHeader, + BaseCard, UserAvatar, BuildEnvironment, CallToAction, @@ -211,6 +212,25 @@ describe('component accessibility audits', () => { }) }) + describe('BaseCard', () => { + it('should have no accessibility violations', async () => { + const component = await mountSuspended(BaseCard, { + slots: { default: '

Card content

' }, + }) + const results = await runAxe(component) + expect(results.violations).toEqual([]) + }) + + it('should have no accessibility violations with exact match highlight', async () => { + const component = await mountSuspended(BaseCard, { + props: { isExactMatch: true }, + slots: { default: '

Exact match content

' }, + }) + const results = await runAxe(component) + expect(results.violations).toEqual([]) + }) + }) + describe('TooltipApp', () => { it('should have no accessibility violations', async () => { const component = await mountSuspended(TooltipApp, { diff --git a/test/unit/a11y-component-coverage.spec.ts b/test/unit/a11y-component-coverage.spec.ts index 81d89fdfb6..129ff56504 100644 --- a/test/unit/a11y-component-coverage.spec.ts +++ b/test/unit/a11y-component-coverage.spec.ts @@ -41,6 +41,8 @@ const SKIPPED_COMPONENTS: Record = { 'Package/WeeklyDownloadStats.vue': 'Uses vue-data-ui VueUiSparkline - has DOM measurement issues in test environment', 'UserCombobox.vue': 'Unused component - intended for future admin features', + 'SkeletonBlock.vue': 'Already covered indirectly via other component tests', + 'SkeletonInline.vue': 'Already covered indirectly via other component tests', } /** diff --git a/uno.config.ts b/uno.config.ts index 284aabc760..4d9c6eac47 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -142,19 +142,6 @@ export default defineConfig({ ], ['link-subtle', 'text-fg-muted hover:text-fg transition-colors duration-200 focus-ring'], - // Cards - [ - 'card', - 'bg-bg-subtle border border-border rounded-lg p-4 sm:p-6 transition-[border-color,background-color] duration-200', - ], - ['card-interactive', 'card hover:(border-border-hover bg-bg-muted) cursor-pointer'], - - // Form elements - [ - 'input-base', - 'w-full bg-bg-subtle border border-border rounded-md px-4 py-3 font-mono text-sm text-fg placeholder:text-fg-subtle transition-all duration-200 focus:(border-fg/40 outline-none ring-1 ring-fg/10)', - ], - // Tags/badges [ 'tag', @@ -169,21 +156,6 @@ export default defineConfig({ ['badge-purple', 'bg-badge-purple/10 text-badge-purple'], ['badge-pink', 'bg-badge-pink/10 text-badge-pink'], ['badge-subtle', 'bg-bg-subtle text-fg-subtle'], - - // Code blocks - [ - 'code-block', - 'bg-bg-muted border border-border rounded-md p-4 font-mono text-sm overflow-x-auto', - ], - - // Skeleton loading - ['skeleton', 'bg-bg-elevated rounded animate-skeleton-pulse'], - - // Subtle divider - ['divider', 'border-t border-border'], - - // Section spacing - ['section', 'py-8 sm:py-12'], ], rules: [ // Custom scale for active states