@xy-planning-network/trees 0.3.2 → 0.4.0-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.
Files changed (82) hide show
  1. package/README.md +3 -8
  2. package/config/tailwind.config.js +4 -7
  3. package/config/theme/colors.js +3 -75
  4. package/config/theme/fontFamily.js +1 -1
  5. package/config/theme/index.js +0 -3
  6. package/dist/style.css +1 -0
  7. package/dist/trees.es.js +8399 -0
  8. package/dist/trees.umd.js +10 -0
  9. package/dist/types/api/base.d.ts +12 -0
  10. package/dist/types/entry.d.ts +8 -0
  11. package/dist/types/helpers/Uniques.d.ts +4 -0
  12. package/dist/types/lib-components/forms/BaseInput.vue.d.ts +38 -0
  13. package/dist/types/lib-components/forms/Checkbox.vue.d.ts +22 -0
  14. package/dist/types/lib-components/forms/DateRangePicker.vue.d.ts +45 -0
  15. package/dist/types/lib-components/forms/InputHelp.vue.d.ts +22 -0
  16. package/dist/types/lib-components/forms/InputLabel.vue.d.ts +22 -0
  17. package/dist/types/lib-components/forms/MultiCheckboxes.vue.d.ts +34 -0
  18. package/dist/types/lib-components/forms/Radio.vue.d.ts +44 -0
  19. package/dist/types/lib-components/forms/Select.vue.d.ts +58 -0
  20. package/dist/types/lib-components/forms/TextArea.vue.d.ts +32 -0
  21. package/dist/types/lib-components/forms/Toggle.vue.d.ts +17 -0
  22. package/dist/types/lib-components/forms/YesOrNoRadio.vue.d.ts +33 -0
  23. package/dist/types/lib-components/index.d.ts +64 -0
  24. package/dist/types/lib-components/layout/DateFilter.vue.d.ts +34 -0
  25. package/dist/types/lib-components/layout/SidebarLayout.vue.d.ts +33 -0
  26. package/dist/types/lib-components/layout/StackedLayout.vue.d.ts +40 -0
  27. package/dist/types/lib-components/lists/Cards.vue.d.ts +23 -0
  28. package/dist/types/lib-components/lists/DetailList.vue.d.ts +34 -0
  29. package/dist/types/lib-components/lists/DownloadCell.vue.d.ts +20 -0
  30. package/dist/types/lib-components/lists/StaticTable.vue.d.ts +18 -0
  31. package/dist/types/lib-components/lists/Table.vue.d.ts +29 -0
  32. package/dist/types/lib-components/navigation/ActionsDropdown.vue.d.ts +26 -0
  33. package/dist/types/lib-components/navigation/Paginator.vue.d.ts +27 -0
  34. package/dist/types/lib-components/navigation/Steps.vue.d.ts +53 -0
  35. package/dist/types/lib-components/navigation/Tabs.vue.d.ts +36 -0
  36. package/dist/types/lib-components/overlays/ContentModal.vue.d.ts +24 -0
  37. package/dist/types/lib-components/overlays/Flash.vue.d.ts +6 -0
  38. package/dist/types/lib-components/overlays/Modal.vue.d.ts +51 -0
  39. package/dist/types/lib-components/overlays/Slideover.vue.d.ts +30 -0
  40. package/dist/types/lib-components/overlays/Spinner.vue.d.ts +2 -0
  41. package/dist/types/types/nav.d.ts +7 -0
  42. package/dist/types/types/table.d.ts +32 -0
  43. package/dist/types/types/users.d.ts +9 -0
  44. package/package.json +47 -64
  45. package/src/index.css +24 -36
  46. package/src/lib-components/forms/BaseInput.vue +51 -45
  47. package/src/lib-components/forms/Checkbox.vue +31 -22
  48. package/src/lib-components/forms/DateRangePicker.vue +56 -56
  49. package/src/lib-components/forms/InputHelp.vue +12 -9
  50. package/src/lib-components/forms/InputLabel.vue +12 -9
  51. package/src/lib-components/forms/MultiCheckboxes.vue +48 -44
  52. package/src/lib-components/forms/Radio.vue +34 -24
  53. package/src/lib-components/forms/Select.vue +40 -46
  54. package/src/lib-components/forms/TextArea.vue +23 -17
  55. package/src/lib-components/forms/Toggle.vue +7 -11
  56. package/src/lib-components/forms/YesOrNoRadio.vue +31 -27
  57. package/src/lib-components/layout/DateFilter.vue +31 -30
  58. package/src/lib-components/layout/SidebarLayout.vue +36 -51
  59. package/src/lib-components/layout/StackedLayout.vue +32 -55
  60. package/src/lib-components/lists/Cards.vue +8 -12
  61. package/src/lib-components/lists/DetailList.vue +83 -83
  62. package/src/lib-components/lists/DownloadCell.vue +8 -12
  63. package/src/lib-components/lists/StaticTable.vue +30 -23
  64. package/src/lib-components/lists/Table.vue +146 -122
  65. package/src/lib-components/navigation/ActionsDropdown.vue +39 -43
  66. package/src/lib-components/navigation/Paginator.vue +65 -80
  67. package/src/lib-components/navigation/Steps.vue +38 -27
  68. package/src/lib-components/navigation/Tabs.vue +64 -60
  69. package/src/lib-components/overlays/ContentModal.vue +27 -31
  70. package/src/lib-components/overlays/Flash.vue +85 -70
  71. package/src/lib-components/overlays/Modal.vue +39 -42
  72. package/src/lib-components/overlays/Slideover.vue +30 -35
  73. package/src/lib-components/overlays/Spinner.vue +51 -51
  74. package/src/types/env.d.ts +18 -0
  75. package/src/types/global.d.ts +10 -0
  76. package/config/theme/fontSize.js +0 -16
  77. package/config/theme/fontWeight.js +0 -27
  78. package/config/theme/spacing.js +0 -3
  79. package/dist/trees.esm.js +0 -10994
  80. package/dist/trees.min.js +0 -7
  81. package/dist/trees.ssr.js +0 -11669
  82. package/trees.d.ts +0 -43
