@redseed/redseed-ui-vue3 1.9.2 → 2.0.0

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 (65) hide show
  1. package/index.js +20 -111
  2. package/package.json +5 -5
  3. package/src/components/Badge/index.js +7 -0
  4. package/src/components/Button/ButtonDanger.vue +6 -12
  5. package/src/components/Button/ButtonDangerFull.vue +1 -7
  6. package/src/components/Button/ButtonDangerFullRounded.vue +1 -7
  7. package/src/components/Button/ButtonDangerRounded.vue +1 -7
  8. package/src/components/Button/ButtonPrimary.vue +6 -12
  9. package/src/components/Button/ButtonPrimaryFull.vue +1 -8
  10. package/src/components/Button/ButtonPrimaryFullRounded.vue +1 -8
  11. package/src/components/Button/ButtonPrimaryRounded.vue +1 -8
  12. package/src/components/Button/ButtonSecondary.vue +6 -12
  13. package/src/components/Button/ButtonSecondaryFull.vue +1 -8
  14. package/src/components/Button/ButtonSecondaryFullRounded.vue +1 -8
  15. package/src/components/Button/ButtonSecondaryRounded.vue +1 -8
  16. package/src/components/Button/ButtonSlot.vue +39 -98
  17. package/src/components/Button/ButtonTertiary.vue +6 -12
  18. package/src/components/Button/ButtonTertiaryFull.vue +1 -7
  19. package/src/components/Button/ButtonTertiaryFullRounded.vue +1 -7
  20. package/src/components/Button/ButtonTertiaryRounded.vue +1 -7
  21. package/src/components/Button/index.js +37 -0
  22. package/src/components/ButtonGroup/ButtonGroup.vue +2 -11
  23. package/src/components/ButtonGroup/ButtonGroupItem.vue +17 -25
  24. package/src/components/ButtonGroup/index.js +7 -0
  25. package/src/components/Card/Card.vue +21 -8
  26. package/src/components/Card/CardResource.vue +26 -0
  27. package/src/components/Card/index.js +7 -0
  28. package/src/components/DropdownMenu/DropdownMenu.vue +1 -6
  29. package/src/components/DropdownMenu/DropdownOption.vue +1 -1
  30. package/src/components/DropdownMenu/index.js +7 -0
  31. package/src/components/Form/index.js +13 -0
  32. package/src/components/FormField/FormFieldCheckbox.vue +1 -1
  33. package/src/components/FormField/FormFieldSearch.vue +1 -1
  34. package/src/components/FormField/FormFieldSelect.vue +209 -0
  35. package/src/components/FormField/FormFieldSlot.vue +8 -2
  36. package/src/components/FormField/index.js +23 -0
  37. package/src/components/Image/Image16By9.vue +7 -1
  38. package/src/components/Image/Image3By1.vue +7 -1
  39. package/src/components/Image/Image9By16.vue +7 -1
  40. package/src/components/Image/ImageCircle.vue +7 -1
  41. package/src/components/Image/index.js +13 -0
  42. package/src/components/Link/LinkPrimary.vue +19 -0
  43. package/src/components/Link/LinkSlot.vue +87 -0
  44. package/src/components/Link/index.js +7 -0
  45. package/src/components/List/List.vue +70 -0
  46. package/src/components/List/ListControl.vue +217 -0
  47. package/src/components/List/ListItem.vue +192 -0
  48. package/src/components/List/index.js +9 -0
  49. package/src/components/Logo/index.js +11 -0
  50. package/src/components/MessageBox/index.js +5 -0
  51. package/src/components/MetaInfo/MetaInfo.vue +2 -2
  52. package/src/components/MetaInfo/index.js +5 -0
  53. package/src/components/Modal/index.js +5 -0
  54. package/src/components/PageHeading/index.js +5 -0
  55. package/src/components/Pagination/Pagination.vue +275 -0
  56. package/src/components/Pagination/PaginationItem.vue +60 -0
  57. package/src/components/Pagination/PaginationItemCollapsed.vue +18 -0
  58. package/src/components/Pagination/PaginationItemNext.vue +17 -0
  59. package/src/components/Pagination/PaginationItemPrevious.vue +17 -0
  60. package/src/components/Pagination/index.js +13 -0
  61. package/src/components/Progress/index.js +5 -0
  62. package/src/components/Social/index.js +7 -0
  63. package/src/components/Sorting/Sorting.vue +79 -0
  64. package/src/components/Sorting/index.js +5 -0
  65. package/src/components/TwoColumnLayout/index.js +5 -0
