Skip to content

Commit

Permalink
feat(table): add header and footer option
Browse files Browse the repository at this point in the history
  • Loading branch information
kiaking committed Jan 23, 2023
1 parent 493145c commit d49b07b
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 139 deletions.
207 changes: 96 additions & 111 deletions docs/components/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,139 +182,105 @@ const options = useTable({
})
```

## Props
## Total number of records

Here are the list of props you may pass to the component.
You may define `total` option to display the total number of records in the table.

### `:options`
```ts
import { MaybeRef } from '@vueuse/core'

The whole definition of the table. The `Table` object should be created via `useTable` composable. For the details on each options, please refer to the corresponding section of this document.
interface UseTableOptions {
total?: MaybeRef<number | null | undefined>
}
```

```ts
interface Props {
options?: Table
const options = useTable({
total: 50
})
```

## Reset filters button

Define `reset` option to show "Reset filters" button on table header. You can define `onReset` callback to listen to the click event on this button.

```ts
import { MaybeRef } from '@vueuse/core'

interface UseTableOptions {
reset?: MaybeRef<boolean | undefined>
onReset?(): void
}
```

```ts
const options = useTable({
reset: true,
onReset: () => { ... }
})
```

## Pagination

By passing in `total`, `page`, and `perPage` option, the table footer gets displayed with pagination. You can listen to "Prev" and "Next" button click callback via `onPrev` and `onNext` option. Note that if both `onPrev` or `onNext` is not defined, it will not show the "Prev" and "Next" buttons.

interface Table {
orders: string[]
columns: TableColumns
records?: Record<string, any>[] | null
total?: number | null
page?: number | null
perPage?: number | null
reset?: boolean
borderless?: boolean
loading?: boolean
```ts
import { MaybeRef } from '@vueuse/core'

interface UseTableOptions {
total?: MaybeRef<number | null | undefined>
page?: MaybeRef<number | null | undefined>
perPage?: MaybeRef<number | null | undefined>
onPrev?(): void
onNext?(): void
onReset?(): void
}
```

interface TableColumns {
[name: string]: TableColumn
}
```ts
const options = useTable({
total: 50,
page: 1,
perPage: 25,
onPrev: () => { ... },
onNext: () => { ... }
})
```

interface TableColumn {
label: string
className?: string
dropdown?: DropdownSection[]
cell?: TableCell | ((value: any, record: any) => TableCell)
}
## Table Header & Footer

type TableCell =
| TableCellText
| TableCellDay
| TableCellPill
| TableCellPills
| TableCellAvatar
| TableCellAvatars
| TableCellComponent

type TableCellType =
| 'text'
| 'day'
| 'pill'
| 'pills'
| 'avatar'
| 'avatars'
| 'component'

interface TableCellBase {
type: TableCellType
}
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.

interface TableCellText extends TableCellBase {
type: 'text'
icon?: any
value?: string | ((value: any, record: any) => string)
link?(value: any, record: any): string
color?: TableCellTextColor | ((value: any, record: any) => TableCellTextColor)
iconColor?: TableCellTextColor | ((value: any, record: any) => TableCellTextColor)
onClick?(value: any, record: any): void
}
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.

type TableCellTextColor =
| 'neutral'
| 'soft'
| 'mute'
| 'info'
| 'success'
| 'warning'
| 'danger'

interface TableCellDay extends TableCellBase {
type: 'day'
format?: string
color?: 'neutral' | 'soft' | 'mute'
}
```ts
import { MaybeRef } from '@vueuse/core'

interface TableCellPill extends TableCellBase {
type: 'pill'
value?: string | ((value: any) => string)
color?: TableCellPillColor | ((value: any) => TableCellPillColor)
interface UseTableOptions {
header?: MaybeRef<number | undefined>
footer?: MaybeRef<number | undefined>
}
```

type TableCellPillColor =
| 'neutral'
| 'mute'
| 'info'
| 'success'
| 'warning'
| 'danger'

interface TableCellPills extends TableCellBase {
type: 'pills'
pills(value: any, record: any): TableCellPillItem[]
}
```ts
const options = useTable({
header: true,
footer: true
})
```

interface TableCellPillItem {
label: string
color: TableCellPillColor
}
## Props

interface TableCellAvatar extends TableCellBase {
type: 'avatar'
image?(value: any, record: any): string | undefined
name?(value: any, record: any): string
link?(value: any, record: any): string
color?: 'neutral' | 'soft' | 'mute'
}
Here are the list of props you may pass to the component.

interface TableCellAvatars extends TableCellBase {
type: 'avatars'
avatars(value: any, record: any): TableCellAvatarsOption[]
color?: 'neutral' | 'soft' | 'mute'
}
### `:options`

interface TableCellComponent extends TableCellBase {
type: 'component'
component: Component
props?: Record<string, any>
}
The whole definition of the table. The `Table` object should be created via `useTable` composable. For the details on each options, please refer to the corresponding section of this document.

```ts
import { Table } from '@globalbrain/sefirot/composables/Table'

interface TableCellAvatarsOption {
image?: string
name?: string
interface Props {
options?: Table
}
```

Expand All @@ -337,7 +303,7 @@ Use `--table-cell-font-size` and `--table-cell-font-weight` to customize the bas
}
```

### Table padding on both sides
### Padding on both sides

You may define `--table-padding-right` and `--table-padding-left` to adjust the padding of the table. This is useful when you want to have "full width" table and increase the first and last cell item padding.

Expand All @@ -347,3 +313,22 @@ You may define `--table-padding-right` and `--table-padding-left` to adjust the
--table-padding-left: 0;
}
```

### Borders customization

You may customize table borders via `--table-border` variable. `--table-border` will set all borders styles at once. If you want to only adjust top and bottom, or left and right part of the border, use dedicated variables such as `--table-border-top`.

You may also adjust the border radius via `--table-border-radius` variable.

```css
:root {
--table-border: 1px solid var(--c-divider-2);

--table-border-top: var(--table-border);
--table-border-right: var(--table-border);
--table-border-bottom: var(--table-border);
--table-border-left: var(--table-border);

--table-border-radius: 6px;
}
```
48 changes: 38 additions & 10 deletions lib/components/STable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const {
orders,
columns,
records,
header,
footer,
total,
page,
perPage,
Expand All @@ -36,11 +38,31 @@ let bodyLock = false
const colWidths = reactive<Record<string, string>>({})
const showHeader = computed(() => {
return total?.value !== undefined
if (header?.value === true) {
return true
}
if (header?.value === false) {
return false
}
return total?.value !== undefined || !!reset?.value
})
const showFooter = computed(() => {
return !loading?.value && page?.value && total?.value
if (loading?.value) {
return false
}
if (footer?.value === true) {
return true
}
if (footer?.value === false) {
return false
}
return page?.value && perPage?.value && total?.value
})
watch(() => records?.value, () => {
Expand Down Expand Up @@ -114,6 +136,7 @@ function updateColWidth(key: string, value: string) {
:label="columns[key].label"
:class-name="columns[key].className"
:dropdown="columns[key].dropdown"
:has-header="showHeader"
@resize="(value) => updateColWidth(key, value)"
/>
</STableItem>
Expand Down Expand Up @@ -180,12 +203,13 @@ function updateColWidth(key: string, value: string) {
<style scoped lang="postcss">
.box {
position: relative;
border-top: var(--table-border);
border-right: var(--table-border);
border-bottom: var(--table-border);
border-left: var(--table-border);
border-top: var(--table-border-top, var(--table-border));
border-right: var(--table-border-right, var(--table-border));
border-bottom: var(--table-border-bottom, var(--table-border));
border-left: var(--table-border-left, var(--table-border));
border-radius: var(--table-border-radius);
width: 100%;
overflow: hidden;
.STable.borderless & {
border-right: 0;
Expand All @@ -210,7 +234,7 @@ function updateColWidth(key: string, value: string) {
position: var(--table-head-position, static);
top: var(--table-head-top, auto);
z-index: 100;
background-color: var(--bg-elv);
background-color: var(--bg-elv-2);
&::-webkit-scrollbar {
display: none;
Expand All @@ -225,14 +249,18 @@ function updateColWidth(key: string, value: string) {
.row {
display: flex;
border-bottom: 1px solid var(--c-divider-light);
border-bottom: 1px solid var(--c-divider-2);
.body &:last-child {
border-bottom: 0;
}
}
.missing {
border-radius: 0 0 6px 6px;
padding: 48px 32px;
text-align: center;
background-color: var(--c-bg-elv-up);
background-color: var(--c-bg-elv-3);
line-height: 24px;
font-size: 14px;
font-weight: 500;
Expand All @@ -242,7 +270,7 @@ function updateColWidth(key: string, value: string) {
.loading {
border-radius: 0 0 6px 6px;
padding: 64px 32px;
background-color: var(--c-bg-elv-up);
background-color: var(--c-bg-elv-3);
}
.loading-icon {
Expand Down

0 comments on commit d49b07b

Please sign in to comment.