8000 bth and btd scope attribute updates and bpagination li element needs presentation role by rgeerts · Pull Request #2646 · bootstrap-vue-next/bootstrap-vue-next · GitHub
[go: up one dir, main page]

Skip to content

bth and btd scope attribute updates and bpagination li element needs presentation role #2646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/docs/src/data/components/table.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,10 @@ export default {
type: 'ColorVariant | null',
default: null,
},
scope: {
type: 'string',
default: undefined,
},
} satisfies Record<keyof BvnComponentProps['BTh'], PropertyReference>,
},
emits: [],
Expand Down
1 change: 1 addition & 0 deletions apps/docs/src/docs/components/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ The following field properties (defined as [TableField](/docs/types#tableitem))
| `thAttr` | `AttrsValue \| ((value: unknown, key: string, item: T \| null, type: TableRowThead) => AttrsValue` | Object representing additional attributes to apply to the field's `<thead>`/`<tfoot>` heading `<th>` cell. If the field's `isRowHeader` is set to `true`, the attributes will also apply to the `<tbody>` field `<th>` cell. If custom attributes per cell are required, a callback function can be specified instead. See the typescript definition for accepted parameters and return types. |
| `isRowHeader` | `boolean` | When set to `true`, the field's item data cell will be rendered with `<th>` rather than the default of `<td>`. |
| `stickyColumn` | `boolean` | When set to `true`, and the table in [responsive](#responsive-tables) mode or has [sticky headers](#sticky-headers), will cause the column to become fixed to the left when the table's horizontal scrollbar is scrolled. See [Sticky columns](#sticky-columns) for more details |
| `scope` | `TableThScope` | The scope attribute for the field's `<th>` element. This is used to specify the relationship of the header cell to the data cells. Valid values are `row`, `col`, `rowgroup`, and `colgroup`. Defaults to `colgroup` if `colspan` specified, `rowgroup` if `rowspan` specified, otherwise `col`. |

**Notes:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ const getBaseButtonProps = ({
label,
position,
isActive,
role,
hidden,
isSmHidden,
}: {
Expand All @@ -160,7 +159,6 @@ const getBaseButtonProps = ({
label?: string
position?: number
isActive?: boolean
role?: string
hidden?: boolean
isSmHidden?: boolean
}) => ({
Expand All @@ -176,7 +174,7 @@ const getBaseButtonProps = ({
},
classVal,
],
role,
'role': 'presentation',
'aria-hidden': hidden,
},
button: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ describe('pagination', () => {
expect($li.classes()).toContain('page-item')
})

it('li child has static role', () => {
const wrapper = mount(BPagination)
const $li = wrapper.get('li')
expect($li.attributes('role')).toBe('presentation')
})

it('has first button by default', () => {
const wrapper = mount(BPagination, {props: {totalRows: 100, perPage: 1, modelValue: 5}})
expect(wrapper.find('[aria-label="Go to first page"]').exists()).toBeTruthy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<BTh
v-for="field in computedFields"
:key="field.key"
scope="col"
:scope="field.scope"
:class="getFieldColumnClasses(field)"
:title="field.headerTitle"
:variant="field.variant"
Expand Down
3 changes: 0 additions & 3 deletions packages/bootstrap-vue-next/src/components/BTable/BTd.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<template>
<td
:scope="scope"
:class="computedClasses"
:colspan="props.colspan"
:rowspan="props.rowspan"
Expand Down Expand Up @@ -37,6 +36,4 @@ const computedClasses = computed(() => ({
'b-table-sticky-column': props.stickyColumn,
'table-b-table-default': props.stickyColumn && props.variant === null,
}))

const scope = computed(() => (props.colspan ? 'colspan' : props.rowspan ? 'rowspan' : 'col'))
</script>
7 changes: 5 additions & 2 deletions packages/bootstrap-vue-next/src/components/BTable/BTh.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<th
:scope="scope"
:scope="localScope"
:class="computedClasses"
:colspan="props.colspan"
:rowspan="props.rowspan"
Expand All @@ -24,6 +24,7 @@ const _props = withDefaults(defineProps<BThProps>(), {
stackedHeading: undefined,
stickyColumn: false,
variant: null,
scope: undefined,
})
const props = useDefaults(_props, 'BTh')

Expand All @@ -38,5 +39,7 @@ const computedClasses = computed(() => ({
'table-b-table-default': props.stickyColumn && props.variant === null,
}))

const scope = computed(() => (props.colspan ? 'colspan' : props.rowspan ? 'rowspan' : 'col'))
const localScope = computed(() =>
props.scope ? props.scope : props.colspan ? 'colgroup' : props.rowspan ? 'rowgroup' : 'col'
)
</script>
30 changes: 0 additions & 30 deletions packages/bootstrap-vue-next/src/components/BTable/td.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,36 +75,6 @@ describe('td', () => {
expect(wrapper.classes()).not.toContain('table-b-table-default')
})

it('has attr scope to be colspan when prop colspan', () => {
const wrapper = mount(BTd, {
props: {
colspan: '6',
},
})
expect(wrapper.attributes('scope')).toBe('colspan')
})

it('has attr scope to be rowspan when prop rowspan', () => {
const wrapper = mount(BTd, {
props: {
rowspan: '6',
},
})
expect(wrapper.attributes('scope')).toBe('rowspan')
})

it('has attr scope to be col by default', () => {
const wrapper = mount(BTd)
expect(wrapper.attributes('scope')).toBe('col')
})

it('has scope colspan when both rowspan and colspan', () =& F438 gt; {
const wrapper = mount(BTd, {
props: {colspan: 6, rowspan: 5},
})
expect(wrapper.attributes('scope')).toBe('colspan')
})

it('does not have a nested div by default when stackedHeading is undefined', () => {
const wrapper = mount(BTd)
const $div = wrapper.find('div')
Expand Down
31 changes: 25 additions & 6 deletions packages/bootstrap-vue-next/src/components/BTable/th.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,34 +75,53 @@ describe('th', () => {
expect(wrapper.classes()).not.toContain('table-b-table-default')
})

it('has attr scope to be colspan when prop colspan', () => {
it('has attr scope to be colgroup when prop colspan', () => {
const wrapper = mount(BTh, {
props: {
colspan: '6',
},
})
expect(wrapper.attributes('scope')).toBe('colspan')
expect(wrapper.attributes('scope')).toBe('colgroup')
})

it('has attr scope to be rowspan when prop rowspan', () => {
it('has attr scope to be rowgroup when prop rowspan', () => {
const wrapper = mount(BTh, {
props: {
rowspan: '6',
},
})
expect(wrapper.attributes('scope')).toBe('rowspan')
expect(wrapper.attributes('scope')).toBe('rowgroup')
})

it('has attr scope to be col by default', () => {
const wrapper = mount(BTh)
expect(wrapper.attributes('scope')).toBe('col')
})

it('has scope colspan when both rowspan and colspan', () => {
it('can override attr scope to be row when prop scope set', () => {
const wrapper = mount(BTh, {
props: {
scope: 'row',
},
})
expect(wrapper.attributes('scope')).toBe('row')
})

it('can override attr scope to be row when props scope and colspan are set', () => {
const wrapper = mount(BTh, {
props: {
scope: 'row',
colspan: '5',
},
})
expect(wrapper.attributes('scope')).toBe('row')
})

it('has scope colgroup when both rowspan and colspan', () => {
const wrapper = mount(BTh, {
props: {colspan: 6, rowspan: 5},
})
expect(wrapper.attributes('scope')).toBe('colspan')
expect(wrapper.attributes('scope')).toBe('colgroup')
})

it('does not have a nested div by default when stackedHeading is undefined', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import {defineComponent, h, type PropType, type SlotsType, Teleport, type Telepo
export default defineComponent({
name: 'ConditionalTeleport',
inheritAttrs: false,
slots: Object as SlotsType<{
default?: Record<string, never>
}>,
props: {
to: {
type: [String, Object] as PropType<TeleportProps['to']>,
Expand All @@ -17,6 +14,9 @@ export default defineComponent({
required: true,
},
},
slots: Object as SlotsType<{
default?: Record<string, never>
}>,
setup(props, {slots}) {
// use this untill https://github.com/vuejs/core/issues/9782 is resolved
return () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import {defineComponent, h, type SlotsType} from 'vue'
export default defineComponent({
name: 'ConditionalWrapper',
inheritAttrs: false,
slots: Object as SlotsType<{
default?: Record<string, never>
}>,
props: {
tag: {
type: String,
Expand All @@ -17,6 +14,9 @@ export default defineComponent({
required: true,
},
},
slots: Object as SlotsType<{
default?: Record<string, never>
}>,
setup(props, {slots, attrs}) {
return () =>
props.skip ? slots.default?.({}) : h(props.tag, {...attrs}, [slots.default?.({})])
Expand Down
2 changes: 2 additions & 0 deletions packages/bootstrap-vue-next/src/types/ComponentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import type {
TableFieldRaw,
TableRowType,
TableStrictClassValue,
TableThScope,
} from './TableTypes'
import type {PopoverPlacement} from './PopoverPlacement'
import type {InputType} from './InputType'
Expand Down Expand Up @@ -1146,6 +1147,7 @@ export interface BThProps {
stackedHeading?: string
stickyColumn?: boolean
variant?: ColorVariant | null
scope?: TableThScope
}

export interface BProgressBarProps extends ColorExtendables {
Expand Down
3 changes: 3 additions & 0 deletions packages/bootstrap-vue-next/src/types/TableTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type TableField<T = any> = {
| ((value: unknown, key: string, item: T | null, type: TableRowThead) => AttrsValue)
isRowHeader?: boolean
stickyColumn?: boolean
scope?: TableThScope
}

export type TableFieldRaw<T = unknown> = T extends object
Expand All @@ -85,3 +86,5 @@ export const isTableFieldRaw = <T>(value: unknown): value is TableFieldRaw<T> =>
typeof value === 'string' || isTableField(value)

export type NoProviderTypes = 'paging' | 'sorting' | 'filtering'

export type TableThScope = 'row' | 'col' | 'rowgroup' | 'colgroup'
0