@@ -0,0 +1,275 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue'
3
+ import PaginationItem from './PaginationItem.vue'
4
+ import PaginationItemCollapsed from './PaginationItemCollapsed.vue'
5
+ import PaginationItemNext from './PaginationItemNext.vue'
6
+ import PaginationItemPrevious from './PaginationItemPrevious.vue'
7
+
8
+ const props = defineProps({
9
+ totalItems: {
10
+ type: Number,
11
+ default: 1
12
+ },
13
+ perPage: {
14
+ type: Number,
15
+ default: 10
16
+ },
17
+ currentPage: {
18
+ type: Number,
19
+ default: 1
20
+ },
21
+ arrowsOnly: {
22
+ type: Boolean,
23
+ default: false
24
+ },
25
+ currentPageOnly: {
26
+ type: Boolean,
27
+ default: false
28
+ }
29
+ })
30
+
31
+ /**
32
+ * Current page
33
+ */
34
+ const current = ref(props.currentPage)
35
+
36
+ const totalPages = computed(() => {
37
+ if (props.totalItems == 0) return 1
38
+ if (props.perPage == 0) return 1
39
+
40
+ return Math.ceil(props.totalItems / props.perPage)
41
+ })
42
+
43
+ const hasOnePage = computed(() => totalPages.value == 1)
44
+
45
+ const hasMoreThanOnePage = computed(() => totalPages.value > 1)
46
+
47
+ const disabledPrevious = computed(() => {
48
+ return totalPages.value < 2
49
+ || current.value == 1
50
+ })
51
+
52
+ const disabledNext = computed(() => {
53
+ return totalPages.value < 2
54
+ || current.value == totalPages.value
55
+ })
56
+
57
+ /**
58
+ * Calculate range of pages to show
59
+ */
60
+ const range = computed(() => {
61
+ const scaleMin = 1
62
+ const scaleMax = 6
63
+ const scaleOffset = 3
64
+
65
+ // Show all pages if total pages is less than 7
66
+ if (totalPages.value <= scaleMax) return false
67
+
68
+ const startRange = [1, 2, 3, 4]
69
+
70
+ const endRange = [
71
+ totalPages.value - 3,
72
+ totalPages.value - 2,
73
+ totalPages.value - 1,
74
+ totalPages.value
75
+ ]
76
+
77
+ const middleRangeGoingPrevious = [
78
+ current.value,
79
+ current.value + 1
80
+ ]
81
+
82
+ const middleRangeGoingNext = [
83
+ current.value - 1,
84
+ current.value
85
+ ]
86
+
87
+ // if total pages is 7 and current page is 4,
88
+ // show end range when going previous
89
+ // show start range when going next
90
+ if (totalPages.value == scaleMax + 1 && current.value + scaleOffset == totalPages.value) {
91
+ if (goingPrevious.value) return endRange
92
+ if (goingNext.value) return startRange
93
+ }
94
+
95
+ // if current page with offset is greater than total pages,
96
+ // show end range
97
+ if (current.value + scaleOffset > totalPages.value) {
98
+ return endRange
99
+ }
100
+
101
+ // if current page with offset is equal to total pages,
102
+ // show end range when going previous
103
+ // show next middle range when going next
104
+ if (current.value + scaleOffset == totalPages.value) {
105
+ if (goingPrevious.value) return endRange
106
+ if (goingNext.value) return middleRangeGoingNext
107
+ }
108
+
109
+ // if current page without offset is less than scale min 1,
110
+ // show previous middle range when going previous
111
+ // show next middle range when going next
112
+ if (current.value - scaleOffset > scaleMin) {
113
+ if (goingPrevious.value) return middleRangeGoingPrevious
114
+ if (goingNext.value) return middleRangeGoingNext
115
+ }
116
+
117
+ // if current page without offset is equal to scale min 1,
118
+ // show previous middle range when going previous
119
+ // show start range when going next
120
+ if (current.value - scaleOffset == scaleMin) {
121
+ if (goingPrevious.value) return middleRangeGoingPrevious
122
+ if (goingNext.value) return startRange
123
+ }
124
+
125
+ // default to show start range
126
+ return startRange
127
+ })
128
+
129
+ const showSingleScale = computed(() => hasOnePage.value || props.currentPageOnly)
130
+
131
+ const showFullScale = computed(() => hasMoreThanOnePage.value
132
+ && !props.currentPageOnly
133
+ && !range.value
134
+ )
135
+
136
+ const showRangedScale = computed(() => hasMoreThanOnePage.value
137
+ && !props.currentPageOnly
138
+ && !!range.value
139
+ )
140
+
141
+ const showCollapsedStart = computed(() => totalPages.value > 6
142
+ && range.value
143
+ && !range.value.includes(1)
144
+ )
145
+
146
+ const showCollapsedEnd = computed(() => totalPages.value > 6
147
+ && range.value
148
+ && !range.value.includes(totalPages.value)
149
+ )
150
+
151
+ const emit = defineEmits(['change'])
152
+
153
+ const goingPrevious = ref(false)
154
+ const goingNext = ref(false)
155
+
156
+ function clickPage(page) {
157
+ if (page == current.value) return
158
+
159
+ if (page < current.value) {
160
+ goingPrevious.value = true
161
+ goingNext.value = false
162
+ }
163
+
164
+ if (page > current.value) {
165
+ goingPrevious.value = false
166
+ goingNext.value = true
167
+ }
168
+
169
+ current.value = page
170
+
171
+ emit('change', {
172
+ currentPage: current.value,
173
+ totalPages: totalPages.value,
174
+ perPage: props.perPage,
175
+ })
176
+ }
177
+ </script>
178
+ <template>
179
+ <div class="rsui-pagination">
180
+ <!-- Previous button -->
181
+ <div class="rsui-pagination__previous">
182
+ <PaginationItemPrevious
183
+ :disabled="disabledPrevious"
184
+ @click="clickPage(current - 1)"
185
+ ></PaginationItemPrevious>
186
+ </div>
187
+ <!-- Page items if not arrows only -->
188
+ <div v-if="!arrowsOnly"
189
+ class="rsui-pagination__items"
190
+ >
191
+ <!-- Single scale for current page only -->
192
+ <div v-if="showSingleScale"
193
+ class="rsui-pagination__items-group"
194
+ >
195
+ <PaginationItem freeze>
196
+ {{ current }}
197
+ </PaginationItem>
198
+ </div>
199
+ <!-- Full scale if total pages equals to scale max -->
200
+ <div v-if="showFullScale"
201
+ class="rsui-pagination__items-group"
202
+ >
203
+ <PaginationItem v-for="page in totalPages"
204
+ :key="page"
205
+ :active="page == current"
206
+ @click="clickPage(page)"
207
+ >
208
+ {{ page }}
209
+ </PaginationItem>
210
+ </div>
211
+ <!-- Ranged scale if total pages is greater than scale max -->
212
+ <div v-if="showRangedScale"
213
+ class="rsui-pagination__items-group"
214
+ >
215
+ <PaginationItem
216
+ v-if="showCollapsedStart"
217
+ :active="current == 1"
218
+ @click="clickPage(1)"
219
+ >
220
+ 1
221
+ </PaginationItem>
222
+
223
+ <PaginationItemCollapsed
224
+ v-if="showCollapsedStart"
225
+ ></PaginationItemCollapsed>
226
+
227
+ <PaginationItem v-for="page in range"
228
+ :key="page"
229
+ :active="page == current"
230
+ @click="clickPage(page)"
231
+ >
232
+ {{ page }}
233
+ </PaginationItem>
234
+
235
+ <PaginationItemCollapsed
236
+ v-if="showCollapsedEnd"
237
+ ></PaginationItemCollapsed>
238
+
239
+ <PaginationItem
240
+ v-if="showCollapsedEnd"
241
+ :active="totalPages == current"
242
+ @click="clickPage(totalPages)"
243
+ >
244
+ {{ totalPages }}
245
+ </PaginationItem>
246
+ </div>
247
+ </div>
248
+ <!-- Next button -->
249
+ <div class="rsui-pagination__next">
250
+ <PaginationItemNext
251
+ :disabled="disabledNext"
252
+ @click="clickPage(current + 1)"
253
+ ></PaginationItemNext>
254
+ </div>
255
+ </div>
256
+ </template>
257
+ <style lang="scss" scoped>
258
+ .rsui-pagination {
259
+ @apply flex flex-nowrap items-center;
260
+ @apply w-fit border border-gray-200 rounded-full p-1;
261
+ @apply divide-x;
262
+ &__previous {
263
+ @apply size-full flex items-center pr-1;
264
+ }
265
+ &__items {
266
+ @apply size-full flex items-center px-1;
267
+ }
268
+ &__items-group {
269
+ @apply size-full flex items-center;
270
+ }
271
+ &__next {
272
+ @apply size-full flex items-center pl-1;
273
+ }
274
+ }
275
+ </style>
@@ -0,0 +1,60 @@
1
+ <script setup>
2
+ import { computed } from 'vue'
3
+
4
+ const props = defineProps({
5
+ active: {
6
+ type: Boolean,
7
+ default: false
8
+ },
9
+ freeze: {
10
+ type: Boolean,
11
+ default: false
12
+ },
13
+ disabled: {
14
+ type: Boolean,
15
+ default: false
16
+ }
17
+ })
18
+
19
+ const paginationItemClass = computed(() => [
20
+ 'rsui-pagination-item',
21
+ {
22
+ 'rsui-pagination-item--active': props.active,
23
+ 'rsui-pagination-item--freeze': props.freeze,
24
+ 'rsui-pagination-item--disabled': props.disabled,
25
+ }
26
+ ])
27
+
28
+ const emit = defineEmits(['click'])
29
+
30
+ function clickItem() {
31
+ if (props.active) return
32
+ if (props.freeze) return
33
+ if (props.disabled) return
34
+
35
+ emit('click')
36
+ }
37
+ </script>
38
+ <template>
39
+ <div :class="paginationItemClass"
40
+ @click.prevent="clickItem"
41
+ >
42
+ <slot></slot>
43
+ </div>
44
+ </template>
45
+ <style lang="scss" scoped>
46
+ .rsui-pagination-item {
47
+ @apply inline-flex items-center justify-center overflow-hidden select-none;
48
+ @apply min-w-9 w-fit h-7 p-1 rounded-md cursor-pointer transition;
49
+ @apply bg-white hover:bg-gray-100 text-rsui-medium text-sm;
50
+ &--active {
51
+ @apply bg-gray-200 hover:bg-gray-200 text-rsui-default cursor-default;
52
+ }
53
+ &--freeze {
54
+ @apply bg-white hover:bg-white cursor-default;
55
+ }
56
+ &--disabled {
57
+ @apply bg-white hover:bg-white text-gray-200 cursor-default;
58
+ }
59
+ }
60
+ </style>
@@ -0,0 +1,18 @@
1
+ <script setup>
2
+ import PaginationItem from './PaginationItem.vue'
3
+ import { EllipsisHorizontalIcon } from '@heroicons/vue/24/outline'
4
+ </script>
5
+ <template>
6
+ <PaginationItem freeze
7
+ class="rsui-pagination-item-collapsed"
8
+ >
9
+ <EllipsisHorizontalIcon></EllipsisHorizontalIcon>
10
+ </PaginationItem>
11
+ </template>
12
+ <style lang="scss" scoped>
13
+ .rsui-pagination-item-collapsed {
14
+ svg {
15
+ @apply size-4;
16
+ }
17
+ }
18
+ </style>
@@ -0,0 +1,17 @@
1
+ <script setup>
2
+ import PaginationItem from './PaginationItem.vue'
3
+ import { ChevronRightIcon } from '@heroicons/vue/24/outline'
4
+ </script>
5
+ <template>
6
+ <PaginationItem class="rsui-pagination-item-next">
7
+ <ChevronRightIcon></ChevronRightIcon>
8
+ </PaginationItem>
9
+ </template>
10
+ <style lang="scss" scoped>
11
+ .rsui-pagination-item-next {
12
+ @apply rounded-r-3xl;
13
+ svg {
14
+ @apply size-5;
15
+ }
16
+ }
17
+ </style>
@@ -0,0 +1,17 @@
1
+ <script setup>
2
+ import PaginationItem from './PaginationItem.vue'
3
+ import { ChevronLeftIcon } from '@heroicons/vue/24/outline'
4
+ </script>
5
+ <template>
6
+ <PaginationItem class="rsui-pagination-item-previous">
7
+ <ChevronLeftIcon></ChevronLeftIcon>
8
+ </PaginationItem>
9
+ </template>
10
+ <style lang="scss" scoped>
11
+ .rsui-pagination-item-previous {
12
+ @apply rounded-l-3xl;
13
+ svg {
14
+ @apply size-5;
15
+ }
16
+ }
17
+ </style>
@@ -0,0 +1,13 @@
1
+ import Pagination from './Pagination.vue'
2
+ import PaginationItem from './PaginationItem.vue'
3
+ import PaginationItemCollapsed from './PaginationItemCollapsed.vue'
4
+ import PaginationItemNext from './PaginationItemNext.vue'
5
+ import PaginationItemPrevious from './PaginationItemPrevious.vue'
6
+
7
+ export {
8
+ Pagination,
9
+ PaginationItem,
10
+ PaginationItemCollapsed,
11
+ PaginationItemNext,
12
+ PaginationItemPrevious,
13
+ }
@@ -0,0 +1,5 @@
1
+ import ProgressCircle from './ProgressCircle.vue'
2
+
3
+ export {
4
+ ProgressCircle,
5
+ }
@@ -0,0 +1,7 @@
1
+ import SignInWithGoogle from './SignInWithGoogle.vue'
2
+ import SignUpWithGoogle from './SignUpWithGoogle.vue'
3
+
4
+ export {
5
+ SignInWithGoogle,
6
+ SignUpWithGoogle,
7
+ }
@@ -0,0 +1,79 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue'
3
+ import { ArrowLongUpIcon } from '@heroicons/vue/24/outline'
4
+ import LinkPrimary from '../Link/LinkPrimary.vue'
5
+
6
+ const props = defineProps({
7
+ primary: {
8
+ type: Boolean,
9
+ default: false
10
+ }
11
+ })
12
+
13
+ const emit = defineEmits(['asc', 'desc'])
14
+
15
+ // const defaultColour = computed(() => !props.primary)
16
+
17
+ const sortingClass = computed(() => [
18
+ 'rsui-sorting',
19
+ {
20
+ 'rsui-sorting--primary': !!props.primary
21
+ }
22
+
23
+ ])
24
+
25
+ const desc = ref(false)
26
+
27
+ const iconClass = computed(() => [
28
+ 'rsui-sorting__icon',
29
+ {
30
+ 'rsui-sorting__icon--desc': !!desc.value
31
+ }
32
+ ])
33
+
34
+ function toggleDesc() {
35
+ desc.value = !desc.value
36
+
37
+ if (desc.value) {
38
+ emit('desc')
39
+ return
40
+ }
41
+
42
+ emit('asc')
43
+ return
44
+ }
45
+ </script>
46
+ <template>
47
+ <div :class="sortingClass">
48
+ <slot name="asc" v-if="!desc">
49
+ <LinkPrimary md
50
+ @click="toggleDesc"
51
+ >
52
+ <slot name="asc-label"></slot>
53
+ </LinkPrimary>
54
+ </slot>
55
+ <slot name="desc" v-if="desc">
56
+ <LinkPrimary md
57
+ @click="toggleDesc"
58
+ >
59
+ <slot name="desc-label"></slot>
60
+ </LinkPrimary>
61
+ </slot>
62
+ <ArrowLongUpIcon :class="iconClass"></ArrowLongUpIcon>
63
+ </div>
64
+ </template>
65
+ <style lang="scss" scoped>
66
+ .rsui-sorting {
67
+ @apply flex items-center justify-between;
68
+ @apply w-fit text-rsui-default;
69
+ &--primary {
70
+ @apply text-primary;
71
+ }
72
+ &__icon {
73
+ @apply size-4 transition;
74
+ &--desc {
75
+ @apply transform rotate-180;
76
+ }
77
+ }
78
+ }
79
+ </style>
@@ -0,0 +1,5 @@
1
+ import Sorting from './Sorting.vue'
2
+
3
+ export {
4
+ Sorting,
5
+ }
@@ -0,0 +1,5 @@
1
+ import TwoColumnLayout from './TwoColumnLayout.vue'
2
+
3
+ export {
4
+ TwoColumnLayout,
5
+ }