@xy-planning-network/trees 0.13.5 → 0.13.7-dev-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/dist/trees.es.js +3021 -2928
- package/dist/trees.umd.js +14 -14
- package/package.json +1 -1
- package/src/lib-components/lists/DataTable.vue +4 -6
- package/src/lib-components/lists/DynamicTable.vue +12 -8
- package/src/lib-components/navigation/ActionsButtonGroup.vue +96 -0
- package/src/lib-components/navigation/ActionsDropdown.vue +96 -21
- package/types/composables/nav.d.ts +21 -4
- package/types/composables/table.d.ts +55 -28
- package/types/composables/useTable.d.ts +15 -3
- package/types/entry.d.ts +3 -0
- package/types/lib-components/forms/RadioCards.vue.d.ts +1 -1
- package/types/lib-components/index.d.ts +3 -1
- package/types/lib-components/navigation/ActionsButtonGroup.vue.d.ts +8 -0
- package/types/lib-components/navigation/ActionsDropdown.vue.d.ts +7 -6
- package/types/lib-components/overlays/Modal.vue.d.ts +1 -1
- package/src/lib-components/lists/TableActionButtons.vue +0 -47
package/package.json
CHANGED
|
@@ -5,8 +5,7 @@ import type {
|
|
|
5
5
|
TableColumns,
|
|
6
6
|
TableRowsData,
|
|
7
7
|
} from "@/composables/table"
|
|
8
|
-
import { ActionsDropdown } from "@/lib-components"
|
|
9
|
-
import TableActionButtons from "./TableActionButtons.vue"
|
|
8
|
+
import { ActionsButtonGroup, ActionsDropdown } from "@/lib-components"
|
|
10
9
|
import { toRef } from "vue"
|
|
11
10
|
|
|
12
11
|
const props = withDefaults(
|
|
@@ -77,15 +76,14 @@ const { columns, hasActions, isEmptyCellValue, rows } = useTable(
|
|
|
77
76
|
<!--Table Actions Cell-->
|
|
78
77
|
<td
|
|
79
78
|
v-if="hasActions"
|
|
80
|
-
class="px-6 py-2 text-sm text-gray-700 whitespace-nowrap leading-5"
|
|
79
|
+
class="px-6 py-2 text-sm text-gray-700 whitespace-nowrap leading-5 w-0"
|
|
81
80
|
>
|
|
82
81
|
<ActionsDropdown
|
|
83
82
|
v-if="tableActions.type === 'dropdown'"
|
|
84
83
|
:actions="row.actions"
|
|
85
84
|
/>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</template>
|
|
85
|
+
|
|
86
|
+
<ActionsButtonGroup v-else :actions="row.actions" />
|
|
89
87
|
</td>
|
|
90
88
|
</tr>
|
|
91
89
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, toRef, watch } from "vue"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ActionsButtonGroup,
|
|
5
|
+
ActionsDropdown,
|
|
6
|
+
TablePaginator,
|
|
7
|
+
} from "@/lib-components"
|
|
4
8
|
import DateRangePicker from "../forms/DateRangePicker.vue"
|
|
5
9
|
import BaseAPI from "../../api/base"
|
|
6
10
|
import type {
|
|
@@ -15,7 +19,6 @@ import { useAppFlasher } from "@/composables/useFlashes"
|
|
|
15
19
|
import { TrailsRespPaged } from "@/api/client"
|
|
16
20
|
import { DateRange, DateRangeProps } from "@/composables/date"
|
|
17
21
|
import { useTable } from "@/composables/useTable"
|
|
18
|
-
import TableActionButtons from "./TableActionButtons.vue"
|
|
19
22
|
|
|
20
23
|
const props = withDefaults(
|
|
21
24
|
defineProps<{
|
|
@@ -168,11 +171,12 @@ const bulkActions = computed(() => {
|
|
|
168
171
|
return {
|
|
169
172
|
...action,
|
|
170
173
|
disabled: selected.value.length === 0 || action.disabled,
|
|
171
|
-
onClick: () =>
|
|
174
|
+
onClick: (e?: Event) =>
|
|
172
175
|
action.onClick.apply(undefined, [
|
|
173
176
|
selected.value,
|
|
174
177
|
selectedData.value,
|
|
175
178
|
publicMethods,
|
|
179
|
+
e,
|
|
176
180
|
]),
|
|
177
181
|
}
|
|
178
182
|
})
|
|
@@ -264,6 +268,7 @@ loadAndRender()
|
|
|
264
268
|
<template>
|
|
265
269
|
<div>
|
|
266
270
|
<div
|
|
271
|
+
v-if="tableOptions.search || tableOptions.dateSearch"
|
|
267
272
|
class="flex flex-col mb-4 space-y-4 lg:space-y-0 lg:flex-row lg:justify-between"
|
|
268
273
|
>
|
|
269
274
|
<div v-if="tableOptions.search" class="w-full max-w-lg lg:max-w-xs">
|
|
@@ -423,7 +428,7 @@ loadAndRender()
|
|
|
423
428
|
<span class="font-medium">{{ selectable.length }}</span>
|
|
424
429
|
</div>
|
|
425
430
|
|
|
426
|
-
<
|
|
431
|
+
<ActionsButtonGroup :actions="bulkActions" />
|
|
427
432
|
</div>
|
|
428
433
|
</td>
|
|
429
434
|
</tr>
|
|
@@ -470,15 +475,14 @@ loadAndRender()
|
|
|
470
475
|
<!--Table Actions Cell-->
|
|
471
476
|
<td
|
|
472
477
|
v-if="hasActions"
|
|
473
|
-
class="px-6 py-2 text-sm text-gray-700 whitespace-nowrap leading-5"
|
|
478
|
+
class="px-6 py-2 text-sm text-gray-700 whitespace-nowrap leading-5 w-0"
|
|
474
479
|
>
|
|
475
480
|
<ActionsDropdown
|
|
476
481
|
v-if="tableActions.type === 'dropdown'"
|
|
477
482
|
:actions="row.actions"
|
|
478
483
|
/>
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
</template>
|
|
484
|
+
|
|
485
|
+
<ActionsButtonGroup v-else :actions="row.actions" />
|
|
482
486
|
</td>
|
|
483
487
|
</tr>
|
|
484
488
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ActionItems, isActionItemButton } from "@/composables/nav"
|
|
3
|
+
import { computed } from "vue"
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
actions?: ActionItems
|
|
8
|
+
}>(),
|
|
9
|
+
{
|
|
10
|
+
actions: () => [],
|
|
11
|
+
}
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
const actionItems = computed(() => {
|
|
15
|
+
return props.actions
|
|
16
|
+
.filter((a) => a.show !== false)
|
|
17
|
+
.map((a) => {
|
|
18
|
+
return {
|
|
19
|
+
...a,
|
|
20
|
+
disabled: a.disabled ?? false,
|
|
21
|
+
kind: isActionItemButton(a) ? "button" : "link",
|
|
22
|
+
show: true,
|
|
23
|
+
onClick: a.onClick ? a.onClick : () => {},
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const hasActions = computed(() => actionItems.value.length > 0)
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<div v-if="hasActions" class="flex items-center space-x-2">
|
|
33
|
+
<span class="isolate inline-flex rounded-md shadow-sm">
|
|
34
|
+
<template v-for="(action, actionIdx) in actionItems" :key="actionIdx">
|
|
35
|
+
<button
|
|
36
|
+
v-if="action.kind === 'button'"
|
|
37
|
+
type="button"
|
|
38
|
+
class="group relative inline-flex items-center bg-white px-3 py-2 text-sm font-semibold text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10 disabled:text-gray-400 disabled:cursor-not-allowed"
|
|
39
|
+
:class="{
|
|
40
|
+
'rounded-l-md': actionIdx === 0,
|
|
41
|
+
'-ml-px': actionIdx > 0,
|
|
42
|
+
'rounded-r-md': actionIdx === actionItems.length - 1,
|
|
43
|
+
}"
|
|
44
|
+
:disabled="action.disabled"
|
|
45
|
+
@click.stop="action.onClick"
|
|
46
|
+
>
|
|
47
|
+
<span class="relative inline-flex items-center gap-x-1.5">
|
|
48
|
+
<component
|
|
49
|
+
:is="action.icon"
|
|
50
|
+
v-if="action.icon"
|
|
51
|
+
class="-ml-0.5 h-4 w-4 group-disabled:text-gray-300"
|
|
52
|
+
:class="action.label ? 'text-gray-400' : 'text-gray-600'"
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
/>
|
|
55
|
+
{{ action.label }}
|
|
56
|
+
</span>
|
|
57
|
+
</button>
|
|
58
|
+
|
|
59
|
+
<a
|
|
60
|
+
v-else
|
|
61
|
+
:href="action.disabled ? undefined : action.url"
|
|
62
|
+
class="group relative inline-flex items-center bg-white px-3 py-2 text-sm font-semibold ring-1 ring-inset ring-gray-300 focus:z-10"
|
|
63
|
+
:class="[
|
|
64
|
+
{
|
|
65
|
+
'rounded-l-md': actionIdx === 0,
|
|
66
|
+
'-ml-px': actionIdx > 0,
|
|
67
|
+
'rounded-r-md': actionIdx === actionItems.length - 1,
|
|
68
|
+
},
|
|
69
|
+
action.disabled
|
|
70
|
+
? 'text-gray-400 cursor-not-allowed pointer-events-none'
|
|
71
|
+
: 'text-gray-700 hover:bg-gray-50',
|
|
72
|
+
]"
|
|
73
|
+
:target="action.openInTab ? '_blank' : undefined"
|
|
74
|
+
v-bind="action.attrs"
|
|
75
|
+
@click.stop="
|
|
76
|
+
action.disabled ? $event.preventDefault() : action.onClick($event)
|
|
77
|
+
"
|
|
78
|
+
>
|
|
79
|
+
<span class="relative inline-flex items-center gap-x-1.5">
|
|
80
|
+
<component
|
|
81
|
+
:is="action.icon"
|
|
82
|
+
v-if="action.icon"
|
|
83
|
+
class="-ml-0.5 h-4 w-4"
|
|
84
|
+
:class="[
|
|
85
|
+
action.label ? 'text-gray-400' : 'text-gray-600',
|
|
86
|
+
action.disabled ? 'text-gray-300' : '',
|
|
87
|
+
]"
|
|
88
|
+
aria-hidden="true"
|
|
89
|
+
/>
|
|
90
|
+
{{ action.label }}
|
|
91
|
+
</span>
|
|
92
|
+
</a>
|
|
93
|
+
</template>
|
|
94
|
+
</span>
|
|
95
|
+
</div>
|
|
96
|
+
</template>
|
|
@@ -1,44 +1,80 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue"
|
|
3
|
-
import { DotsVerticalIcon } from "@heroicons/vue/solid"
|
|
4
|
-
import type
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { useFloating, autoUpdate } from "@floating-ui/vue"
|
|
8
|
-
import type { Placement } from "@floating-ui/vue"
|
|
3
|
+
import { ChevronDownIcon, DotsVerticalIcon } from "@heroicons/vue/solid"
|
|
4
|
+
import { isActionItemButton, type ActionItems } from "@/composables/nav"
|
|
5
|
+
import { computed, useTemplateRef } from "vue"
|
|
6
|
+
import { useFloating, autoUpdate, autoPlacement } from "@floating-ui/vue"
|
|
9
7
|
|
|
10
8
|
const props = withDefaults(
|
|
11
9
|
defineProps<{
|
|
12
|
-
actions?:
|
|
13
|
-
|
|
10
|
+
actions?: ActionItems
|
|
11
|
+
hideOnEmpty?: boolean
|
|
12
|
+
label?: string
|
|
14
13
|
}>(),
|
|
15
14
|
{
|
|
16
15
|
actions: () => [],
|
|
17
|
-
|
|
16
|
+
hideOnEmpty: false,
|
|
17
|
+
label: "",
|
|
18
18
|
}
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const actionItems = computed(() => {
|
|
22
|
+
return props.actions
|
|
23
|
+
.filter((a) => a.show !== false)
|
|
24
|
+
.map((a) => {
|
|
25
|
+
return {
|
|
26
|
+
...a,
|
|
27
|
+
disabled: a.disabled ?? false,
|
|
28
|
+
kind: isActionItemButton(a) ? "button" : "link",
|
|
29
|
+
show: true,
|
|
30
|
+
onClick: a.onClick ? a.onClick : () => {},
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const hasActions = computed(() => actionItems.value.length > 0)
|
|
36
|
+
|
|
37
|
+
const show = computed(() => {
|
|
38
|
+
if (props.hideOnEmpty) {
|
|
39
|
+
return hasActions.value
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true
|
|
43
|
+
})
|
|
22
44
|
|
|
23
45
|
// NOTE(spk): explicitly typing as useTemplateRef is unable to infer the template type.
|
|
24
46
|
// https://vuejs.org/guide/typescript/composition-api.html#typing-template-refs
|
|
25
47
|
const triggerRef = useTemplateRef<InstanceType<typeof MenuButton>>("trigger")
|
|
26
48
|
const wrapperRef = useTemplateRef<HTMLElement | null>("wrapper")
|
|
27
49
|
const { floatingStyles } = useFloating(triggerRef, wrapperRef, {
|
|
28
|
-
|
|
50
|
+
middleware: [
|
|
51
|
+
autoPlacement({
|
|
52
|
+
allowedPlacements: ["bottom-end", "bottom-start"],
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
29
55
|
strategy: "fixed",
|
|
30
56
|
whileElementsMounted: autoUpdate,
|
|
31
57
|
})
|
|
32
58
|
</script>
|
|
59
|
+
|
|
33
60
|
<template>
|
|
34
|
-
<Menu as="div" class="relative flex
|
|
61
|
+
<Menu v-if="show" as="div" class="relative flex items-center">
|
|
35
62
|
<MenuButton
|
|
36
63
|
ref="trigger"
|
|
37
|
-
class="
|
|
64
|
+
:class="[
|
|
65
|
+
label
|
|
66
|
+
? 'rounded-md px-4 py-2 border border-gray-200 shadow-sm text-gray-800'
|
|
67
|
+
: 'w-8 h-8 rounded-full border border-transparent text-gray-700',
|
|
68
|
+
'inline-flex items-center justify-center text-sm font-medium hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors',
|
|
69
|
+
]"
|
|
38
70
|
:disabled="!hasActions"
|
|
39
71
|
>
|
|
40
|
-
<span class="sr-only">Open options</span>
|
|
41
|
-
<
|
|
72
|
+
<span :class="!label && 'sr-only'">{{ label || "Open options" }}</span>
|
|
73
|
+
<component
|
|
74
|
+
:is="label ? ChevronDownIcon : DotsVerticalIcon"
|
|
75
|
+
:class="[label && '-mr-1 ml-2', 'w-5 h-5']"
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
/>
|
|
42
78
|
</MenuButton>
|
|
43
79
|
<transition
|
|
44
80
|
enter-active-class="transition ease-out duration-100"
|
|
@@ -53,16 +89,28 @@ const { floatingStyles } = useFloating(triggerRef, wrapperRef, {
|
|
|
53
89
|
class="w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-200 focus:outline-none"
|
|
54
90
|
>
|
|
55
91
|
<div class="py-1">
|
|
56
|
-
<template v-for="(action, idx) in
|
|
57
|
-
<MenuItem
|
|
92
|
+
<template v-for="(action, idx) in actionItems" :key="idx">
|
|
93
|
+
<MenuItem
|
|
94
|
+
v-slot="{
|
|
95
|
+
active,
|
|
96
|
+
disabled,
|
|
97
|
+
}: {
|
|
98
|
+
active: boolean
|
|
99
|
+
disabled: boolean
|
|
100
|
+
}"
|
|
101
|
+
:disabled="action.disabled"
|
|
102
|
+
as="div"
|
|
103
|
+
>
|
|
58
104
|
<button
|
|
59
|
-
|
|
60
|
-
|
|
105
|
+
v-if="action.kind === 'button'"
|
|
106
|
+
type="button"
|
|
107
|
+
:disabled="disabled"
|
|
61
108
|
:class="[
|
|
62
109
|
active ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
|
|
63
|
-
|
|
110
|
+
disabled ? 'opacity-50 cursor-not-allowed' : '',
|
|
111
|
+
'block w-full text-left px-4 py-2 text-sm font-semibold',
|
|
64
112
|
]"
|
|
65
|
-
@click="action.onClick"
|
|
113
|
+
@click="($event) => action.onClick($event)"
|
|
66
114
|
>
|
|
67
115
|
<span class="relative inline-flex items-center gap-x-1.5">
|
|
68
116
|
<component
|
|
@@ -74,6 +122,33 @@ const { floatingStyles } = useFloating(triggerRef, wrapperRef, {
|
|
|
74
122
|
{{ action.label }}
|
|
75
123
|
</span>
|
|
76
124
|
</button>
|
|
125
|
+
|
|
126
|
+
<a
|
|
127
|
+
v-else
|
|
128
|
+
:class="[
|
|
129
|
+
active ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
|
|
130
|
+
disabled
|
|
131
|
+
? 'opacity-50 cursor-not-allowed pointer-events-none'
|
|
132
|
+
: '',
|
|
133
|
+
'block w-full text-left px-4 py-2 text-sm font-semibold',
|
|
134
|
+
]"
|
|
135
|
+
:href="disabled ? undefined : action.url"
|
|
136
|
+
:target="action.openInTab ? '_blank' : undefined"
|
|
137
|
+
v-bind="action.attrs"
|
|
138
|
+
@click="
|
|
139
|
+
disabled ? $event.preventDefault() : action.onClick($event)
|
|
140
|
+
"
|
|
141
|
+
>
|
|
142
|
+
<span class="relative inline-flex items-center gap-x-1.5">
|
|
143
|
+
<component
|
|
144
|
+
:is="action.icon"
|
|
145
|
+
v-if="action.icon"
|
|
146
|
+
class="-ml-0.5 h-4 w-4 text-gray-400"
|
|
147
|
+
aria-hidden="true"
|
|
148
|
+
/>
|
|
149
|
+
{{ action.label }}
|
|
150
|
+
</span>
|
|
151
|
+
</a>
|
|
77
152
|
</MenuItem>
|
|
78
153
|
</template>
|
|
79
154
|
</div>
|
|
@@ -11,13 +11,30 @@ export interface Pagination {
|
|
|
11
11
|
totalItems: number;
|
|
12
12
|
totalPages: number;
|
|
13
13
|
}
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
export type ActionItem = ActionItemButton | ActionItemLink;
|
|
15
|
+
export type ActionItems = ActionItem[];
|
|
16
|
+
export interface ActionItemButton {
|
|
17
|
+
label: string;
|
|
18
|
+
attrs?: never;
|
|
19
|
+
disabled?: boolean;
|
|
17
20
|
icon?: FunctionalComponent | RenderFunction;
|
|
21
|
+
openInTab?: never;
|
|
22
|
+
show?: boolean;
|
|
23
|
+
url?: never;
|
|
24
|
+
onClick: (e: Event) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const isActionItemButton: (item: ActionItem) => item is ActionItemButton;
|
|
27
|
+
export interface ActionItemLink {
|
|
18
28
|
label: string;
|
|
19
|
-
|
|
29
|
+
url: string;
|
|
30
|
+
attrs?: Record<string, string | number | boolean>;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
icon?: FunctionalComponent | RenderFunction;
|
|
33
|
+
openInTab?: boolean;
|
|
34
|
+
show?: boolean;
|
|
35
|
+
onClick?: (e: Event) => void;
|
|
20
36
|
}
|
|
37
|
+
export declare const isActionItemLink: (item: ActionItem) => item is ActionItemLink;
|
|
21
38
|
export interface UseTabHistoryOpts {
|
|
22
39
|
/**
|
|
23
40
|
* The initial value of activeTab.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { VNodeChild, type ComputedRef } from "vue";
|
|
2
|
-
import { ActionItem } from "../composables/nav";
|
|
1
|
+
import { FunctionalComponent, RenderFunction, VNodeChild, type ComputedRef } from "vue";
|
|
3
2
|
import { DateRangeProps } from "./date";
|
|
4
3
|
export interface DynamicTableOptions {
|
|
5
4
|
dateSearch?: boolean | DateRangeProps;
|
|
@@ -37,51 +36,79 @@ export interface DynamicTableAPI<T = TableRowData> {
|
|
|
37
36
|
*/
|
|
38
37
|
selectedData: ComputedRef<T[]>;
|
|
39
38
|
}
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
export type TableActionItem<T = TableRowData> = TableActionButton<T> | TableActionLink<T>;
|
|
40
|
+
/**
|
|
41
|
+
* TableActionButton determines the configuration for a action button within a table row.
|
|
42
|
+
* Visibility (`show`) and interactivity (`disabled`) can be toggled via static booleans
|
|
43
|
+
* or dynamic methods based on the specific row's state and index.
|
|
44
|
+
*
|
|
45
|
+
* @template T The shape of the underlying row data.
|
|
46
|
+
*/
|
|
47
|
+
export interface TableActionButton<T = TableRowData> {
|
|
48
|
+
label: string;
|
|
49
|
+
attrs?: never;
|
|
49
50
|
disabled?: boolean | ((rowData: T, rowIndex: number) => boolean);
|
|
51
|
+
icon?: FunctionalComponent | RenderFunction;
|
|
52
|
+
openInTab?: never;
|
|
53
|
+
show?: boolean | ((rowData: T, rowIndex: number) => boolean);
|
|
54
|
+
url?: never;
|
|
50
55
|
/**
|
|
51
56
|
* onClick is the callback function triggered by the button rendered in the table actions.
|
|
52
57
|
* @param rowData T
|
|
53
58
|
* @param rowIndex number
|
|
54
59
|
* @param tableAPI DynamicTableAPI
|
|
60
|
+
* @param e Event | undefined
|
|
55
61
|
* @returns void
|
|
56
62
|
*/
|
|
57
|
-
onClick: (rowData: T, rowIndex: number, tableAPI: DynamicTableAPI) => void;
|
|
58
|
-
/**
|
|
59
|
-
* The show property determines whether the action is visible.
|
|
60
|
-
*
|
|
61
|
-
* show accepts a boolean value or a function with the table row data as
|
|
62
|
-
* the first argument and the row index as the second.
|
|
63
|
-
*/
|
|
64
|
-
show?: boolean | ((rowData: T, rowIndex: number) => boolean);
|
|
63
|
+
onClick: (rowData: T, rowIndex: number, tableAPI: DynamicTableAPI, e?: Event) => void;
|
|
65
64
|
}
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* TableActionLink determines the configuration for a link button within a table row.
|
|
67
|
+
* Visibility (`show`) and interactivity (`disabled`) can be toggled via static booleans
|
|
68
|
+
* or dynamic methods based on the specific row's state and index.
|
|
69
|
+
* HTML Attributes can be defined on (`attrs`) for additional HTML anchor tag attributes
|
|
70
|
+
* that are not explicitly defined in the interface.
|
|
71
|
+
*
|
|
72
|
+
* @template T The shape of the underlying row data.
|
|
73
|
+
*/
|
|
74
|
+
export interface TableActionLink<T = TableRowData> {
|
|
75
|
+
label: string;
|
|
76
|
+
url: string;
|
|
77
|
+
attrs?: Record<string, string | number | boolean>;
|
|
78
|
+
disabled?: boolean | ((rowData: T, rowIndex: number) => boolean);
|
|
79
|
+
icon?: FunctionalComponent | RenderFunction;
|
|
80
|
+
openInTab?: boolean;
|
|
81
|
+
show?: boolean | ((rowData: T, rowIndex: number) => boolean);
|
|
67
82
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
83
|
+
* onClick is the callback function triggered by the button rendered in the table actions.
|
|
84
|
+
* @param rowData T
|
|
85
|
+
* @param rowIndex number
|
|
86
|
+
* @param tableAPI DynamicTableAPI
|
|
87
|
+
* @param e Event | undefined
|
|
88
|
+
* @returns void
|
|
70
89
|
*/
|
|
90
|
+
onClick: (rowData: T, rowIndex: number, tableAPI: DynamicTableAPI, e?: Event) => void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* TableBulkActionItem determines the configuration for a bulk action button on a table.
|
|
94
|
+
* Visibility (`show`) and interactivity (`disabled`) can be toggled via static booleans.
|
|
95
|
+
*
|
|
96
|
+
* @template T The shape of the underlying row data.
|
|
97
|
+
*/
|
|
98
|
+
export interface TableBulkActionItem<T = TableRowData> {
|
|
99
|
+
label: string;
|
|
71
100
|
disabled?: boolean;
|
|
101
|
+
icon?: FunctionalComponent | RenderFunction;
|
|
102
|
+
show?: boolean;
|
|
72
103
|
/**
|
|
73
104
|
* The callback method triggered by the action item buttons click event.
|
|
74
105
|
* @param selected the array of selected rows by the primary key `id`
|
|
75
106
|
* @param selectedData the array of selected rows as the underlying data type T
|
|
76
107
|
* @param tableAPI DynamicTableAPI
|
|
108
|
+
* @param e Event | undefined
|
|
77
109
|
* @returns void
|
|
78
110
|
*/
|
|
79
|
-
onClick: (selected: number[], selectedData: T[], tableAPI: DynamicTableAPI) => void;
|
|
80
|
-
/**
|
|
81
|
-
* Whether or not to visible show the action item in the UI. When all action items
|
|
82
|
-
* on a table a hidden with show: false, bulk selections are disabled for the table.
|
|
83
|
-
*/
|
|
84
|
-
show?: boolean;
|
|
111
|
+
onClick: (selected: number[], selectedData: T[], tableAPI: DynamicTableAPI, e?: Event) => void;
|
|
85
112
|
}
|
|
86
113
|
export interface TableActions<T = TableRowData> {
|
|
87
114
|
/**
|
|
@@ -12,13 +12,25 @@ export declare const useTable: (rowData: TableRowsData | Ref<TableRowsData>, col
|
|
|
12
12
|
hasActions: import("vue").ComputedRef<boolean>;
|
|
13
13
|
isEmptyCellValue: (v: unknown) => boolean;
|
|
14
14
|
rows: import("vue").ComputedRef<{
|
|
15
|
-
actions: {
|
|
15
|
+
actions: ({
|
|
16
16
|
disabled: boolean | undefined;
|
|
17
|
-
onClick: () => void;
|
|
17
|
+
onClick: (e?: Event) => void;
|
|
18
18
|
show: boolean | undefined;
|
|
19
|
+
label: string;
|
|
20
|
+
attrs?: undefined;
|
|
19
21
|
icon?: import("vue").RenderFunction | import("vue").FunctionalComponent<{}, {}, any, {}> | undefined;
|
|
22
|
+
openInTab?: undefined;
|
|
23
|
+
url?: undefined;
|
|
24
|
+
} | {
|
|
25
|
+
disabled: boolean | undefined;
|
|
26
|
+
onClick: (e?: Event) => void;
|
|
27
|
+
show: boolean | undefined;
|
|
20
28
|
label: string;
|
|
21
|
-
|
|
29
|
+
url: string;
|
|
30
|
+
attrs?: Record<string, string | number | boolean> | undefined;
|
|
31
|
+
icon?: import("vue").RenderFunction | import("vue").FunctionalComponent<{}, {}, any, {}> | undefined;
|
|
32
|
+
openInTab?: boolean | undefined;
|
|
33
|
+
})[];
|
|
22
34
|
rowData: import("./table").TableRowData;
|
|
23
35
|
cells: {
|
|
24
36
|
isComponent: boolean;
|
package/types/entry.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Plugin } from "vue";
|
|
|
2
2
|
import BaseAPI, { isHttpCancel, isHttpError, setBaseAPIDefaults } from "./api/base";
|
|
3
3
|
import type { HttpPromise, HttpError, QueryParams, ReqOptions, ReqPayload, TrailsPromise, TrailsPromisePaged, TrailsResp, TrailsRespPaged } from "./api/client";
|
|
4
4
|
import { emailPattern, looseToNumber, numericInputTypes, phonePattern, urlPattern, textInputTypes, useInputField } from "./composables/forms";
|
|
5
|
+
import { isActionItemButton, isActionItemLink, useTabHistory, useUrlSearchParams } from "./composables/nav";
|
|
5
6
|
import { debounce as debounceFn, debounceLeading } from "./helpers/Debounce";
|
|
6
7
|
import { throttle as throttleFn } from "./helpers/Throttle";
|
|
7
8
|
declare const install: Exclude<Plugin["install"], undefined>;
|
|
@@ -12,4 +13,6 @@ export { BaseAPI, isHttpCancel, isHttpError, setBaseAPIDefaults };
|
|
|
12
13
|
export type { HttpPromise, HttpError, QueryParams, ReqOptions, ReqPayload, TrailsPromise, TrailsPromisePaged, TrailsResp, TrailsRespPaged, };
|
|
13
14
|
export type * from "./composables/forms";
|
|
14
15
|
export { emailPattern, looseToNumber, phonePattern, urlPattern, numericInputTypes, textInputTypes, useInputField, };
|
|
16
|
+
export type * from "./composables/nav";
|
|
17
|
+
export { isActionItemButton, isActionItemLink, useTabHistory, useUrlSearchParams, };
|
|
15
18
|
export { debounceFn, debounceLeading, throttleFn };
|
|
@@ -8,6 +8,7 @@ declare const _default: <T extends InputOption>(__VLS_props: {
|
|
|
8
8
|
placeholder?: string | undefined;
|
|
9
9
|
columns?: 2 | 3 | undefined;
|
|
10
10
|
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: {
|
|
11
|
+
attrs: any;
|
|
11
12
|
slots: {
|
|
12
13
|
sublabel?(_: {
|
|
13
14
|
active: boolean;
|
|
@@ -16,7 +17,6 @@ declare const _default: <T extends InputOption>(__VLS_props: {
|
|
|
16
17
|
option: T;
|
|
17
18
|
}): any;
|
|
18
19
|
};
|
|
19
|
-
attrs: any;
|
|
20
20
|
emit: (evt: "update:modelValue", value: string | number | null | undefined) => void;
|
|
21
21
|
} | undefined, __VLS_expose?: ((exposed: import('vue').ShallowUnwrapRef<{}>) => void) | undefined, __VLS_setup?: Promise<{
|
|
22
22
|
props: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { default as ActionsButtonGroup } from "./navigation/ActionsButtonGroup.vue";
|
|
1
2
|
import { default as ActionsDropdown } from "./navigation/ActionsDropdown.vue";
|
|
2
3
|
import { default as Cards } from "./lists/Cards.vue";
|
|
3
4
|
import { default as ContentModal } from "./overlays/ContentModal.vue";
|
|
@@ -40,12 +41,13 @@ import { default as RadioCards } from "./forms/RadioCards.vue";
|
|
|
40
41
|
import { default as Select } from "./forms/Select.vue";
|
|
41
42
|
import { default as TextArea } from "./forms/TextArea.vue";
|
|
42
43
|
import { default as YesOrNoRadio } from "./forms/YesOrNoRadio.vue";
|
|
43
|
-
export { ActionsDropdown, Cards, ContentModal, DateFilter, DetailList, DownloadCell, Flash, InlineAlert, Modal, SidebarLayout, Slideover, StackedLayout, Popover, PopoverContent, PopoverPosition, // Type export
|
|
44
|
+
export { ActionsButtonGroup, ActionsDropdown, Cards, ContentModal, DateFilter, DetailList, DownloadCell, Flash, InlineAlert, Modal, SidebarLayout, Slideover, StackedLayout, Popover, PopoverContent, PopoverPosition, // Type export
|
|
44
45
|
Paginator, Spinner, DataTable, Steps, DynamicTable, Tabs, TablePaginator, Toggle, Tooltip, BaseInput, Checkbox, DateRangePicker, DateTime, InputError, InputHelp, InputLabel, FieldsetLegend, MultiCheckboxes, NumberInput, Radio, RadioCards, Select, TextArea, YesOrNoRadio, XYSpinner, ProgressCircles, ProgressCirclesLabeled, };
|
|
45
46
|
/**
|
|
46
47
|
* declare global component types for App.use(Trees)
|
|
47
48
|
*/
|
|
48
49
|
export interface TreesComponents {
|
|
50
|
+
ActionsButtonGroup: typeof ActionsButtonGroup;
|
|
49
51
|
ActionsDropdown: typeof ActionsDropdown;
|
|
50
52
|
Cards: typeof Cards;
|
|
51
53
|
ContentModal: typeof ContentModal;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionItems } from "../../composables/nav";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
actions?: ActionItems;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
6
|
+
actions: ActionItems;
|
|
7
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
export default _default;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { Placement } from "@floating-ui/vue";
|
|
1
|
+
import { type ActionItems } from "../../composables/nav";
|
|
3
2
|
type __VLS_Props = {
|
|
4
|
-
actions?:
|
|
5
|
-
|
|
3
|
+
actions?: ActionItems;
|
|
4
|
+
hideOnEmpty?: boolean;
|
|
5
|
+
label?: string;
|
|
6
6
|
};
|
|
7
7
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
label: string;
|
|
9
|
+
actions: ActionItems;
|
|
10
|
+
hideOnEmpty: boolean;
|
|
10
11
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
12
|
export default _default;
|
|
@@ -18,8 +18,8 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
18
18
|
onSubmit?: (() => any) | undefined;
|
|
19
19
|
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
|
|
20
20
|
}>, {
|
|
21
|
-
disabled: boolean;
|
|
22
21
|
title: string;
|
|
22
|
+
disabled: boolean;
|
|
23
23
|
destructive: boolean;
|
|
24
24
|
wide: boolean;
|
|
25
25
|
submitText: string;
|