Skip to content

Commit

Permalink
feat(table): allow adding summary row (#230) (#231)
Browse files Browse the repository at this point in the history
close #230

Co-authored-by: Kia King Ishii <kia.king.08@gmail.com>
  • Loading branch information
brc-dd and kiaking committed Mar 28, 2023
1 parent cff18f1 commit e55ec58
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 6 deletions.
28 changes: 24 additions & 4 deletions docs/components/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ const options = useTable({

## Table Header & Footer

The Table Header and Footer is the part where it shows additional information such as total number of records or pagnation. The header and footer gets displayed depending on it has any data to display or not. For example, header gets displayed when there's `total` or `reset` option is set.
The Table Header and Footer is the part where it shows additional information such as total number of records or pagination. The header and footer gets displayed depending on it has any data to display or not. For example, header gets displayed when there's `total` or `reset` option is set.

If you would like to diaplay or hide the header and footer regardless of the other options presense, set `boolean` to `header` or `footer` option.
If you would like to display or hide the header and footer regardless of the other options present, set `boolean` to `header` or `footer` option.

```ts
const options = useTable({
Expand All @@ -253,6 +253,24 @@ const options = useTable({
})
```

## Summary row

You may define `summary` option to display a summary row at the bottom of the table. It's useful to display information such as the total of each column.

```ts
const options = useTable({
orders: ['name', 'amount'],
columns: { ... },

summary: {
name: 'Total',
amount: 100
}
})
```

Each field defined at the `summary` option must match the key of the `columns` option, and the type of cell is applied as same as other records. For example, if the cell type of the `name` field is `text`, then the `name` field of the `summary` option will be displayed as `text` type.

## Props

Here are the list of props you may pass to the component.
Expand All @@ -277,14 +295,16 @@ interface Props {

You may customize the styles by overriding `--table` prefixed CSS variables.

### Global font style
### Font style

Use `--table-cell-font-size` and `--table-cell-font-weight` to customize the base font style in the table.
Use `--table-cell-font-size` and `--table-cell-font-weight` to customize the base font style in the table. Also, you can use `--table-cell-summary-font-weight` to adjust the font weight of the cell added by `summary` option.

```css
:root {
--table-cell-font-size: 14px;
--table-cell-font-weight: 400;

--table-cell-summary-font-weight: 600;
}
```

Expand Down
15 changes: 14 additions & 1 deletion lib/components/STable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {
records,
header,
footer,
summary,
total,
page,
perPage,
Expand Down Expand Up @@ -71,6 +72,12 @@ const classes = computed(() => ({
'borderless': borderless?.value
}))
const recordsWithSummary = computed(() => {
return (records?.value && summary?.value)
? [...records?.value, summary?.value]
: records?.value ?? []
})
watch(() => records?.value, () => {
headLock = true
bodyLock = true
Expand Down Expand Up @@ -160,7 +167,12 @@ function updateColWidth(key: string, value: string) {
@scroll="syncBodyScroll"
>
<div class="block">
<div v-for="(record, rIndex) in records" :key="rIndex" class="row">
<div
v-for="(record, rIndex) in recordsWithSummary"
:key="rIndex"
class="row"
:class="rIndex === records?.length && 'summary'"
>
<STableItem
v-for="key in orders"
:key="key"
Expand All @@ -170,6 +182,7 @@ function updateColWidth(key: string, value: string) {
>
<STableCell
:name="key"
:class="rIndex === records?.length && 'summary'"
:class-name="columns[key].className"
:cell="columns[key].cell"
:value="record[key]"
Expand Down
6 changes: 5 additions & 1 deletion lib/components/STableCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ const computedCell = computed<TableCell | undefined>(() =>
overflow: hidden;
.row:hover & {
background-color: var(--c-bg-elv);
background-color: var(--c-bg-elv-1);
}
.summary & {
background-color: var(--c-bg-elv-2);
}
.STableItem:first-child & {
Expand Down
4 changes: 4 additions & 0 deletions lib/components/STableCellDay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,9 @@ const _value = computed(() => {
.STableCellDay.neutral & { color: var(--c-text-1); }
.STableCellDay.soft & { color: var(--c-text-2); }
.STableCellDay.mute & { color: var(--c-text-3); }
.STableCell.summary & {
font-weight: var(--table-cell-summary-font-weight);
}
}
</style>
4 changes: 4 additions & 0 deletions lib/components/STableCellText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ const _iconColor = computed(() => {
.STableCellText.link:hover &.warning { color: var(--c-warning-darker); }
.STableCellText.link &.danger { color: var(--c-danger); }
.STableCellText.link:hover &.danger { color: var(--c-danger-dark); }
.STableCell.summary & {
font-weight: var(--table-cell-summary-font-weight);
}
}
.icon {
Expand Down
6 changes: 6 additions & 0 deletions lib/composables/Table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface Table<
records?: R[] | null
header?: boolean
footer?: boolean
summary?: TableSummary<R> | null
total?: number | null
page?: number | null
perPage?: number | null
Expand Down Expand Up @@ -138,12 +139,17 @@ export interface TableCellComponent extends TableCellBase {
props?: Record<string, any>
}

export type TableSummary<T> = {
[P in keyof T]?: T[P] | null | undefined
}

export interface UseTableOptions<O extends string, R extends Record<string, any>> {
orders: MaybeRef<O[]>
columns: MaybeRef<TableColumns<O, R>>
records?: MaybeRef<R[] | null | undefined>
header?: MaybeRef<boolean | undefined>
footer?: MaybeRef<boolean | undefined>
summary?: MaybeRef<TableSummary<R> | null | undefined>
total?: MaybeRef<number | null | undefined>
page?: MaybeRef<number | null | undefined>
perPage?: MaybeRef<number | null | undefined>
Expand Down
2 changes: 2 additions & 0 deletions lib/styles/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@

--table-cell-font-size: 14px;
--table-cell-font-weight: 400;

--table-cell-summary-font-weight: 600;
}

/**
Expand Down
26 changes: 26 additions & 0 deletions tests/components/STable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,30 @@ describe('components/STable', () => {
expect(wrapper.find('.STable .head .col-item_2 .label').text()).toBe('item_2')
expect(wrapper.find('.STable .head .col-item_3 .label').text()).toBe('item_3')
})

test('it displays summary row at bottom', () => {
const table = useTable({
orders: ['name', 'amount'],
columns: {
name: { label: 'Name' },
amount: { label: 'Amount' }
},
records: [
{ name: 'Item 1', amount: 10 },
{ name: 'Item 2', amount: 90 }
],
summary: {
name: 'Total', amount: 100
}
})

const wrapper = mount(STable, {
props: {
options: table
}
})

expect(wrapper.findAll('.summary .text')[0].text()).toBe('Total')
expect(wrapper.findAll('.summary .text')[1].text()).toBe('100')
})
})

0 comments on commit e55ec58

Please sign in to comment.