@xy-planning-network/trees 0.6.5 → 0.6.6-rc-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xy-planning-network/trees",
3
- "version": "0.6.5",
3
+ "version": "0.6.6-rc-1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "repository": "github:xy-planning-network/trees",
@@ -48,7 +48,6 @@
48
48
  "deepmerge": "^4.3.1",
49
49
  "eslint": "^8.38.0",
50
50
  "eslint-plugin-vue": "^9.10.0",
51
- "mitt": "^2.1.0",
52
51
  "postcss": "^8.4.21",
53
52
  "prettier": "^2.8.7",
54
53
  "tailwindcss": "^3.2.1",
@@ -0,0 +1,99 @@
1
+ <script setup lang="ts">
2
+ import { useTable } from "@/composables/useTable"
3
+ import { TableActions, TableColumns, TableRowsData } from "@/composables/table"
4
+
5
+ const props = withDefaults(
6
+ defineProps<{
7
+ tableActions?: TableActions<any>
8
+ tableColumns: TableColumns<any>
9
+ tableData: TableRowsData
10
+ }>(),
11
+ {
12
+ tableActions: () => [],
13
+ }
14
+ )
15
+
16
+ const { columns, hasActions, isEmptyCellValue, rows } = useTable(
17
+ props.tableData,
18
+ props.tableColumns,
19
+ props.tableActions
20
+ )
21
+ </script>
22
+ <template>
23
+ <div class="flex flex-col">
24
+ <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
25
+ <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
26
+ <div
27
+ class="overflow-hidden border-b border-gray-200 shadow sm:rounded-lg"
28
+ >
29
+ <table class="min-w-full divide-y divide-gray-200">
30
+ <thead>
31
+ <tr>
32
+ <th
33
+ v-for="(col, idx) in columns"
34
+ :key="idx"
35
+ class="px-6 py-3 text-xs font-medium tracking-wider text-gray-900 uppercase bg-gray-50 leading-4"
36
+ :class="{
37
+ 'text-left': col.alignment === 'left',
38
+ 'text-right': col.alignment === 'right',
39
+ 'text-center': col.alignment === 'center',
40
+ }"
41
+ >
42
+ {{ col.title }}
43
+ </th>
44
+
45
+ <!--Table Actions Header-->
46
+ <th
47
+ v-if="hasActions"
48
+ class="px-6 py-3 text-xs font-medium tracking-wider text-gray-900 uppercase bg-gray-50 leading-4"
49
+ >
50
+ Actions
51
+ </th>
52
+ </tr>
53
+ </thead>
54
+ <tbody class="bg-white divide-y divide-gray-200">
55
+ <tr v-for="(row, rowIdx) in rows" :key="rowIdx">
56
+ <template v-for="(cell, cellIdx) in row.cells" :key="cellIdx">
57
+ <component
58
+ :is="'td'"
59
+ class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap leading-5"
60
+ :class="{
61
+ 'text-left': cell.alignment === 'left',
62
+ 'text-right': cell.alignment === 'right',
63
+ 'text-center': cell.alignment === 'center',
64
+ }"
65
+ >
66
+ <template v-if="cell.isComponent">
67
+ <component :is="cell.val" />
68
+ </template>
69
+
70
+ <span v-else :class="cell.classNames">
71
+ {{ isEmptyCellValue(cell.val) ? "-" : String(cell.val) }}
72
+ </span>
73
+ </component>
74
+ </template>
75
+
76
+ <!--Table Actions Cell-->
77
+ <td
78
+ v-if="hasActions"
79
+ class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap leading-5"
80
+ >
81
+ <ActionsDropdown :items="row.actions" />
82
+ </td>
83
+ </tr>
84
+
85
+ <tr v-if="rows.length === 0">
86
+ <td
87
+ :colspan="columns.length"
88
+ class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap leading-5"
89
+ >
90
+ No items were found!
91
+ </td>
92
+ </tr>
93
+ </tbody>
94
+ </table>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </template>
@@ -2,11 +2,13 @@
2
2
  import { DownloadIcon } from "@heroicons/vue/solid"