@@ -1,3 +1,147 @@
1
+ <script setup lang="ts">
2
+ import { AxiosResponse } from "axios"
3
+ import {
4
+ ComponentPublicInstance,
5
+ computed,
6
+ getCurrentInstance,
7
+ ref,
8
+ watch,
9
+ } from "vue"
10
+ import DateRangePicker from "../forms/DateRangePicker.vue"
11
+ import Paginator from "../navigation/Paginator.vue"
12
+ import BaseAPI from "../../api/base"
13
+ import * as TableTypes from "../../types/table"
14
+
15
+ const props = withDefaults(
16
+ defineProps<{
17
+ clickable?: boolean
18
+ loader?: boolean
19
+ tableData: TableTypes.Dynamic
20
+ }>(),
21
+ {
22
+ clickable: false,
23
+ loader: true,
24
+ }
25
+ )
26
+
27
+ const currentSort = ref(
28
+ props.tableData.defaultSort ? props.tableData.defaultSort : ""
29
+ )
30
+ const currentSortDirection = ref(
31
+ props.tableData.defaultSortDirection
32
+ ? props.tableData.defaultSortDirection
33
+ : "desc"
34
+ )
35
+ const dateRange = ref({
36
+ minDate: 0,
37
+ maxDate: 0,
38
+ })
39
+ const items = ref<any[]>([])
40
+ const pagination = ref({
41
+ page: 1,
42
+ perPage: 10,
43
+ totalItems: 0,
44
+ totalPages: 0,
45
+ })
46
+ const query = ref("")
47
+ const cellValue = (
48
+ item: Record<string, any>,
49
+ col: TableTypes.Column
50
+ ): string => {
51
+ if (col.key) {
52
+ // NOTE(dlk): supports dot notation for nested keys
53
+ return col.key.split(".").reduce((o, i) => o[i], item as any)
54
+ }
55
+
56
+ if (col.presenter) {
57
+ // TODO: discuss this pattern. Current usage can be replaced with modules.
58
+ // https://v3.vuejs.org/api/composition-api.html#getcurrentinstance
59
+ const internalInstance = getCurrentInstance()
60
+ return col.presenter(
61
+ item,
62
+ internalInstance?.proxy as ComponentPublicInstance
63
+ )
64
+ }
65
+
66
+ return ""
67
+ }
68
+ const dateRangeChanged = (newDateRange: {
69
+ minDate: number
70
+ maxDate: number
71
+ }): void => {
72
+ pagination.value.page = 1
73
+ dateRange.value = newDateRange
74
+ loadAndRender()
75
+ }
76
+ const handleSort = (selectedSort: string): void => {
77
+ if (currentSort.value == selectedSort) {
78
+ currentSortDirection.value =
79
+ currentSortDirection.value === "desc" ? "asc" : "desc"
80
+ } else {
81
+ currentSort.value = selectedSort
82
+ currentSortDirection.value = "desc"
83
+ }
84
+
85
+ loadAndRender()
86
+ }
87
+ const loadAndRender = (): void => {
88
+ const params = {
89
+ minDate: dateRange.value.minDate,
90
+ maxDate: dateRange.value.maxDate,
91
+ page: pagination.value.page,
92
+ perPage: pagination.value.perPage,
93
+ sort: currentSort.value,
94
+ sortDir: currentSortDirection.value,
95
+ q: query.value,
96
+ }
97
+
98
+ BaseAPI.get(props.tableData.url, { skipLoader: !props.loader }, params).then(
99
+ (success: AxiosResponse) => {
100
+ pagination.value = {
101
+ page: success.data.page,
102
+ perPage: success.data.perPage,
103
+ totalItems: success.data.totalItems,
104
+ totalPages: success.data.totalPages,
105
+ }
106
+ items.value = success.data.items
107
+ },
108
+ () => {
109
+ window.VueBus.emit(
110
+ "Flash-show-generic-error",
111
+ "membership@xyplanningnetwork.com"
112
+ )
113
+ }
114
+ )
115
+ }
116
+
117
+ const reloadTable = (): void => {
118
+ pagination.value.page = 1
119
+ loadAndRender()
120
+ }
121
+
122
+ const hasContent = computed((): boolean => {
123
+ return items.value.length ? true : false
124
+ })
125
+
126
+ watch(
127
+ () => props.tableData.refreshTrigger,
128
+ () => {
129
+ // This lets parent components trigger a refresh of the current page depending on external actions.
130
+ loadAndRender()
131
+ }
132
+ )
133
+
134
+ watch(
135
+ () => props.tableData.reloadTrigger,
136
+ () => {
137
+ // This lets parent components trigger a reload of page 1 depending on external actions.
138
+ reloadTable()
139
+ }
140
+ )
141
+
142
+ // onCreated
143
+ loadAndRender()
144
+ </script>
1
145
  <template>
