@redseed/redseed-ui-vue3 5.3.9 → 5.4.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.
package/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './src/components/Button'
12
12
  export * from './src/components/ButtonGroup'
13
13
  export * from './src/components/Card'
14
14
  export * from './src/components/CardGroup'
15
+ export * from './src/components/Disclosure'
15
16
  export * from './src/components/DropdownMenu'
16
17
  export * from './src/components/Empty'
17
18
  export * from './src/components/Form'
@@ -33,4 +34,5 @@ export * from './src/components/Social'
33
34
  export * from './src/components/Sorting'
34
35
  export * from './src/components/Switcher'
35
36
  export * from './src/components/Table'
36
- export * from './src/components/Toggle'
37
+ export * from './src/components/Toggle'
38
+ export * from './src/helpers'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redseed/redseed-ui-vue3",
3
- "version": "5.3.9",
3
+ "version": "5.4.0",
4
4
  "description": "RedSeed UI Vue 3 components",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/redseedtraining/redseed-ui",
@@ -12,8 +12,8 @@
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
14
  "@heroicons/vue": "^2.2.0",
15
- "@vueuse/components": "^12.8.2",
16
- "@vueuse/core": "^12.7.0",
15
+ "@vueuse/components": "^13.2.0",
16
+ "@vueuse/core": "^13.2.0",
17
17
  "lodash": "^4.17.21",
18
18
  "lottie-web": "^5.12.2",
19
19
  "vue": "^3.5.13"
@@ -100,10 +100,10 @@ function onClick() {
100
100
  }
101
101
 
102
102
  &__content {
103
- @apply min-h-16 flex-1 flex flex-col relative gap-y-3;
103
+ @apply flex-1 flex flex-col relative gap-y-3;
104
104
 
105
105
  &--padded {
106
- @apply py-5 px-4 sm:px-6;
106
+ @apply py-5 px-4 sm:px-6 min-h-16;
107
107
  }
108
108
  }
109
109
 
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { ref } from 'vue'
3
3
  import ButtonTertiary from '../Button/ButtonTertiary.vue'
4
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
4
+ import { useResponsiveWidth } from '../../helpers'
5
5
  import { EllipsisVerticalIcon } from '@heroicons/vue/24/outline'
6
6
 