3
3
  defineProps<{
4
4
  propsData: Record<string, unknown>
5
- attribute: string
6
5
  }>()
7
6
  </script>
8
7
  <template>
9
- <a :href="propsData[attribute] as string">
10
- <DownloadIcon class="h-6 w-6 group-hover:text-gray-500 transition" />
8
+ <a href="#">
9
+ <DownloadIcon
10
+ class="h-6 w-6 group-hover:text-gray-500 transition text-right"
11
+ text-anchor="end"
12
+ />
11
13
  </a>
12
14
  </template>
@@ -1,47 +1,62 @@
1
1
  <script setup lang="ts">
2
- import {
3
- ComponentPublicInstance,
4
- computed,
5
- getCurrentInstance,
6
- ref,
7
- watch,
8
- } from "vue"
2
+ import { computed, ref, watch } from "vue"
9
3
  import DateRangePicker from "../forms/DateRangePicker.vue"
10
4
  import Paginator from "../navigation/Paginator.vue"
11
5
  import BaseAPI from "../../api/base"
12
- import * as TableTypes from "@/composables/table"
6
+ import {
7
+ DynamicTableAPI,
8
+ DynamicTableOptions,
9
+ TableActions,
10
+ TableColumns,
11
+ } from "@/composables/table"
13
12
  import { useAppFlasher } from "@/composables/useFlashes"
14
13
  import { TrailsRespPaged } from "@/api/client"
14
+ import { useTable } from "@/composables/useTable"
15
15
 
16
16
  const props = withDefaults(
17
17
  defineProps<{
18
18
  clickable?: boolean
19
19
  loader?: boolean
20
- tableData: TableTypes.Dynamic
20
+ tableActions?: TableActions<any>
21
+ tableColumns: TableColumns<any>
22
+ tableOptions: DynamicTableOptions
21
23
  }>(),
22
24
  {
23
25
  clickable: false,
24
26
  loader: true,
27
+ tableActions: () => [],
25
28
  }
26
29
  )
27
30
 
28
31
  defineEmits<{
29
- (e: "handleClick", v: any): void
32
+ (
33
+ e: "click:row",
34
+ v: (typeof tableData.value)[number],
35
+ c: typeof publicMethods
36
+ ): void
30
37
  }>()
31
38
 
39
+ const tableData = ref<Record<string, any>[]>([])
40
+
41
+ const { columns, hasActions, isEmptyCellValue, rows } = useTable(
42
+ tableData,
43
+ props.tableColumns,
44
+ props.tableActions
45
+ )
46
+
32
47
  const currentSort = ref(
33
- props.tableData.defaultSort ? props.tableData.defaultSort : ""
48
+ props.tableOptions.defaultSort ? props.tableOptions.defaultSort : ""
34
49
  )
35
50
  const currentSortDirection = ref(
36
- props.tableData.defaultSortDirection
37
- ? props.tableData.defaultSortDirection
51
+ props.tableOptions.defaultSortDirection
52
+ ? props.tableOptions.defaultSortDirection
38
53
  : "desc"
39
54
  )
40
55
  const dateRange = ref({
41
56
  minDate: 0,
42
57
  maxDate: 0,
43
58
  })