2
146
  <div>
3
147
  <div
@@ -52,7 +196,7 @@
52
196
  <span v-if="!!col.display.length">{{ col.display }}</span>
53
197
  <span
54
198
  class="cursor-pointer"
55
- @click.prevent="handleSort(col.sort)"
199
+ @click.prevent="handleSort(col.sort as string)"
56
200
  v-if="col.sort"
57
201
  >
58
202
  <svg
@@ -140,128 +284,8 @@
140
284
 
141
285
  <Paginator
142
286
  v-model="pagination"
143
- @update:modelValue="loadAndRender(false)"
287
+ @update:modelValue="loadAndRender()"
144
288
  v-if="hasContent"
145
289
  />
146
290
  </div>
147
291
  </template>
148
-
149
- <script lang="ts">
150
- import { Options, Prop, Watch, Vue } from "vue-property-decorator";
151
- import { AxiosResponse } from "axios";
152
- import DateRangePicker from "../forms/DateRangePicker.vue";
153
- import Paginator from "../navigation/Paginator.vue";
154
- import BaseAPI from "../../api/base";
155
- import TableTypes from "../../types/table";
156
-
157
- @Options({ components: { DateRangePicker, Paginator }, name: "Table" })
158
- export default class Table extends Vue {
159
- @Prop({ type: Boolean, required: false, default: false }) clickable!: boolean;
160
- @Prop({ type: Boolean, required: false, default: true }) loader!: boolean;
161
- @Prop({ type: Object, required: true }) tableData!: TableTypes.Dynamic;
162
-
163
- currentSort = "";
164
- currentSortDirection = "";
165
- dateRange: { minDate: number; maxDate: number } = {
166
- minDate: 0,
167
- maxDate: 0,
168
- };
169
- items: any[] = [];
170
- pagination = {
171
- page: 1,
172
- perPage: 10,
173
- totalItems: 0,
174
- totalPages: 0,
175
- };
176
- query = "";
177
-
178
- @Watch("tableData.refreshTrigger")
179
- onRefreshTrigger(): void {
180
- // This lets parent components trigger a refresh of the current page depending on external actions.
181
- this.loadAndRender();
182
- }
183
-
184
- @Watch("tableData.reloadTrigger")
185
- onReloadTrigger(): void {
186
- // This lets parent components trigger a reload of page 1 depending on external actions.
187
- this.reloadTable();
188
- }
189
-
190
- created() {
191
- if (this.tableData.defaultSort) {
192
- this.currentSort = this.tableData.defaultSort;
193
- this.currentSortDirection = this.tableData.defaultSortDirection
194
- ? this.tableData.defaultSortDirection
195
- : "desc";
196
- }
197
-
198
- this.loadAndRender();
199
- }
200
-
201
- cellValue(item: Record<string, any>, col: TableTypes.Column): string {
202
- if (col.key) {
203
- // NOTE(dlk): supports dot notation for nested keys
204
- return col.key.split(".").reduce((o, i) => o[i], item as any);
205
- }
206
-
207
- if (col.presenter) {
208
- return col.presenter(item, this);
209
- }
210
-
211
- return "";
212
- }
213
- dateRangeChanged(dateRange: { minDate: number; maxDate: number }): void {
214
- this.pagination.page = 1;
215
- this.dateRange = dateRange;
216
- this.loadAndRender();
217
- }
218
- handleSort(selectedSort: string): void {
219
- if (this.currentSort == selectedSort) {
220
- this.currentSortDirection =
221
- this.currentSortDirection === "desc" ? "asc" : "desc";
222
- } else {
223
- this.currentSort = selectedSort;
224
- this.currentSortDirection = "desc";
225
- }
226
-
227
- this.loadAndRender();
228
- }
229
- loadAndRender(): void {
230
- const params = {
231
- minDate: this.dateRange.minDate,
232
- maxDate: this.dateRange.maxDate,
233
- page: this.pagination.page,
234
- perPage: this.pagination.perPage,
235
- sort: this.currentSort,
236
- sortDir: this.currentSortDirection,
237
- q: this.query,
238
- };
239
-
240
- BaseAPI.get(this.tableData.url, { skipLoader: !this.loader }, params).then(
241
- (success: AxiosResponse) => {
242
- this.pagination = {
243
- page: success.data.page,
244
- perPage: success.data.perPage,
245
- totalItems: success.data.totalItems,
246
- totalPages: success.data.totalPages,
247
- };
248
- this.items = success.data.items;
249
- },
250
- () => {
251
- window.VueBus.emit(
252
- "Flash-show-generic-error",
253
- "membership@xyplanningnetwork.com"
254
- );
255
- }
256
- );
257
- }
258
- reloadTable(): void {
259
- this.pagination.page = 1;
260
- this.loadAndRender();
261
- }
262
-
263
- get hasContent(): boolean {
264
- return this.items.length ? true : false;
265
- }
266
- }
267
- </script>
@@ -1,3 +1,42 @@
1
+ <script setup lang="ts">
2
+ import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue"
3
+ import { DotsVerticalIcon } from "@heroicons/vue/solid"
4
+ import { onMounted, ref } from "vue"
5
+ import * as TableTypes from "../../types/table"
6
+ import User from "../../types/users"
7
+
8
+ const props = defineProps<{
9
+ currentUser: User
10
+ items: TableTypes.MenuItem[]
11
+ propsData: any
12
+ }>()
13
+
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
+ }
24
+
25
+ onMounted(() => {
26
+ for (let item of props.items) {
27
+ if (!item.show) {
28
+ hasActionItems.value = true
29
+ return
30
+ }
31
+
32
+ const showActionItem = item.show(props.propsData, props.currentUser)
33
+ if (showActionItem) {
34
+ hasActionItems.value = true
35
+ return
36
+ }
37
+ }
38
+ })
39
+ </script>
1
40
  <template>
