Skip to content

Commit 91514af

Browse files
authored
feat(table): add support for transitions on tbody element (Closes #1821) (#2450)
Renders the `<tbody>` element usingVue's `<transition-group>` component. Users can pass an object of props via the `tbodyTransitionProps` prop, and can also pass an object of transition event handlers via the `tbodyTransitionHandlers` props. When neither prop is specified, no transitions will occur.
1 parent 3723493 commit 91514af

File tree

3 files changed

+105
-5
lines changed

3 files changed

+105
-5
lines changed

docs/assets/css/styles.css

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,10 @@
1313
z-index: 999999;
1414
}
1515

16-
1716
* {
1817
-webkit-font-smoothing: antialiased;
1918
}
2019

21-
22-
2320
.bd-toc-link, .bd-navbar .navbar-nav .nav-link.active {
2421
font-weight: normal;
2522
}
@@ -118,3 +115,8 @@ pre.editable.error:after {
118115
min-height: 10rem;
119116
background-color: rgba(255, 0, 0, .1);
120117
}
118+
119+
/* CSS for table transtion example */
120+
table#table-transition-example .flip-list-move {
121+
transition: transform 1s;
122+
}

src/components/table/README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,77 @@ remove the record from the original items array.
13341334

13351335
**Note:** _Do not bind any value directly to the `value` prop. Use the `v-model` binding._
13361336

1337+
## Table body transition support
1338+
1339+
Vue transitions and animations are optionally supported on the `<tbody>` element via the use of Vue's
1340+
`<transition-group>` component internally. Three props are available for transitions support (all three
1341+
default to undefined):
1342+
1343+
| Prop | Type | Description
1344+
| --------------------------- | ------ | ----------------------------------------------------------------- |
1345+
| `tbody-transition-props` | Object | Object of transition-group properties |
1346+
| `tbody-transition-handlers` | Object | Object of transition-group event handlers |
1347+
| `primary-key` | String | String specifying the field to use as a unique row key (required) |
1348+
1349+
To enable transitons you need to specify `tbody-transition-props` and/or `tbody-transition-handlers`,
1350+
and must specify which field key to use as a unique key via the `primary-key` prop. Your data **must
1351+
have** a column (specified by the `primary-key` prop) that has a **unique value per row** in order for
1352+
transitions to work properly. The `primary-key` field's _value_ can either be a unique string or number.
1353+
The field specified does not need to appear in the rendered table output, but it **must** exist in each
1354+
row of your items data.
1355+
1356+
You must also provide CSS to handle your transitions (if using CSS transitions) in your project.
1357+
1358+
For more information of Vue's list rendering transitions, see the
1359+
[Vue JS official docs](https://vuejs.org/v2/guide/transitions.html#List-Move-Transitions).
1360+
1361+
In the example below, we have used the following custom CSS:
1362+
1363+
```css
1364+
table#table-transition-example .flip-list-move {
1365+
transition: transform 1s;
1366+
}
1367+
```
1368+
1369+
```html
1370+
<template>
1371+
<b-table id="table-transition-example"
1372+
:items="items"
1373+
:fields="fields"
1374+
striped
1375+
small
1376+
primary-key="a"
1377+
:tbody-transition-props="transProps"
1378+
/>
1379+
</template>
1380+
1381+
<script>
1382+
export default {
1383+
data () {
1384+
return {
1385+
transProps: {
1386+
// Transition name
1387+
name: 'flip-list'
1388+
},
1389+
items: [
1390+
{a: 2, b: 'Two', c: 'Moose'},
1391+
{a: 1, b: 'Three', c: 'Dog'},
1392+
{a: 3, b: 'Four', c: 'Cat'},
1393+
{a: 4, b: 'One', c: 'Mouse'}
1394+
],
1395+
fields: [
1396+
{ key: 'a', sortable: true },
1397+
{ key: 'b', sortable: true },
1398+
{ key: 'c', sortable: true }
1399+
]
1400+
}
1401+
}
1402+
}
1403+
</script>
1404+
1405+
<!-- table-transitions.vue -->
1406+
```
1407+
13371408
## Using Items Provider Functions
13381409

13391410
As mentioned under the [**Items**](#items-record-data-) prop section, it is possible to use a

src/components/table/table.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,14 @@ export default {
352352
// Passthrough prop. Passed to the context object. Not used by b-table directly
353353
type: String,
354354
default: ''
355+
},
356+
tbodyTransitionProps: {
357+
type: Object
358+
// default: undefined
359+
},
360+
tbodyTransitionHandlers: {
361+
type: Object
362+
// default: undefined
355363
}
356364
},
357365
data() {
@@ -1508,10 +1516,29 @@ export default {
15081516
rows.push(h(false))
15091517
}
15101518

1519+
// Is tbody transition enabled
1520+
const isTransGroup = this.tbodyTransitionProps || this.tbodyTransitionHandlers
1521+
let tbodyProps = {}
1522+
let tbodyOn = {}
1523+
if (isTransGroup) {
1524+
tbodyOn = this.tbodyTransitionHandlers || {}
1525+
tbodyProps = assign(
1526+
{},
1527+
this.tbodyTransitionProps || {},
1528+
// Always use tbody element as tag. Users can't override this.
1529+
{ tag: 'tbody' }
1530+
)
1531+
}
1532+
15111533
// Assemble the rows into the tbody
15121534
const tbody = h(
1513-
'tbody',
1514-
{ class: this.bodyClasses, attrs: this.isStacked ? { role: 'rowgroup' } : {} },
1535+
isTransGroup ? 'transition-group' : 'tbody',
1536+
{
1537+
props: tbodyProps,
1538+
on: tbodyOn,
1539+
class: this.bodyClasses,
1540+
attrs: this.isStacked ? { role: 'rowgroup' } : {}
1541+
},
15151542
rows
15161543
)
15171544

0 commit comments

Comments
 (0)