7
7
  defineProps({
@@ -132,12 +132,13 @@ const emit = defineEmits(['click:more-actions'])
132
132
  </template>
133
133
  <style lang="scss" scoped>
134
134
  .rsui-card-header {
135
- @apply flex flex-col gap-x-3 gap-y-5 overflow-hidden;
135
+ @apply flex flex-col gap-x-3 gap-y-5 overflow-hidden transition-all;
136
136
  @apply md:flex-row md:justify-between md:items-center;
137
137
  @apply py-4 px-4 sm:px-6;
138
+ @apply border-b border-transparent;
138
139
 
139
140
  &--divider {
140
- @apply border-b border-rsui-grey-400;
141
+ @apply border-rsui-grey-400;
141
142
  }
142
143
 
143
144
  &__header {
@@ -2,7 +2,7 @@
2
2
  import { ref, computed } from 'vue'
3
3
  import Empty from '../Empty/Empty.vue'
4
4
  import Pagination from '../Pagination/Pagination.vue'
5
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
5
+ import { useResponsiveWidth } from '../../helpers'
6
6
 
7
7
  const props = defineProps({
8
8
  controlApplied: {
@@ -86,42 +86,46 @@ const showNotFoundMessage = computed(() => !props.totalItems && props.controlApp
86
86
  <slot></slot>
87
87
  </div>
88
88
  <div v-if="showEmptyMessage" class="rsui-card-group__empty">
89
- <Empty
90
- @clickPrimaryAction="$emit('clickEmptyAction')"
91
- @clickSecondaryAction="$emit('clickSecondaryEmptyAction')"
92
- @clickTertiaryAction="$emit('clickTertiaryEmptyAction')"
93
- >
94
- <template #image>
95
- <slot name="empty-image"></slot>
96
- </template>
97
-
98
- <template #title v-if="$slots['empty-title']">
99
- <slot name="empty-title"></slot>
100
- </template>
101
-
102
- <slot name="empty-description">It looks like there's nothing here yet.</slot>
103
-
104
- <template #actions="{ isWide }" v-if="$slots['empty-actions']">
105
- <slot name="empty-actions" :isWide="isWide"></slot>
106
- </template>
107
-
108
- <template #primary-action-label v-if="$slots['empty-action-label']">
109
- <slot name="empty-action-label"></slot>
110
- </template>
111
-
112
- <template #secondary-action-label v-if="$slots['empty-secondary-action-label']">
113
- <slot name="empty-secondary-action-label"></slot>
114
- </template>
115
-
116
- <template #tertiary-action-label v-if="$slots['empty-tertiary-action-label']">
117
- <slot name="empty-tertiary-action-label"></slot>
118
- </template>
119
- </Empty>
89
+ <slot name="empty">
90
+ <Empty
91
+ @clickPrimaryAction="$emit('clickEmptyAction')"
92
+ @clickSecondaryAction="$emit('clickSecondaryEmptyAction')"
93
+ @clickTertiaryAction="$emit('clickTertiaryEmptyAction')"
94
+ >
95
+ <template #image>
96
+ <slot name="empty-image"></slot>
97
+ </template>
98
+
99
+ <template #title v-if="$slots['empty-title']">
100
+ <slot name="empty-title"></slot>
101
+ </template>
102
+
103
+ <slot name="empty-description">It looks like there's nothing here yet.</slot>
104
+
105
+ <template #actions="{ isWide }" v-if="$slots['empty-actions']">
106
+ <slot name="empty-actions" :isWide="isWide"></slot>
107
+ </template>
108
+
109
+ <template #primary-action-label v-if="$slots['empty-action-label']">
110
+ <slot name="empty-action-label"></slot>
111
+ </template>
112
+
113
+ <template #secondary-action-label v-if="$slots['empty-secondary-action-label']">
114
+ <slot name="empty-secondary-action-label"></slot>
115
+ </template>
116
+
117
+ <template #tertiary-action-label v-if="$slots['empty-tertiary-action-label']">
118
+ <slot name="empty-tertiary-action-label"></slot>
119
+ </template>
120
+ </Empty>
121
+ </slot>
120
122
  </div>
121
- <div v-if="showNotFoundMessage" class="rsui-card-group">
122
- <Empty>
123
- <slot name="filter-empty-description">No items meet your filter criteria.</slot>
124
- </Empty>
123
+ <div v-if="showNotFoundMessage" class="rsui-card-group__empty">
124
+ <slot name="not-found">
125
+ <Empty>
126
+ <slot name="filter-empty-description">No items meet your filter criteria.</slot>
127
+ </Empty>
128
+ </slot>
125
129
  </div>
126
130
  </div>
127
131
  </template>
@@ -0,0 +1,122 @@
1
+ <script setup>
2
+ import { ref, watch, watchEffect, nextTick } from 'vue'
3
+ import { ChevronUpIcon } from '@heroicons/vue/24/outline'
4
+ import { ButtonTertiary } from '../Button'
5
+
6
+ const props = defineProps({
7
+ open: {
8
+ type: Boolean,
9
+ default: true,
10
+ },
11
+ })
12
+
13
+ const emit = defineEmits(['click'])
14
+
15
+ const triggerId = ref(_.uniqueId('disclosure-trigger-'))
16
+ const contentId = ref(_.uniqueId('disclosure-content-'))
17
+
18
+ const isOpen = ref(props.open)
19
+ watch(() => props.open, () => isOpen.value = props.open)
20
+
21
+ function handleTrigger() {
22
+ isOpen.value = !isOpen.value
23
+
24
+ emit('click', { open: isOpen.value })
25
+ }
26
+
27
+ const contentRef = ref(null)
28
+
29
+ async function setContentMaxHeight() {
30
+ if (!contentRef.value) return
31
+
32
+ await nextTick()
33
+
34
+ contentRef.value.style.maxHeight = contentRef.value.scrollHeight + 'px'
35
+ }
36
+
37
+ async function resetContentMaxHeight() {
38
+ if (!contentRef.value) return
39
+
40
+ await nextTick()
41
+
42
+ contentRef.value.style.maxHeight = '0px'
43
+ }
44
+
45
+ watchEffect(() => {
46
+ if (isOpen.value) {
47
+ setContentMaxHeight()
48
+ return
49
+ }
50
+
51
+ resetContentMaxHeight()
52
+ })
53
+ </script>
54
+
55
+ <template>
56
+ <div class="rsui-disclosure">
57
+ <slot name="child"
58
+ :isOpen="isOpen"
59
+ :triggerId="triggerId"
60
+ :contentId="contentId"
61
+ :handleTrigger="handleTrigger"
62
+ ></slot>
63
+ </div>
64
+
65
+ <Teleport :to="`#${triggerId}`">
66
+ <slot name="trigger"
67
+ :handleTrigger="handleTrigger"
68
+ >
69
+ <ButtonTertiary
70
+ :sm="$attrs.sm"
71
+ :md="$attrs.md"
72
+ :lg="$attrs.lg"
73
+ :xl="$attrs.xl"
74
+ :2xl="$attrs['2xl']"
75
+ :full="$attrs.full"
76
+ @click.stop="handleTrigger"
77
+ >
78
+ <ChevronUpIcon
79
+ :class="[
80
+ 'rsui-disclosure__trigger-icon',
81
+ {
82
+ 'rsui-disclosure__trigger-icon--open': isOpen,
83
+ }
84
+ ]"
85
+ ></ChevronUpIcon>
86
+ </ButtonTertiary>
87
+ </slot>
88
+ </Teleport>
89
+
90
+ <Teleport :to="`#${contentId}`">
91
+ <div ref="contentRef"
92
+ :class="[
93
+ 'rsui-disclosure__content',
94
+ {
95
+ 'rsui-disclosure__content--open': isOpen,
96
+ }
97
+ ]"
98
+ >
99
+ <slot name="content"></slot>
100
+ </div>
101
+ </Teleport>
102
+ </template>
103
+
104
+ <style lang="scss" scoped>
105
+ .rsui-disclosure {
106
+ &__trigger-icon {
107
+ @apply transition-all;
108
+
109
+ &--open {
110
+ @apply rotate-180;
111
+ }
112
+ }
113
+
114
+ &__content {
115
+ @apply transition-all max-h-0 overflow-hidden opacity-0;
116
+
117
+ &--open {
118
+ @apply overflow-visible opacity-100;
119
+ }
120
+ }
121
+ }
122
+ </style>
@@ -0,0 +1,6 @@
1
+
2
+ import Disclosure from './Disclosure.vue'
3
+
4
+ export {
5
+ Disclosure
6
+ }
@@ -5,7 +5,14 @@ import ButtonSecondary from '../Button/ButtonSecondary.vue'
5
5
  import ButtonTertiary from '../Button/ButtonTertiary.vue'
6
6
  import BodyText from '../HTML/BodyText.vue'
7
7
  import { ExclamationCircleIcon } from '@heroicons/vue/24/outline'
8
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
8
+ import { useResponsiveWidth } from '../../helpers'
9
+
10
+ const props = defineProps({
11
+ showImage: {
12
+ type: Boolean,
13
+ default: true,
14
+ },
15
+ })
9
16
 
10
17
  const emit = defineEmits(['clickPrimaryAction', 'clickSecondaryAction', 'clickTertiaryAction'])
11
18
 
@@ -32,7 +39,9 @@ const emptyClass = computed(() => [
32
39
  This slot is used to render the image.
33
40
  The image is used to display an icon or an image.
34
41
  -->
35
- <div class="rsui-empty__image">
42
+ <div v-if="showImage"
43
+ class="rsui-empty__image"
44
+ >
36
45
  <slot name="image">
37
46
  <ExclamationCircleIcon></ExclamationCircleIcon>
38
47
  </slot>
@@ -1,10 +1,34 @@
1
1
  <script setup>
2
+ defineProps({
3
+ showContent: {
4
+ type: Boolean,
5
+ default: true,
6
+ },
7
+ })
2
8
  </script>
3
9
  <template>
4
10
  <div class="rsui-hero-section">
5
11
  <slot name="header"></slot>
6
12
 
7
- <div class="rsui-hero-section__cards">
13
+ <div v-if="$slots.content"
14
+ :class="[
15
+ 'rsui-hero-section__content',
16
+ {
17
+ 'rsui-hero-section__content--hidden': !showContent,
18
+ }
19
+ ]"
20
+ >
21
+ <slot name="content"></slot>
22
+ </div>
23
+
24
+ <div v-if="$slots.default"
25
+ :class="[
26
+ 'rsui-hero-section__cards',
27
+ {
28
+ 'rsui-hero-section__cards--hidden': !showContent,
29
+ }
30
+ ]"
31
+ >
8
32
  <slot></slot>
9
33
  </div>
10
34
  </div>
@@ -15,6 +39,16 @@
15
39
 
16
40
  &__cards {
17
41
  @apply grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-6;
42
+
43
+ &--hidden {
44
+ @apply hidden;
45
+ }
46
+ }
47
+
48
+ &__content {
49
+ &--hidden {
50
+ @apply hidden;
51
+ }
18
52
  }
19
53
  }
20
54
  </style>
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { ref } from 'vue'
3
3
  import ButtonTertiary from '../Button/ButtonTertiary.vue'
4
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
4
+ import { useResponsiveWidth } from '../../helpers'
5
5
  import { EllipsisVerticalIcon } from '@heroicons/vue/24/outline'
6
6
 
7
7
  defineProps({
@@ -101,10 +101,12 @@ const emit = defineEmits(['click:more-actions'])
101
101
  </template>
102
102
  <style lang="scss" scoped>
103
103
  .rsui-section-header {
104
- @apply flex flex-col gap-x-3 gap-y-5;
104
+ @apply flex flex-col gap-x-3 gap-y-5 transition-all;
105
105
  @apply md:flex-row md:justify-between md:items-center;
106
+ @apply border-b border-transparent;
107
+
106
108
  &--divider {
107
- @apply border-b border-rsui-grey-400 pb-5;
109
+ @apply border-rsui-grey-400 pb-5;
108
110
  }
109
111
 
110
112
  &__header {
@@ -4,7 +4,7 @@ import FormFieldSearch from '../FormField/FormFieldSearch.vue'
4
4
  import FormFieldSelect from '../FormField/FormFieldSelect.vue'
5
5
  import Sorting from '../Sorting/Sorting.vue'
6
6
  import Pagination from '../Pagination/Pagination.vue'
7
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
7
+ import { useResponsiveWidth } from '../../helpers'
8
8
 
9
9
  const props = defineProps({
10
10
  searchable: {
@@ -2,7 +2,7 @@
2
2
  import { ref, computed, useSlots } from 'vue'
3
3
  import { UserIcon } from '@heroicons/vue/24/solid'
4
4
  import ButtonTertiary from '../Button/ButtonTertiary.vue'
5
- import { useResponsiveWidth } from '../../helpers/ResponsiveWidth'
5
+ import { useResponsiveWidth } from '../../helpers'
6
6
 
7
7
  const props = defineProps({
8
8
  avatar: {
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { ref, computed } from 'vue'
3
3
  import LottieCubes from './LottieCubes.json'
4
- import { useLottie } from '../../helpers/Lottie'
4
+ import { useLottie } from '../../helpers'
5
5
 
6
6
  const props = defineProps({
7
7
  primary: {
@@ -0,0 +1,7 @@
1
+ import { useLottie } from './Lottie'
2
+ import { useResponsiveWidth } from './ResponsiveWidth'
3
+
4
+ export {
5
+ useLottie,
6
+ useResponsiveWidth,
7
+ }