2
41
  <Menu as="div" class="relative flex justify-end items-center">
3
42
  <MenuButton
@@ -37,46 +76,3 @@
37
76
  </transition>
38
77
  </Menu>
39
78
  </template>
40
-
41
- <script lang="ts">
42
- import { Options, Prop, Vue } from "vue-property-decorator";
43
- import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue";
44
- import { DotsVerticalIcon } from "@heroicons/vue/solid";
45
- import TableTypes from "../../types/table";
46
- import UserTypes from "../../types/users";
47
-
48
- @Options({
49
- components: { DotsVerticalIcon, Menu, MenuButton, MenuItem, MenuItems },
50
- name: "ActionsDropdown",
51
- })
52
- export default class ActionsDropdown extends Vue {
53
- @Prop({ type: Object, required: true }) currentUser!: UserTypes.User;
54
- @Prop({ type: Array, required: true }) items!: Array<TableTypes.MenuItem>;
55
- @Prop({ type: Object, required: true }) propsData!: any;
56
-
57
- hasActionItems = false;
58
-
59
- mounted(): void {
60
- for (let item of this.items) {
61
- if (!item.show) {
62
- this.hasActionItems = true;
63
- return;
64
- }
65
-
66
- const showActionItem = item.show(this.propsData, this.currentUser);
67
- if (showActionItem) {
68
- this.hasActionItems = true;
69
- return;
70
- }
71
- }
72
- }
73
-
74
- emitEvent(event: string): void {
75
- window.VueBus.emit(event, this.propsData);
76
- }
77
- show(item: TableTypes.MenuItem): boolean {
78
- if (!item.show) return true;
79
- return item.show(this.propsData, this.currentUser);
80
- }
81
- }
82
- </script>
@@ -1,12 +1,72 @@
1
+ <script lang="ts">
2
+ // TODO: explore this further as a pattern for exporting commonly used types
3
+ export interface Pagination {
4
+ page: number
5
+ perPage: number
6
+ totalItems: number
7
+ totalPages: number
8
+ }
9
+ </script>
10
+ <script setup lang="ts">
11
+ import { computed, ref } from "vue"
12
+
13
+ const props = defineProps<{
14
+ modelValue: Pagination
15
+ }>()
16
+
17
+ const emit = defineEmits<{
18
+ (e: "update:modelValue", pagination: Pagination): void
19
+ }>()
20
+
21
+ const pagination = ref<Pagination>(props.modelValue)
22
+
23
+ const updateModelValue = () => {
24
+ emit("update:modelValue", pagination.value)
25
+ }
26
+
27
+ const changePage = (page: number): void => {
28
+ pagination.value.page = page
29
+ updateModelValue()
30
+ }
31
+
32
+ const pageShortcuts = computed((): number[] => {
33
+ const shortcuts: number[] = []
34
+
35
+ // If total pages is less than or equal to 4, just return 1, 2, 3, 4
36
+ if (pagination.value.totalPages <= 4) {
37
+ for (let i = 0; i < pagination.value.totalPages; i++) {
38
+ shortcuts.push(i + 1)
39
+ }
40
+ return shortcuts
41
+ }
42
+
43
+ // If there are more than 3 pages left, show these
44
+ // e.g. [4, 5, 6, 7] when there are 8 total pages and the current page is 4
45
+ const pagesLeft: number = pagination.value.totalPages - pagination.value.page
46
+ if (pagesLeft >= 3) {
47
+ for (let i = 0; i < 4; i++) {
48
+ shortcuts.push(pagination.value.page + i)
49
+ }
50
+ return shortcuts
51
+ }
52
+
53
+ // If there are less than 3 pages left, count backwards from the last page
54
+ // e.g. [5, 6, 7, 8] when on page 5, 6, 7, and 8 and there are 8 total pages
55
+ for (let i = 0; i < 4; i++) {
56
+ shortcuts.unshift(pagination.value.totalPages - i)
57
+ }
58
+ return shortcuts
59
+ })
60
+ </script>
1
61
  <template>
