Skip to content

Commit

Permalink
feat(ui): add new rowMeta prop to table to apply classes & styles
Browse files Browse the repository at this point in the history
  • Loading branch information
mesqueeb committed May 8, 2024
1 parent 3d0ef46 commit 3b3648b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
3 changes: 3 additions & 0 deletions packages/ui/src/components/MagnetarTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useElementSize } from '@vueuse/core'
import { isAnyObject, isError, isPlainObject, isNumber } from 'is-what'
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import {
MUIRowMeta,
FilterState,
FiltersState,
MUIColumn,
Expand Down Expand Up @@ -34,6 +35,7 @@ import MagnetarFiltersCodeRepresentation from './MagnetarFiltersCodeRepresentati
const props = defineProps<{
collection: CollectionInstance<any>
columns: MUIColumn<any, any>[]
rowMeta?: MUIRowMeta
pagination: MUIPagination
filters?: MUIFilter<any, any>[]
parseLabel?: MUIParseLabel
Expand Down Expand Up @@ -459,6 +461,7 @@ const debugMode = !!localStorage.getItem('DEBUG')
:row="row"
:columns="columns"
:parseLabel="parseLabel"
:rowMeta="rowMeta"
>
<template
v-for="(column, columnIndex) in columns"
Expand Down
12 changes: 5 additions & 7 deletions packages/ui/src/components/TableTd.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ const cellValueRaw = computedAsync<any>(
)
/** Any `Codable<...>` prop or handler will use this payload, so we prep it here. */
const codablePayload = computed<{ data: Record<string, any>; value: any; isExpanded: boolean }>(
() => ({
data: props.row,
value: cellValueRaw.value,
isExpanded: isExpanded.value,
})
)
const codablePayload = computed<Parameters<Codable<any, any>>[0]>(() => ({
data: props.row,
value: cellValueRaw.value,
isExpanded: isExpanded.value,
}))
/** Any type that has `Codable<...>` should be piped through this. */
function evaluateCodableProp<T>(prop: T | Codable<Record<string, any>, T>): T {
Expand Down
25 changes: 23 additions & 2 deletions packages/ui/src/components/TableTr.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { MUIColumn, MUIParseLabel, MUITableSlot } from '../types'
import { MUIColumn, MUIParseLabel, MUITableSlot, MUIRowMeta, Codable } from '../types'
import TableTd from './TableTd.vue'
import { isFunction } from 'is-what'
const props = defineProps<{
row: any
columns: MUIColumn<any, any>[]
parseLabel?: MUIParseLabel
rowMeta: MUIRowMeta | undefined
}>()
const isExpanded = ref(false)
/** Any `Codable<...>` prop or handler will use this payload, so we prep it here. */
const codablePayload = computed<Parameters<Codable<any, any>>[0]>(() => ({
data: props.row,
value: undefined,
isExpanded: isExpanded.value,
}))
/** Any type that has `Codable<...>` should be piped through this. */
function evaluateCodableProp<T>(prop: T | Codable<Record<string, any>, T>): T {
return isFunction(prop) ? prop(codablePayload.value) : prop
}
const rowAttrs = computed<{ class: string | undefined; style: string | undefined }>(() => ({
class: evaluateCodableProp(props.rowMeta?.class),
style: evaluateCodableProp(props.rowMeta?.style),
}))
const rowSlotContext = computed<MUITableSlot<any>>(() => ({
data: props.row,
isExpanded,
value: undefined,
class: rowAttrs.value.class,
style: rowAttrs.value.style,
}))
</script>

<template>
<tr>
<tr :class="rowAttrs.class" :style="rowAttrs.style">
<td
v-for="(column, columnIndex) in columns"
:key="(column.fieldPath || column.slot) + 'td' + row.id"
Expand Down
12 changes: 11 additions & 1 deletion packages/ui/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type OPaths<T> = OPathsWithOptional<T>

export type MUITableSlot<T = any> = {
data: Readonly<T>
value: Readonly<any>
value: Readonly<any> | undefined
isExpanded: Ref<boolean>
class: Readonly<string | undefined>
style: Readonly<string | undefined>
Expand All @@ -34,6 +34,16 @@ export type Codable<DataType, ReturnType> = (
}>
) => ReturnType

/**
* Gives you the ability to apply classes / styles to rows.
*
* Use {@link Codable} to write a function so you can apply it conditionally based on the row data.
*/
export type MUIRowMeta = {
class?: string | Codable<any, string | undefined>
style?: string | Codable<any, string | undefined>
}

export type MUIButton<T extends Record<string, any>, Label = string> = {
/** Executed on button click */
handler: (info: {
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/testApp/TestTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,13 @@ const magnetarTableInstance = ref<null | InstanceType<typeof MagnetarTable>>(nul
:pagination="{ fetchSize: 20, pageSize: 10 }"
:parseLabel="parseLabel"
:filterDataFn="filterDataFn"
:rowMeta="{
style: ({ data }) =>
data.isDone ? 'background-color: lightgreen; opacity: 0.5' : undefined,
}"
>
<template #nakashima="{ data, isExpanded, value }: MUITableSlot<Item>">
{{ value.slice(0, 1) + '...' }}
{{ value?.slice(0, 1) + '...' }}
<button @click="() => (isExpanded.value = !isExpanded.value)">
{{ isExpanded.value ? 'Hide Details' : 'Show Details' }}
</button>
Expand Down

0 comments on commit 3b3648b

Please sign in to comment.