Skip to content

Commit

Permalink
feat(Table): improve expanded row (#2485)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdjanuar authored Nov 5, 2024
1 parent 0b2a398 commit 1acd01a
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script setup>
const people = [{
id: 1,
name: 'Lindsay Walton',
title: 'Front-end Developer',
email: '[email protected]',
role: 'Member'
}, {
id: 2,
name: 'Courtney Henry',
title: 'Designer',
email: '[email protected]',
role: 'Admin',
disabledExpand: true
}, {
id: 3,
name: 'Tom Cook',
title: 'Director of Product',
email: '[email protected]',
role: 'Member'
}, {
id: 4,
name: 'Whitney Francis',
title: 'Copywriter',
email: '[email protected]',
role: 'Admin',
disabledExpand: true
}, {
id: 5,
name: 'Leonard Krasner',
title: 'Senior Designer',
email: '[email protected]',
role: 'Owner'
}, {
id: 6,
name: 'Floyd Miles',
title: 'Principal Designer',
email: '[email protected]',
role: 'Member',
disabledExpand: true
}]
const columns = [
{
label: 'Name',
key: 'name'
},
{
label: 'title',
key: 'title'
},
{
label: 'Email',
key: 'email'
},
{
label: 'role',
key: 'role'
}
]
const expand = ref({
openedRows: [],
row: null
})
</script>

<template>
<UTable v-model:expand="expand" :rows="people" :columns="columns">
<template #expand="{ row }">
<div class="p-4">
<pre>{{ row }}</pre>
</div>
</template>
</UTable>
</template>
65 changes: 65 additions & 0 deletions docs/components/content/examples/TableExampleExpandActionSlot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script setup lang='ts'>
const people = [{
id: 1,
name: 'Lindsay Walton',
title: 'Front-end Developer',
email: '[email protected]',
role: 'Member',
hasExpand: false
}, {
id: 2,
name: 'Courtney Henry',
title: 'Designer',
email: '[email protected]',
role: 'Admin',
hasExpand: true
}, {
id: 3,
name: 'Tom Cook',
title: 'Director of Product',
email: '[email protected]',
role: 'Member',
hasExpand: false
}, {
id: 4,
name: 'Whitney Francis',
title: 'Copywriter',
email: '[email protected]',
role: 'Admin',
hasExpand: true
}, {
id: 5,
name: 'Leonard Krasner',
title: 'Senior Designer',
email: '[email protected]',
role: 'Owner',
hasExpand: false
}, {
id: 6,
name: 'Floyd Miles',
title: 'Principal Designer',
email: '[email protected]',
role: 'Member',
hasExpand: true
}]
const expand = ref({
openedRows: [people.find(v => v.hasExpand)],
row: {}
})
</script>

<template>
<UTable v-model:expand="expand" :rows="people">
<template #expand="{ row }">
<div class="p-4">
<pre>{{ row }}</pre>
</div>
</template>
<template #expand-action="{ row, isExpanded, toggle }">
<UButton v-if="row.hasExpand" @click="toggle">
{{ isExpanded ? 'collapse' : 'expand' }}
</UButton>
</template>
</UTable>
</template>
9 changes: 7 additions & 2 deletions docs/components/content/examples/TableExampleExpandable.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<script setup>
<script setup lang='ts'>
const people = [{
id: 1,
name: 'Lindsay Walton',
Expand Down Expand Up @@ -36,10 +36,15 @@ const people = [{
email: '[email protected]',
role: 'Member'
}]
const expand = ref({
openedRows: [people[0]],
row: {}
})
</script>

<template>
<UTable :rows="people">
<UTable v-model:expand="expand" :rows="people">
<template #expand="{ row }">
<div class="p-4">
<pre>{{ row }}</pre>
Expand Down
108 changes: 107 additions & 1 deletion docs/content/2.components/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ componentProps:

### Expandable :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}

You can use the `expand` slot to display extra information about a row. You will have access to the `row` property in the slot scope.
You can use the `v-model:expand` to enables row expansion functionality in the table component. It maintains an object containing an `openedRows` an array and `row` an object, which tracks the indices of currently expanded rows.

When using the expand slot, you have access to the `row` property in the slot scope, which contains the data of the row that triggered the expand/collapse action. This allows you to customize the expanded content based on the row's data.

::component-example{class="grid"}
---
Expand All @@ -327,6 +329,73 @@ componentProps:
---
::

#### Event expand

The `@update:expand` event is emitted when a row is expanded. This event provides the current state of expanded rows and the data of the row that triggered the event.

To use the `@update:expand` event, add it to your `UTable` component. The event handler will receive an object with the following properties:
- `openedRows`: An array of indices of the currently expanded rows.
- `row`: The row data that triggered the expand/collapse action.

```vue
<script setup lang="ts">
const { data, pending } = await useLazyFetch(() => `/api/users`)
const handleExpand = ({ openedRows, row }) => {
console.log('opened Rows:', openedRows);
console.log('Row Data:', row);
};
const expand = ref({
openedRows: [],
row: null
})
</script>
<template>
<UTable v-model="expand" :loading="pending" :rows="data" @update:expand="handleExpand">
<template #expand="{ row }">
<div class="p-4">
<pre>{{ row }}</pre>
</div>
</template>
</UTable>
</template>
```

#### Multiple expand
Controls whether multiple rows can be expanded simultaneously in the table.

```vue
<template>
<!-- Allow only one row to be expanded at a time -->
<UTable :multiple-expand="false" />
<!-- Default behavior: Allow multiple rows to be expanded simultaneously -->
<UTable :multiple-expand="true" />
<!-- Or simply -->
<UTable />
</template>
```

#### Disable Row Expansion

You can disable the expansion functionality for specific rows in the UTable component by adding the `disabledExpand` property to your row data.

> Important: When using `disabledExpand`, you must define the `columns` prop for the UTable component. Otherwise, the table will render all properties as columns, including the `disabledExpand` property.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-disabled-expandable'
componentProps:
class: 'flex-1'
---
::

### Loading

Use the `loading` prop to indicate that data is currently loading with an indeterminate [Progress](/components/progress#indeterminate) bar.
Expand Down Expand Up @@ -449,6 +518,43 @@ componentProps:
---
::

### `expand-action`

The `#expand-action` slot allows you to customize the expansion control interface for expandable table rows. This feature provides a flexible way to implement custom expand/collapse functionality while maintaining access to essential row data and state.

#### Usage

```vue
<template>
<UTable>
<template #expand-action="{ row, toggle, isExpanded }">
<!-- Your custom expand action content -->
</template>
</UTable>
</template>
```

#### Slot Props

The slot provides three key props:

| Prop | Type | Description |
|------|------|-------------|
| `row` | `Object` | Contains the current row's data |
| `toggle` | `Function` | Function to toggle the expanded state |
| `isExpanded` | `Boolean` | Current expansion state of the row |

::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-expand-action-slot'
componentProps:
class: 'flex-1'
---
::


### `loading-state`

Use the `#loading-state` slot to customize the loading state.
Expand Down
Loading

0 comments on commit 1acd01a

Please sign in to comment.