feat(vue/primitives): add FocusScope component with auto-focus and focus trap functionality

This commit is contained in:
2026-03-10 18:28:52 +07:00
parent a996eb74b9
commit 4574bae0b6
36 changed files with 1266 additions and 65 deletions
@@ -19,8 +19,8 @@ const disabled = computed(() => ctx.isFirstPage.value || ctx.disabled.value);
const attrs = computed(() => ({
'aria-label': 'First Page',
'type': as === 'button' ? 'button' as const : undefined,
'disabled': disabled.value,
type: as === 'button' ? 'button' as const : undefined,
disabled: disabled.value,
}));
function handleClick() {
@@ -19,8 +19,8 @@ const disabled = computed(() => ctx.isLastPage.value || ctx.disabled.value);
const attrs = computed(() => ({
'aria-label': 'Last Page',
'type': as === 'button' ? 'button' as const : undefined,
'disabled': disabled.value,
type: as === 'button' ? 'button' as const : undefined,
disabled: disabled.value,
}));
function handleClick() {
@@ -25,8 +25,8 @@ const attrs = computed(() => ({
'aria-label': `Page ${value}`,
'aria-current': isSelected.value ? 'page' as const : undefined,
'data-selected': isSelected.value ? 'true' : undefined,
'disabled': disabled.value,
'type': as === 'button' ? 'button' as const : undefined,
disabled: disabled.value,
type: as === 'button' ? 'button' as const : undefined,
}));
function handleClick() {
@@ -19,8 +19,8 @@ const disabled = computed(() => ctx.isLastPage.value || ctx.disabled.value);
const attrs = computed(() => ({
'aria-label': 'Next Page',
'type': as === 'button' ? 'button' as const : undefined,
'disabled': disabled.value,
type: as === 'button' ? 'button' as const : undefined,
disabled: disabled.value,
}));
function handleClick() {
@@ -19,8 +19,8 @@ const disabled = computed(() => ctx.isFirstPage.value || ctx.disabled.value);
const attrs = computed(() => ({
'aria-label': 'Previous Page',
'type': as === 'button' ? 'button' as const : undefined,
'disabled': disabled.value,
type: as === 'button' ? 'button' as const : undefined,
disabled: disabled.value,
}));
function handleClick() {
@@ -13,7 +13,7 @@ export interface PaginationRootProps extends PrimitiveProps {
<script setup lang="ts">
import { toRef } from 'vue';
import { useOffsetPagination, useForwardExpose } from '@robonen/vue';
import { useForwardExpose, useOffsetPagination } from '@robonen/vue';
import { Primitive } from '@/primitive';
import { providePaginationContext } from './context';
@@ -1,15 +1,15 @@
import { describe, it, expect } from 'vitest';
import { describe, expect, it } from 'vitest';
import { defineComponent, h, nextTick, ref } from 'vue';
import { mount } from '@vue/test-utils';
import {
PaginationRoot,
PaginationEllipsis,
PaginationFirst,
PaginationLast,
PaginationList,
PaginationListItem,
PaginationFirst,
PaginationPrev,
PaginationNext,
PaginationLast,
PaginationEllipsis,
PaginationPrev,
PaginationRoot,
} from '..';
import type { PaginationItem } from '../utils';
@@ -23,10 +23,10 @@ function createPagination(props: Record<string, unknown> = {}) {
h(
PaginationRoot,
{
'total': 100,
'pageSize': 10,
total: 100,
pageSize: 10,
...props,
'page': page.value,
page: page.value,
'onUpdate:page': (v: number) => {
page.value = v;
},
@@ -1,16 +1,16 @@
import { describe, it, expect } from 'vitest';
import { describe, expect, it } from 'vitest';
import { defineComponent, h, ref } from 'vue';
import { mount } from '@vue/test-utils';
import axe from 'axe-core';
import {
PaginationRoot,
PaginationEllipsis,
PaginationFirst,
PaginationLast,
PaginationList,
PaginationListItem,
PaginationFirst,
PaginationPrev,
PaginationNext,
PaginationLast,
PaginationEllipsis,
PaginationPrev,
PaginationRoot,
} from '..';
import type { PaginationItem } from '../utils';
@@ -30,10 +30,10 @@ function createPagination(props: Record<string, unknown> = {}) {
h(
PaginationRoot,
{
'total': 100,
'pageSize': 10,
total: 100,
pageSize: 10,
...props,
'page': page.value,
page: page.value,
'onUpdate:page': (v: number) => {
page.value = v;
},
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { getRange, transform, PaginationItemType } from '../utils';
import { describe, expect, it } from 'vitest';
import { PaginationItemType, getRange, transform } from '../utils';
describe(getRange, () => {
it('returns empty array for zero total pages', () => {