2
62
  <div class="px-4 flex items-center justify-between sm:px-0">
3
63
  <div class="w-0 flex-1 flex">
4
64
  <a
5
65
  href="#"
6
66
  class="-mt-px border-t-2 border-transparent pt-4 pr-1 inline-flex items-center text-sm leading-5 font-medium focus:outline-none focus:text-gray-700 focus:border-gray-400"
7
- @click.prevent="changePage(modelValue.page - 1)"
67
+ @click.prevent="changePage(pagination.page - 1)"
8
68
  :class="
9
- modelValue.page == 1
69
+ pagination.page == 1
10
70
  ? 'text-gray-500 cursor-not-allowed pointer-events-none'
11
71
  : 'text-gray-700 hover:text-gray-900 hover:border-gray-300'
12
72
  "
@@ -30,7 +90,7 @@
30
90
  :key="i"
31
91
  v-text="i"
32
92
  :class="
33
- modelValue.page === i
93
+ pagination.page === i
34
94
  ? 'border-blue-500 text-blue-600 focus:outline-none focus:text-blue-800 focus:border-blue-700'
35
95
  : 'border-transparent text-gray-700 hover:text-gray-900 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-400'
36
96
  "
@@ -42,9 +102,9 @@
42
102
  <a
43
103
  href="#"