44
- const items = ref<any[]>([])
59
+
45
60
  const pagination = ref({
46
61
  page: 1,
47
62
  perPage: 10,
@@ -49,27 +64,7 @@ const pagination = ref({
49
64
  totalPages: 0,
50
65
  })
51
66
  const query = ref("")
52
- const cellValue = (
53
- item: Record<string, any>,
54
- col: TableTypes.Column
55
- ): string => {
56
- if (col.key) {
57
- // NOTE(dlk): supports dot notation for nested keys
58
- return col.key.split(".").reduce((o, i) => o[i], item as any)
59
- }
60
-
61
- if (col.presenter) {
62
- // TODO: discuss this pattern. Current usage can be replaced with modules.
63
- // https://v3.vuejs.org/api/composition-api.html#getcurrentinstance
64
- const internalInstance = getCurrentInstance()
65
- return col.presenter(
66
- item,
67
- internalInstance?.proxy as ComponentPublicInstance
68
- )
69
- }
70
67
 
71
- return ""
72
- }
73
68
  const dateRangeChanged = (newDateRange: {
74
69
  minDate: number
75
70
  maxDate: number
@@ -101,7 +96,7 @@ const loadAndRender = (): void => {
101
96
  }
102
97
 
103
98
  BaseAPI.get<TrailsRespPaged<unknown>>(
104
- props.tableData.url,
99
+ props.tableOptions.url,
105
100
  { skipLoader: !props.loader },
106
101
  params
107
102
  ).then(
@@ -112,7 +107,7 @@ const loadAndRender = (): void => {
112
107
  totalItems: success.data.totalItems,
113
108
  totalPages: success.data.totalPages,
114
109
  }
115
- items.value = success.data.items
110
+ tableData.value = success.data.items as Record<string, any>[]
116
111
  },
117
112
  () => {
118
113
  useAppFlasher.genericError()
@@ -126,11 +121,11 @@ const reloadTable = (): void => {
126
121
  }
127
122
 
128
123
  const hasContent = computed((): boolean => {
129
- return items.value.length ? true : false
124
+ return rows.value.length ? true : false
130
125
  })
131
126
 
132
127
  watch(
133
- () => props.tableData.refreshTrigger,
128
+ () => props.tableOptions.refreshTrigger,
134
129
  () => {
135
130
  // This lets parent components trigger a refresh of the current page depending on external actions.
136
131
  loadAndRender()
@@ -138,13 +133,20 @@ watch(
138
133
  )
139
134
 
140
135
  watch(
141
- () => props.tableData.reloadTrigger,
136
+ () => props.tableOptions.reloadTrigger,
142
137
  () => {
143
138
  // This lets parent components trigger a reload of page 1 depending on external actions.
144
139
  reloadTable()
145
140
  }
146
141
  )
147
142
 
143
+ const publicMethods: DynamicTableAPI = {
144
+ refresh: loadAndRender,
145
+ reset: reloadTable,
146
+ }
147
+
148
+ defineExpose(publicMethods)
149
+
148
150
  // onCreated
149
151
  loadAndRender()
150
152
  </script>
@@ -153,7 +155,7 @@ loadAndRender()
153
155
  <div
154
156
  class="flex flex-col mb-4 space-y-4 lg:space-y-0 lg:flex-row lg:justify-between"
155
157
  >
156
- <div v-if="tableData.search" class="w-full max-w-lg lg:max-w-xs">
158
+ <div v-if="tableOptions.search" class="w-full max-w-lg lg:max-w-xs">
157
159
  <label for="search" class="sr-only">Search</label>
158
160
  <div class="relative">
159
161
  <div
@@ -180,7 +182,7 @@ loadAndRender()
180
182
  />
181
183
  </div>
182
184
  </div>
183
- <div v-if="tableData.dateSearch" class="w-full max-w-lg lg:max-w-xs">
185
+ <div v-if="tableOptions.dateSearch" class="w-full max-w-lg lg:max-w-xs">
184
186
  <DateRangePicker
185
187
  v-model="dateRange"
186
188
  @update:model-value="dateRangeChanged"
@@ -195,11 +197,16 @@ loadAndRender()
195
197
  <thead>
196
198
  <tr>
197
199
  <th
198
- v-for="(col, idx) in tableData.columns"
200
+ v-for="(col, idx) in columns"
199
201
  :key="idx"
200
- class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-900 uppercase border-b border-gray-200 bg-gray-50 leading-4"
202
+ class="px-6 py-3 text-xs font-medium tracking-wider text-gray-900 uppercase border-b border-gray-200 bg-gray-50 leading-4"
203
+ :class="{
204
+ 'text-left': col.alignment === 'left',
205
+ 'text-right': col.alignment === 'right',
206
+ 'text-center': col.alignment === 'center',
207
+ }"
201
208
  >
202
- <span v-if="!!col.display.length">{{ col.display }}</span>
209
+ <span v-if="col.title">{{ col.title }}</span>
203
210
  <span
204
211
  v-if="col.sort"
205
212
  class="cursor-pointer"
@@ -248,37 +255,56 @@ loadAndRender()
248
255
  </svg>
249
256
  </span>
250
257
  </th>
258
+
259
+ <!--Table Actions Header-->
260
+ <th
261
+ v-if="hasActions"
262
+ class="px-6 py-3 text-xs font-medium tracking-wider text-gray-900 uppercase bg-gray-50 leading-4"
263
+ >
264
+ Actions
265
+ </th>
251
266
  </tr>
252
267
  </thead>
253
268
 
254
269
  <tbody class="bg-white">
255
270
  <tr
256
- v-for="(item, rowIdx) in items"
257
- :key="item.id ? item.id : rowIdx"
271
+ v-for="(row, rowIdx) in rows"
272
+ :key="rowIdx"
258
273
  :class="{ 'cursor-pointer': clickable }"
259
- @click="$emit('handleClick', item)"
274
+ @click="$emit('click:row', row.rowData, publicMethods)"
260
275
  >
276
+ <template v-for="(cell, cellIdx) in row.cells" :key="cellIdx">
277
+ <component
278
+ :is="'td'"
279
+ class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap leading-5"
280
+ :class="{
281
+ 'text-left': cell.alignment === 'left',
282
+ 'text-right': cell.alignment === 'right',
283
+ 'text-center': cell.alignment === 'center',
284
+ }"
285
+ >
286
+ <template v-if="cell.isComponent">
287
+ <component :is="cell.val" />
288
+ </template>
289
+
290
+ <span v-else :class="cell.classNames">
291
+ {{ isEmptyCellValue(cell.val) ? "-" : String(cell.val) }}
292
+ </span>
293
+ </component>
294
+ </template>
295
+
296
+ <!--Table Actions Cell-->
261
297
  <td
262
- v-for="(col, colIdx) in tableData.columns"
263
- :key="rowIdx + '-' + colIdx"
264
- class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap border-b border-gray-200 leading-5"
265
- :class="col.class"
298
+ v-if="hasActions"
299
+ class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap leading-5"
266
300
  >
267
- <component
268
- :is="col.component"
269
- v-if="col.component"
270
- :props-data="item"
271
- :current-user="tableData.currentUser"
272
- :attribute="col.key"
273
- :items="col.items"
274
- ></component>
275
- <div v-else v-text="cellValue(item, col)"></div>
301
+ <ActionsDropdown :items="row.actions" />
276
302
  </td>
277
303
  </tr>
278
304
 
279
305
  <tr v-if="!hasContent">
280
306
  <td
281
- :colspan="tableData.columns.length"
307
+ :colspan="rows.length"
282
308
  class="px-6 py-4 text-sm text-gray-700 whitespace-nowrap border-b border-gray-200 leading-5"
283
309
  >
284
310
  No items were found!
@@ -1,47 +1,36 @@
1
1
  <script setup lang="ts">
2
2
  import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue"
3
3
  import { DotsVerticalIcon } from "@heroicons/vue/solid"
4
- import { onMounted, ref } from "vue"
5
- import * as TableTypes from "@/composables/table"
6
- import User from "@/composables/user"
4
+ import { computed, isRef } from "vue"
5
+ import type { ActionMenuItem } from "@/composables/nav"
7
6
 
8
7
  const props = defineProps<{
9
- currentUser: User
10
- items: TableTypes.MenuItem[]
11
- propsData: any
8
+ items: ActionMenuItem[]
12
9
  }>()
13
10
 
14
- const hasActionItems = ref(false)
15
-
16
- const emitEvent = (event: string): void => {
17
- window.VueBus.emit(event, props.propsData)
18
- }
19
-
20
- const show = (item: TableTypes.MenuItem): boolean => {
21
- if (!item.show) return true
22
- return item.show(props.propsData, props.currentUser)
23
- }
11
+ const menuItems = computed(() => {
12
+ return props.items.filter((item) => {
13
+ if (item.show === undefined) {
14
+ return true
15
+ }
24
16
 
25
- onMounted(() => {
26
- for (let item of props.items) {
27
- if (!item.show) {
28
- hasActionItems.value = true
29
- return
17
+ if (isRef<boolean>(item.show)) {
18
+ return item.show.value
30
19
  }
31
20
 
32
- const showActionItem = item.show(props.propsData, props.currentUser)
33
- if (showActionItem) {
34
- hasActionItems.value = true
35
- return
21
+ if (typeof item.show === "boolean") {
22
+ return item.show
36
23
  }
37
- }
24
+
25
+ return item.show()
26
+ })
38
27
  })
39
28
  </script>
40
29
  <template>
41
30
  <Menu as="div" class="relative flex justify-end items-center">
42
31
  <MenuButton
43
32
  class="w-8 h-8 bg-white inline-flex items-center justify-center text-gray-700 rounded-full hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
44
- :disabled="!hasActionItems"
33
+ :disabled="menuItems.length === 0"
45
34
  >
46
35
  <span class="sr-only">Open options</span>
47
36
  <DotsVerticalIcon class="w-5 h-5" aria-hidden="true" />
@@ -58,17 +47,18 @@ onMounted(() => {
58
47
  class="z-10 mx-3 origin-top-right absolute right-7 top-0 w-48 mt-1 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-200 focus:outline-none"
59
48
  >
60
49
  <div class="py-1">
61
- <template v-for="(item, idx) in items" :key="idx">
62
- <MenuItem v-if="show(item)" v-slot="{ active }" as="div">
50
+ <template v-for="(item, idx) in menuItems" :key="idx">
51
+ <MenuItem v-slot="{ active }: { active: boolean }" as="div">
63
52
  <button
64
53
  type="submit"
65
54
  :class="[
66
55
  active ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
67
56
  'block w-full text-left px-4 py-2 text-sm font-semibold',
68
57
  ]"
69
- @click="emitEvent(item.event)"
70
- v-text="item.label"
71
- ></button>
58
+ @click="item.callback"
59
+ >
60
+ {{ item.label }}
61
+ </button>
72
62
  </MenuItem>
73
63
  </template>
74
64
  </div>
@@ -1,3 +1,5 @@
1
+ import { ComputedRef } from "vue";
2
+ import { Ref } from "vue";
1
3
  import { Component, RenderFunction } from "vue";
2
4
  export interface Item {
3
5
  icon?: Component | RenderFunction;
@@ -11,3 +13,13 @@ export interface Pagination {
11
13
  totalItems: number;
12
14
  totalPages: number;
13
15
  }
16
+ export interface ActionMenuItem {
17
+ label: string;
18
+ callback: (...args: any[]) => void;
19
+ show?: ((...args: any[]) => boolean) | Ref<boolean> | ComputedRef<boolean> | boolean;
20
+ }
21
+ export interface ActionMenuEmit {
22
+ id: string;
23
+ label: string;
24
+ show?: ((...args: any[]) => boolean) | Ref<boolean> | ComputedRef<boolean> | boolean;
25
+ }
@@ -1,17 +1,6 @@
1
- import { Component, ComponentPublicInstance } from "vue";
2
- import User from "../composables/user";
3
- export interface Column {
4
- display: string;
5
- class?: string;
6
- key?: string;
7
- presenter?(row: any, instance: ComponentPublicInstance): any;
8
- component?: Component;
9
- items?: Array<MenuItem>;
10
- sort?: string;
11
- }
12
- export interface Dynamic {
13
- currentUser: User;
14
- columns: Array<Column>;
1
+ import { ComputedRef, Ref, VNodeChild } from "vue";
2
+ import { ActionMenuItem } from "../composables/nav";
3
+ export interface DynamicTableOptions {
15
4
  dateSearch?: boolean;
16
5
  defaultSort?: string;
17
6
  defaultSortDirection?: string;
@@ -20,13 +9,54 @@ export interface Dynamic {
20
9
  search?: boolean;
21
10
  url: string;
22
11
  }
23
- export interface MenuItem {
24
- label: string;
25
- event: string;
26
- show?(propsData: any, currentUser: User): boolean;
12
+ export interface DynamicTableAPI {
13
+ /**
14
+ * Force refresh the table data with the current api params state
15
+ * @returns void
16
+ */
17
+ refresh: () => void;
18
+ /**
19
+ * Reset the table data back to page 1 and load
20
+ * @returns void
21
+ */
22
+ reset: () => void;
27
23
  }
28
- export interface Static {
29
- currentUser: User;
30
- columns: Array<Column>;
31
- items: Record<string, unknown>[];
24
+ export interface TableActionItem<T = TableRowData> extends ActionMenuItem {
25
+ callback: (rowData: T, rowIndex: number) => void;
26
+ show?: ((rowData: T, rowIndex: number) => boolean) | Ref<boolean> | ComputedRef<boolean> | boolean;
27
+ }
28
+ export interface TableColumn<T = TableRowData> {
29
+ actions?: TableActions<T>;
30
+ /**
31
+ * The alignment the table cell should have
32
+ */
33
+ alignment?: TableCellAlignment;
34
+ /**
35
+ * Class names to wrap your column data in
36
+ * This field is ignored when a render method is defined
37
+ */
38
+ classNames?: string;
39
+ /**
40
+ * The text to display as the column header
41
+ */
42
+ title: string;
43
+ /**
44
+ * The property key your column data maps to
45
+ */
46
+ key: keyof T;
47
+ /**
48
+ * A render method for formatting the output of your columns data
49
+ * This may include returning a custom component using the vue h method
50
+ */
51
+ render?: (rowData: T, rowIndex: number) => string | number | boolean | VNodeChild;
52
+ /**
53
+ * A sorting identifier
54
+ * Only used on DynamicTable
55
+ */
56
+ sort?: string;
32
57
  }
58
+ export type TableActions<T = TableRowData> = TableActionItem<T>[];
59
+ export type TableCellAlignment = "left" | "center" | "right";
60
+ export type TableRowData = Record<string, any>;
61
+ export type TableColumns<T = TableRowData> = TableColumn<T>[];
62
+ export type TableRowsData = TableRowData[];
@@ -1,4 +1,9 @@
1
1
  import { Ref } from "vue";
2
+ declare global {
3
+ interface Window {
4
+ Flashes: FlashMessage[];
5
+ }
6
+ }
2
7
  /**
3
8
  * FlashMessage represents the shape of an on screen notification
4
9
  * to a user.
@@ -0,0 +1,42 @@
1
+ import { Ref } from "vue";
2
+ import { TableColumns, TableRowsData, TableActions } from "./table";
3
+ export declare const useTable: (rowData: TableRowsData | Ref<TableRowsData>, cols: TableColumns, acts: TableActions) => {
4
+ columns: import("vue").ComputedRef<{
5
+ alignment: import("./table").TableCellAlignment;
6
+ actions?: {
7
+ callback: (rowData: import("./table").TableRowData, rowIndex: number) => void;
8
+ show?: boolean | ((rowData: import("./table").TableRowData, rowIndex: number) => boolean) | undefined;
9
+ label: string;
10
+ }[] | undefined;
11
+ classNames?: string | undefined;
12
+ title: string;
13
+ key: string;
14
+ render?: ((rowData: import("./table").TableRowData, rowIndex: number) => import("vue").VNodeChild) | undefined;
15
+ sort?: string | undefined;
16
+ }[]>;
17
+ hasActions: import("vue").ComputedRef<boolean>;
18
+ isEmptyCellValue: (v: unknown) => boolean;
19
+ rows: import("vue").ComputedRef<{
20
+ actions: {
21
+ callback: () => void;
22
+ show: boolean | undefined;
23
+ label: string;
24
+ }[];
25
+ rowData: import("./table").TableRowData;
26
+ cells: {
27
+ isComponent: boolean;
28
+ val: any;
29
+ alignment: import("./table").TableCellAlignment;
30
+ actions?: {
31
+ callback: (rowData: import("./table").TableRowData, rowIndex: number) => void;
32
+ show?: boolean | ((rowData: import("./table").TableRowData, rowIndex: number) => boolean) | undefined;
33
+ label: string;
34
+ }[] | undefined;
35
+ classNames?: string | undefined;
36
+ title: string;
37
+ key: string;
38
+ render?: ((rowData: import("./table").TableRowData, rowIndex: number) => import("vue").VNodeChild) | undefined;
39
+ sort?: string | undefined;
40
+ }[];
41
+ }[]>;
42
+ };