Skip to content

Commit

Permalink
feat(VDataTable): index prop in item* slots (#12605)
Browse files Browse the repository at this point in the history
Co-authored-by: Kael <kaelwd@gmail.com>

resolves #10646
  • Loading branch information
jacekkarczmarczyk committed Nov 17, 2020
1 parent e35d79b commit 9daeb16
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions packages/api-generator/src/maps/v-data-iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const DataIteratorSlots = [

const DataIteratorItemScopedProps = {
expand: '(v: boolean) => void',
index: 'number',
item: 'any',
isExpanded: 'boolean',
isMobile: 'boolean',
Expand Down
2 changes: 1 addition & 1 deletion packages/api-generator/src/maps/v-data-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const DataTableSlots = [
{ name: 'group', props: DataGroupScopedProps },
{ name: 'group.header', props: DataGroupHeaderScopedProps },
{ name: 'group.summary', props: DataGroupSummaryScopedProps },
{ name: 'item', props: { ...DataTableItemScopedProps, index: 'number' } },
{ name: 'item', props: DataTableItemScopedProps },
{ name: 'item.data-table-select', props: DataTableItemScopedProps },
{ name: 'item.data-table-expand', props: DataTableItemScopedProps },
{ name: 'item.<name>', props: DataTableItemColumnScopedProps },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,10 @@ export default mixins(
this.expansion = expansion
this.$emit('item-expanded', { item, value })
},
createItemProps (item: any): DataItemProps {
createItemProps (item: any, index: number): DataItemProps {
return {
item,
index,
select: (v: boolean) => this.select(item, v),
isSelected: this.isSelected(item),
expand: (v: boolean) => this.expand(item, v),
Expand Down Expand Up @@ -244,7 +245,10 @@ export default mixins(
}

if (this.$scopedSlots.item) {
return props.items.map((item: any) => this.$scopedSlots.item!(this.createItemProps(item)))
return props.items.map((item: any, index) => this.$scopedSlots.item!(this.createItemProps(
item,
index
)))
}

return []
Expand Down
9 changes: 8 additions & 1 deletion packages/vuetify/src/components/VDataTable/MobileRow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default Vue.extend({
props: {
headers: Array as PropType<DataTableHeader[]>,
hideDefaultHeader: Boolean,
index: Number,
item: Object,
rtl: Boolean,
},
Expand All @@ -30,7 +31,13 @@ export default Vue.extend({
const regularSlot = computedSlots[slotName]

if (scopedSlot) {
children.push(scopedSlot({ item: props.item, isMobile: true, header, value }))
children.push(scopedSlot({
item: props.item,
isMobile: true,
header,
index: props.index,
value,
}))
} else if (regularSlot) {
children.push(regularSlot)
} else {
Expand Down
9 changes: 8 additions & 1 deletion packages/vuetify/src/components/VDataTable/Row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default Vue.extend({

props: {
headers: Array as PropType<DataTableHeader[]>,
index: Number,
item: Object,
rtl: Boolean,
},
Expand All @@ -28,7 +29,13 @@ export default Vue.extend({
const regularSlot = computedSlots[slotName]

if (scopedSlot) {
children.push(scopedSlot({ item: props.item, isMobile: false, header, value }))
children.push(scopedSlot({
item: props.item,
isMobile: false,
header,
index: props.index,
value,
}))
} else if (regularSlot) {
children.push(regularSlot)
} else {
Expand Down
23 changes: 12 additions & 11 deletions packages/vuetify/src/components/VDataTable/VDataTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ export default mixins(
customSortWithHeaders (items: any[], sortBy: string[], sortDesc: boolean[], locale: string) {
return this.customSort(items, sortBy, sortDesc, locale, this.columnSorters)
},
createItemProps (item: any): DataTableItemProps {
const props = VDataIterator.options.methods.createItemProps.call(this, item)
createItemProps (item: any, index: number): DataTableItemProps {
const props = VDataIterator.options.methods.createItemProps.call(this, item, index)

return Object.assign(props, { headers: this.computedHeaders })
},
Expand Down Expand Up @@ -407,15 +407,15 @@ export default mixins(
for (let i = 0; i < items.length; i++) {
const item = items[i]
rows.push(this.$scopedSlots.item!({
...this.createItemProps(item),
index: i,
...this.createItemProps(item, i),
isMobile: this.isMobile,
}))

if (this.isExpanded(item)) {
rows.push(this.$scopedSlots['expanded-item']!({
headers: this.computedHeaders,
isMobile: this.isMobile,
index: i,
item,
}))
}
Expand All @@ -425,15 +425,15 @@ export default mixins(
},
genDefaultRows (items: any[], props: DataScopeProps) {
return this.$scopedSlots['expanded-item']
? items.map(item => this.genDefaultExpandedRow(item))
: items.map(item => this.genDefaultSimpleRow(item))
? items.map((item, index) => this.genDefaultExpandedRow(item, index))
: items.map((item, index) => this.genDefaultSimpleRow(item, index))
},
genDefaultExpandedRow (item: any): VNode {
genDefaultExpandedRow (item: any, index: number): VNode {
const isExpanded = this.isExpanded(item)
const classes = {
'v-data-table__expanded v-data-table__expanded__row': isExpanded,
}
const headerRow = this.genDefaultSimpleRow(item, classes)
const headerRow = this.genDefaultSimpleRow(item, index, classes)
const expandedRow = this.$createElement('tr', {
staticClass: 'v-data-table__expanded v-data-table__expanded__content',
}, [this.$scopedSlots['expanded-item']!({
Expand All @@ -451,10 +451,10 @@ export default mixins(
this.$createElement('template', { slot: 'row.content' }, [expandedRow]),
])
},
genDefaultSimpleRow (item: any, classes: Record<string, boolean> = {}): VNode {
genDefaultSimpleRow (item: any, index: number, classes: Record<string, boolean> = {}): VNode {
const scopedSlots = getPrefixedScopedSlots('item.', this.$scopedSlots)

const data = this.createItemProps(item)
const data = this.createItemProps(item, index)

if (this.showSelect) {
const slot = scopedSlots['data-table-select']
Expand Down Expand Up @@ -498,6 +498,7 @@ export default mixins(
props: {
headers: this.computedHeaders,
hideDefaultHeader: this.hideDefaultHeader,
index,
item,
rtl: this.$vuetify.rtl,
},
Expand Down Expand Up @@ -631,7 +632,7 @@ export default mixins(
'page-count': (v: number) => this.$emit('page-count', v),
},
scopedSlots: {
default: this.genDefaultScopedSlot as any,
default: this.genDefaultScopedSlot,
},
})
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8952,19 +8952,19 @@ exports[`VDataTable.ts should render with item scoped slot 1`] = `
</thead>
<tbody>
<div>
{"item":{"name":"Frozen Yogurt","calories":159,"fat":6,"carbs":24,"protein":4,"iron":"1%","class":"test"},"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}],"index":0}
{"item":{"name":"Frozen Yogurt","calories":159,"fat":6,"carbs":24,"protein":4,"iron":"1%","class":"test"},"index":0,"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}]}
</div>
<div>
{"item":{"name":"Ice cream sandwich","calories":237,"fat":9,"carbs":37,"protein":4.3,"iron":"1%","class":["test","second"]},"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}],"index":1}
{"item":{"name":"Ice cream sandwich","calories":237,"fat":9,"carbs":37,"protein":4.3,"iron":"1%","class":["test","second"]},"index":1,"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}]}
</div>
<div>
{"item":{"name":"Eclair","calories":262,"fat":16,"carbs":23,"protein":6,"iron":"7%","class":{"test":true,"second":false}},"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}],"index":2}
{"item":{"name":"Eclair","calories":262,"fat":16,"carbs":23,"protein":6,"iron":"7%","class":{"test":true,"second":false}},"index":2,"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}]}
</div>
<div>
{"item":{"name":"Cupcake","calories":305,"fat":3.7,"carbs":67,"protein":4.3,"iron":"8%"},"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}],"index":3}
{"item":{"name":"Cupcake","calories":305,"fat":3.7,"carbs":67,"protein":4.3,"iron":"8%"},"index":3,"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}]}
</div>
<div>
{"item":{"name":"Gingerbread","calories":356,"fat":16,"carbs":49,"protein":3.9,"iron":"16%"},"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}],"index":4}
{"item":{"name":"Gingerbread","calories":356,"fat":16,"carbs":49,"protein":3.9,"iron":"16%"},"index":4,"isSelected":false,"isExpanded":false,"isMobile":true,"headers":[{"text":"Dessert (100g serving)","align":"left","sortable":false,"value":"name"},{"text":"Calories","value":"calories"},{"text":"Fat (g)","value":"fat"},{"text":"Carbs (g)","value":"carbs"},{"text":"Protein (g)","value":"protein"},{"text":"Iron (%)","value":"iron"}]}
</div>
</tbody>
</table>
Expand Down
1 change: 1 addition & 0 deletions packages/vuetify/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export interface DataPagination {
}

export interface DataItemProps {
index: number
item: any
select: (v: boolean) => void
isSelected: boolean
Expand Down

0 comments on commit 9daeb16

Please sign in to comment.