44
104
  class="-mt-px border-t-2 border-transparent pt-4 pl-1 inline-flex items-center text-sm leading-5 font-medium focus:outline-none focus:text-gray-700 focus:border-gray-400"
45
- @click.prevent="changePage(modelValue.page + 1)"
105
+ @click.prevent="changePage(pagination.page + 1)"
46
106
  :class="
47
- modelValue.page >= modelValue.totalPages
107
+ pagination.page >= pagination.totalPages
48
108
  ? 'text-gray-500 cursor-not-allowed pointer-events-none'
49
109
  : 'text-gray-700 hover:text-gray-900 hover:border-gray-300'
50
110
  "
@@ -61,78 +121,3 @@
61
121
  </div>
62
122
  </div>
63
123
  </template>
64
-
65
- <script lang="ts">
66
- import { Emit, Options, Prop, Vue } from "vue-property-decorator";
67
-
68
- @Options({ name: "Paginator" })
69
- export default class Paginator extends Vue {
70
- @Prop({ type: Object, required: true }) modelValue!: {
71
- page: number;
72
- perPage: number;
73
- totalItems: number;
74
- totalPages: number;
75
- };
76
-
77
- @Emit("update:modelValue")
78
- updateModelValue(): {
79
- page: number;
80
- perPage: number;
81
- totalItems: number;
82
- totalPages: number;
83
- } {
84
- return this.modelValue;
85
- }
86
-
87
- changePage(page: number): void {
88
- this.modelValue.page = page;
89
- this.updateModelValue();
90
- }
91
- changePerPage(parent: HTMLElement, perPage: number): void {
92
- parent.blur();
93
- this.modelValue.page = 1;
94
- this.modelValue.perPage = perPage;
95
- this.updateModelValue();
96
- }
97
-
98
- get endingItem(): number {
99
- const end = this.modelValue.page * this.modelValue.perPage;
100
- return end > this.modelValue.totalItems ? this.modelValue.totalItems : end;
101
- }
102
- get pageShortcuts(): number[] {
103
- const shortcuts: number[] = [];
104
-
105
- // If total pages is less than or equal to 4, just return 1, 2, 3, 4
106
- if (this.modelValue.totalPages <= 4) {
107
- for (let i = 0; i < this.modelValue.totalPages; i++) {
108
- shortcuts.push(i + 1);
109
- }
110
- return shortcuts;
111
- }
112
-
113
- // If there are more than 3 pages left, show these
114
- // e.g. [4, 5, 6, 7] when there are 8 total pages and the current page is 4
115
- const pagesLeft: number = this.modelValue.totalPages - this.modelValue.page;
116
- if (pagesLeft >= 3) {
117
- for (let i = 0; i < 4; i++) {
118
- shortcuts.push(this.modelValue.page + i);
119
- }
120
- return shortcuts;
121
- }
122
-
123
- // If there are less than 3 pages left, count backwards from the last page
124
- // e.g. [5, 6, 7, 8] when on page 5, 6, 7, and 8 and there are 8 total pages
125
- for (let i = 0; i < 4; i++) {
126
- shortcuts.unshift(this.modelValue.totalPages - i);
127
- }
128
- return shortcuts;
129
- }
130
- get startingItem(): number {
131
- const start =
132
- this.modelValue.page * this.modelValue.perPage -
133
- this.modelValue.perPage +
134
- 1;
135
- return this.modelValue.totalItems === 0 ? 0 : start;
136
- }
137
- }
138
- </script>
@@ -1,3 +1,34 @@
1
+ <script setup lang="ts">
2
+ // TODO: think about whether there is value in updating and emiting step with next/previous
3
+ // TODO: add to docs
4
+
5
+ withDefaults(
6
+ defineProps<{
7
+ hideActions?: boolean
8
+ hidePrevious?: boolean
9
+ nextText?: string
10
+ previousText?: string
11
+ step: number
12
+ total: number
13
+ }>(),
14
+ {
15
+ hideActions: false,
16
+ hidePrevious: false,
17
+ nextText: "Next",
18
+ previousText: "Back",
19
+ }
20
+ )
21
+
22
+ const emit = defineEmits(["next", "previous"])
23
+
24
+ const next = (): void => {
25
+ emit("next")
26
+ }
27
+
28
+ const previous = (): void => {
29
+ emit("previous")
30
+ }
31
+ </script>
1
32
  <template>
2
33
  <div>
3
34
  <nav class="flex items-center justify-center space-x-8">
@@ -32,41 +63,21 @@
32
63
 
33
64
  <div class="flex flex-shrink-0" v-if="!hideActions">
34
65
  <span class="inline-flex rounded-md shadow-sm" v-if="!hidePrevious">
35
- <button type="button" class="xy-btn-white" @click="previous">
36
- Back
37
- </button>
66
+ <button
67
+ type="button"
68
+ class="xy-btn-white"
69
+ @click="previous"
70
+ v-text="previousText"
71
+ ></button>
38
72
  </span>
39
73
  <span class="ml-3 inline-flex rounded-md shadow-sm">
40
74
  <button
41
75
  type="button"
42
76
  class="xy-btn"
43
77
  @click="next"
44
- v-text="nextText ? nextText : 'Next'"
78
+ v-text="nextText"
45
79
  ></button>
46
80
  </span>
47
81
  </div>
48
82
  </div>
49
83
  </template>
50
-
51
- <script lang="ts">
52
- import { Options, Emit, Prop, Vue } from "vue-property-decorator";
53
-
54
- @Options({ name: "Steps" })
55
- export default class Steps extends Vue {
56
- @Prop({ type: Boolean, required: false }) hideActions?: boolean;
57
- @Prop({ type: Boolean, required: false }) hidePrevious?: boolean;
58
- @Prop({ type: String, required: false }) nextText?: string;
59
- @Prop({ type: Number, required: true }) step!: number;
60
- @Prop({ type: Number, required: true }) total!: number;
61
-
62
- @Emit()
63
- next(): void {
64
- return;
65
- }
66
-
67
- @Emit()
68
- previous(): void {
69
- return;
70
- }
71
- }
72
- </script>