@energie360/ui-library 0.1.22 → 0.1.24

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 (38) hide show
  1. package/components/badge/u-badge.vue +2 -2
  2. package/components/card-amount/card-amount.scss +7 -0
  3. package/components/card-amount/u-card-amount.vue +21 -0
  4. package/components/card-amount-illustrated/card-amount-illustrated.scss +35 -0
  5. package/components/card-amount-illustrated/u-card-amount-illustrated.vue +80 -0
  6. package/components/card-contact/card-contact.scss +5 -3
  7. package/components/card-contact/u-card-contact.vue +15 -10
  8. package/components/card-footer/u-card-footer.vue +6 -2
  9. package/components/card-group/card-group.scss +25 -11
  10. package/components/card-group/u-card-group.vue +59 -4
  11. package/components/chip/chip.scss +31 -4
  12. package/components/chip/u-chip.vue +5 -2
  13. package/components/index.js +5 -0
  14. package/components/progress-bar/progress-bar.scss +5 -9
  15. package/components/progress-bar/u-progress-bar.vue +3 -6
  16. package/components/richtext/richtext.scss +2 -0
  17. package/components/skeleton-loader/u-skeleton-loader.vue +1 -1
  18. package/components/slider/slider.scss +249 -0
  19. package/components/slider/u-slider.vue +174 -0
  20. package/components/slider-progress-animation/slider-progress-animation.scss +25 -0
  21. package/components/slider-progress-animation/u-slider-progress-animation.vue +65 -0
  22. package/components/sprite-animation/sprite-animation.scss +7 -0
  23. package/components/sprite-animation/u-sprite-animation.vue +169 -0
  24. package/components/table/cell-progress-bar.scss +4 -0
  25. package/components/table/u-cell-icon-group.vue +12 -7
  26. package/components/table/u-cell-progress-bar.vue +5 -5
  27. package/components/text-block/text-block.scss +18 -14
  28. package/components/text-block/u-text-block.vue +17 -11
  29. package/components/tooltip/tooltip.scss +4 -2
  30. package/components/tooltip/u-tooltip.vue +20 -2
  31. package/elements/select-chip/select-chip.scss +1 -1
  32. package/elements/select-chip/u-select-chip.vue +7 -6
  33. package/modules/dialog/u-dialog.vue +2 -2
  34. package/package.json +3 -1
  35. package/utils/functions/animate.js +258 -0
  36. package/utils/math/scale-value.js +13 -0
  37. package/wizard/wizard-layout/u-wizard-layout-block.vue +2 -2
  38. package/wizard/wizard-top-bar/u-wizard-top-bar.vue +0 -8
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- interface Props {
2
+ export interface Badge {
3
3
  color?: string
4
4
  dot?: boolean
5
5
  type?: 'default' | 'success' | 'error' | 'warning' | 'info'
@@ -19,7 +19,7 @@ const {
19
19
  color = 'var(--e-c-mono-900)',
20
20
  type = 'default',
21
21
  show = true,
22
- } = defineProps<Props>()
22
+ } = defineProps<Badge>()
23
23
  </script>
24
24
 
25
25
  <template>
@@ -0,0 +1,7 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .card-amount__text {
4
+ @include a.type(700, strong);
5
+
6
+ margin-bottom: var(--e-space-2);
7
+ }
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { UProgressBar } from '../'
3
+
4
+ interface Props {
5
+ progress: number
6
+ text: string
7
+ }
8
+
9
+ defineProps<Props>()
10
+ </script>
11
+
12
+ <template>
13
+ <div class="card-amount">
14
+ <div class="card-amount__text">
15
+ {{ text }}
16
+ </div>
17
+ <UProgressBar :value="progress"></UProgressBar>
18
+ </div>
19
+ </template>
20
+
21
+ <style scoped lang="scss" src="./card-amount.scss"></style>
@@ -0,0 +1,35 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .card-amount-illustrated {
4
+ display: flex;
5
+ flex-direction: column;
6
+ row-gap: var(--e-space-3);
7
+ }
8
+
9
+ .card-amount-illustrated__title {
10
+ @include a.type(300, strong);
11
+ }
12
+
13
+ .card-amount-illustrated__amount {
14
+ padding: a.rem(22) 0;
15
+ }
16
+
17
+ .card-amount-illustrated__illustration {
18
+ position: relative;
19
+ width: a.rem(200);
20
+ height: a.rem(200);
21
+ align-self: center;
22
+ }
23
+
24
+ .card-amount-illustrated__max-amount-image {
25
+ position: absolute;
26
+ top: 0;
27
+ right: 0;
28
+ aspect-ratio: 5/2;
29
+ width: 85px;
30
+ }
31
+
32
+ .card-amount-illustrated__slider {
33
+ margin-top: -2px;
34
+ margin-bottom: -2px;
35
+ }
@@ -0,0 +1,80 @@
1
+ <script setup lang="ts">
2
+ import { SpriteAnimation } from '../sprite-animation/u-sprite-animation.vue'
3
+ import { UProgressBar, USpriteAnimation } from '../'
4
+ import { useTemplateRef } from 'vue'
5
+ import { Image } from '../../elements/types'
6
+
7
+ interface Props {
8
+ title?: string
9
+ amount?: number
10
+ maxAmountImage: Image
11
+ spriteAnimation?: Pick<
12
+ SpriteAnimation,
13
+ 'spritesheetPath' | 'framePositions' | 'frameHeight' | 'frameWidth'
14
+ >
15
+ }
16
+
17
+ defineProps<Props>()
18
+ defineEmits(['amount'])
19
+
20
+ const spriteAnimRef = useTemplateRef('spriteAnim')
21
+ let pausedFrame: number
22
+
23
+ const onPause = (frame: number) => {
24
+ pausedFrame = frame
25
+ }
26
+
27
+ const onMouseenter = () => {
28
+ spriteAnimRef.value.play()
29
+ }
30
+
31
+ const onMouseleave = () => {
32
+ spriteAnimRef.value.pause()
33
+ spriteAnimRef.value.playReverse(pausedFrame)
34
+ }
35
+ </script>
36
+
37
+ <template>
38
+ <div class="card-amount-illustrated">
39
+ <h3 class="card-amount-illustrated__title">
40
+ <slot name="title">{{ title }}</slot>
41
+ </h3>
42
+
43
+ <div
44
+ v-if="$slots.illustration || spriteAnimation"
45
+ class="card-amount-illustrated__illustration"
46
+ >
47
+ <slot name="illustration">
48
+ <USpriteAnimation
49
+ ref="spriteAnim"
50
+ v-bind="spriteAnimation"
51
+ :duration="200"
52
+ :width="200"
53
+ :height="200"
54
+ @mouseenter="onMouseenter"
55
+ @mouseleave="onMouseleave"
56
+ @pause="onPause"
57
+ ></USpriteAnimation>
58
+ </slot>
59
+
60
+ <div
61
+ v-if="($slots.maxAmountImage || maxAmountImage) && amount === 100"
62
+ class="card-amount-illustrated__max-amount-image"
63
+ >
64
+ <slot name="maxAmountImage">
65
+ <img :src="maxAmountImage.src" :alt="maxAmountImage.alt" />
66
+ </slot>
67
+ </div>
68
+ </div>
69
+
70
+ <div v-if="amount && !$slots.slider" class="card-amount-illustrated__amount">
71
+ <UProgressBar :value="amount"></UProgressBar>
72
+ </div>
73
+
74
+ <div v-if="$slots.slider" class="card-amount-illustrated__slider">
75
+ <slot name="slider"></slot>
76
+ </div>
77
+ </div>
78
+ </template>
79
+
80
+ <style scoped lang="scss" src="./card-amount-illustrated.scss"></style>
@@ -21,11 +21,13 @@
21
21
  @include a.type(200);
22
22
 
23
23
  margin-top: var(--e-space-1);
24
- }
25
24
 
26
- .card-contact__tel {
27
- @include t.text-link;
25
+ &:has(+ .card-contact__contacts) {
26
+ margin-bottom: var(--e-space-4);
27
+ }
28
+ }
28
29
 
30
+ .card-contact__contacts {
29
31
  margin-top: auto;
30
32
  }
31
33
 
@@ -1,16 +1,21 @@
1
1
  <script setup lang="ts">
2
- import { Image, Cta } from '../../elements/types'
3
-
4
- type Tel = Omit<Cta, 'target'>
2
+ import { Image } from '../../elements/types'
3
+ import { URichtext } from '../'
5
4
 
6
5
  interface Props {
7
6
  name?: string
8
7
  role?: string
9
- tel?: Tel
10
8
  image?: Image
9
+ contacts?: string
11
10
  }
12
11
 
13
12
  defineProps<Props>()
13
+ defineSlots<{
14
+ name()
15
+ role()
16
+ contacts()
17
+ image()
18
+ }>()
14
19
  </script>
15
20
 
16
21
  <template>
@@ -24,12 +29,12 @@ defineProps<Props>()
24
29
  <slot name="role">{{ role }}</slot>
25
30
  </p>
26
31
 
27
- <div v-if="$slots.tel || tel" class="card-contact__tel">
28
- <slot name="tel">
29
- <a :href="tel.href">
30
- {{ tel.label }}
31
- </a>
32
- </slot>
32
+ <div v-if="$slots.contacts || contacts" class="card-contact__contacts">
33
+ <URichtext>
34
+ <slot name="contacts">
35
+ <div v-html="contacts"></div>
36
+ </slot>
37
+ </URichtext>
33
38
  </div>
34
39
  </div>
35
40
 
@@ -13,6 +13,7 @@ interface Radio {
13
13
  label: string
14
14
  name?: string
15
15
  value?: string
16
+ disabled?: boolean
16
17
  }
17
18
 
18
19
  interface Props {
@@ -21,21 +22,24 @@ interface Props {
21
22
 
22
23
  const { cta = undefined } = defineProps<Props>()
23
24
 
25
+ const emits = defineEmits(['change'])
26
+
24
27
  const { toggleActiveCard } = inject('card')
25
28
  const { currentValue } = inject('card-group', {})
26
29
 
27
30
  const onChange = () => {
28
31
  toggleActiveCard(true)
32
+ emits('change', cta.value)
29
33
  }
30
34
 
31
35
  if (currentValue) {
32
36
  watch(currentValue, (newV) => {
33
- toggleActiveCard(newV === cta.value)
37
+ toggleActiveCard(newV === cta.value && !cta.disabled)
34
38
  })
35
39
 
36
40
  onMounted(() => {
37
41
  if (currentValue?.value) {
38
- toggleActiveCard(currentValue.value === cta.value)
42
+ toggleActiveCard(currentValue.value === cta.value && !cta.disabled)
39
43
  }
40
44
  })
41
45
  }
@@ -1,25 +1,39 @@
1
- @use '../../base/abstracts/' as a;
1
+ @use '../../base/abstracts' as a;
2
2
 
3
3
  .card-group {
4
4
  display: grid;
5
5
  gap: var(--e-space-5);
6
6
 
7
- // >= 3 card items
8
- grid-template-columns: repeat(3, 1fr);
9
- grid-template-rows: 1fr;
10
-
11
- // 1 card item
12
- &:has(> :last-child:nth-child(1)) {
13
- grid-template-columns: repeat(1, 1fr);
7
+ // Column behaviours
8
+ &.columns-auto {
9
+ // >= 3 card items
10
+ grid-template-columns: repeat(3, 1fr);
14
11
  grid-template-rows: 1fr;
12
+
13
+ // 1 card item
14
+ &:has(> :last-child:nth-child(1)) {
15
+ grid-template-columns: repeat(1, 1fr);
16
+ grid-template-rows: 1fr;
17
+ }
18
+
19
+ // 2 card items
20
+ &:has(> :last-child:nth-child(2)) {
21
+ grid-template-columns: repeat(2, 1fr);
22
+ grid-template-rows: 1fr;
23
+ }
15
24
  }
16
25
 
17
- // 2 card items
18
- &:has(> :last-child:nth-child(2)) {
19
- grid-template-columns: repeat(2, 1fr);
26
+ &.columns-4 {
27
+ grid-template-columns: repeat(4, 1fr);
20
28
  grid-template-rows: 1fr;
21
29
  }
22
30
 
31
+ &.use-carousel {
32
+ display: block;
33
+
34
+ // touch-action: pan-y;
35
+ }
36
+
23
37
  @include a.bp(lg) {
24
38
  &:has(> :last-child:nth-child(n)) {
25
39
  grid-template-columns: repeat(1, 1fr);
@@ -1,13 +1,48 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, onUnmounted, useTemplateRef } from 'vue'
2
+ import { register } from 'swiper/element/bundle'
3
+ import { onMounted, onUnmounted, useTemplateRef, watch } from 'vue'
3
4
  import { debounceRaf } from '../../utils/functions/debounce'
4
5
  import { isLarge } from '../../utils/functions/breakpoint'
5
6
  import { useRadioGroup } from '../../elements/radio-group/radio-group-composables'
6
7
 
7
- const model = defineModel<string>()
8
+ // Register swiper custom elements.
9
+ register()
10
+
11
+ interface Props {
12
+ columns?: 1 | 2 | 3 | 4 | 'auto'
13
+ useCarousel?: boolean
14
+ }
8
15
 
16
+ const { columns = 'auto', useCarousel = false } = defineProps<Props>()
17
+ const model = defineModel<string>()
9
18
  const group = useTemplateRef('group')
10
19
 
20
+ const initSwiper = () => {
21
+ if (!useCarousel) {
22
+ return
23
+ }
24
+
25
+ const swiperEl = group.value.querySelector('swiper-container')
26
+ const swiperParams = {
27
+ spaceBetween: 20,
28
+ breakpoints: {
29
+ 1240: {
30
+ slidesPerView: 4,
31
+ },
32
+ 1020: {
33
+ slidesPerView: 3,
34
+ },
35
+ 740: {
36
+ slidesPerView: 2,
37
+ },
38
+ },
39
+ }
40
+
41
+ Object.assign(swiperEl, swiperParams)
42
+
43
+ swiperEl.initialize()
44
+ }
45
+
11
46
  const onResize = debounceRaf(() => {
12
47
  const headers = Array.from(group.value.querySelectorAll('.card-header'))
13
48
 
@@ -45,6 +80,8 @@ onMounted(() => {
45
80
  // Initial state
46
81
  onResize()
47
82
  })
83
+
84
+ initSwiper()
48
85
  })
49
86
 
50
87
  onUnmounted(() => {
@@ -55,11 +92,29 @@ useRadioGroup({
55
92
  model,
56
93
  provideKey: 'card-group',
57
94
  })
95
+
96
+ watch(
97
+ () => useCarousel,
98
+ () => {
99
+ initSwiper()
100
+ },
101
+ )
58
102
  </script>
59
103
 
60
104
  <template>
61
- <div ref="group" class="card-group">
62
- <slot></slot>
105
+ <div ref="group" :class="['card-group', `columns-${columns}`, { 'use-carousel': useCarousel }]">
106
+ <template v-if="useCarousel">
107
+ <swiper-container init="false">
108
+ <template v-for="(vnode, idx) in $slots.default()[0].children" :key="idx">
109
+ <swiper-slide>
110
+ <component :is="vnode" />
111
+ </swiper-slide>
112
+ </template>
113
+ </swiper-container>
114
+ </template>
115
+ <template v-else>
116
+ <slot />
117
+ </template>
63
118
  </div>
64
119
  </template>
65
120
 
@@ -1,25 +1,52 @@
1
1
  @use '../../base/abstracts' as a;
2
2
 
3
3
  .chip {
4
- background-color: var(--e-c-mono-50);
5
- border: 1px solid var(--e-c-mono-200);
4
+ --chip-background-color: var(--e-c-mono-50);
5
+ --chip-font-color: var(--e-c-mono-900);
6
+ --chip-caption-color: var(--e-c-mono-700);
7
+ --chip-border-color: var(--e-c-mono-200);
8
+ --chip-icon-color: var(--e-c-mono-700);
9
+
10
+ background-color: var(--chip-background-color);
11
+ border: 1px solid var(--chip-border-color);
6
12
  border-radius: var(--e-brd-radius-2);
7
13
  padding: var(--e-space-1_5) var(--e-space-3);
8
14
  display: inline-flex;
9
15
  align-items: center;
16
+ justify-content: space-between;
10
17
  column-gap: var(--e-space-1);
18
+
19
+ &.chip--icon-right {
20
+ .chip__icon {
21
+ order: 2;
22
+ }
23
+
24
+ .chip__label {
25
+ order: 1;
26
+ }
27
+ }
28
+
29
+ &.full-width {
30
+ width: 100%;
31
+ }
32
+
33
+ &.big {
34
+ padding: a.rem(16);
35
+ }
11
36
  }
12
37
 
13
38
  .chip__icon {
14
- color: var(--e-c-mono-700);
39
+ color: var(--chip-icon-color);
15
40
  }
16
41
 
17
42
  .chip__label {
18
43
  @include a.type(200, strong);
44
+
45
+ color: var(--chip-font-color);
19
46
  }
20
47
 
21
48
  .chip__caption {
22
49
  @include a.type(50, strong);
23
50
 
24
- color: var(--e-c-mono-700);
51
+ color: var(--chip-caption-color);
25
52
  }
@@ -5,13 +5,16 @@ export interface Chip {
5
5
  caption?: string
6
6
  label?: string
7
7
  icon?: string
8
+ iconPosition?: 'left' | 'right'
9
+ fullWidth?: boolean
10
+ big?: boolean
8
11
  }
9
12
 
10
- defineProps<Chip>()
13
+ const { caption = '', label = '', icon = undefined, iconPosition = 'left' } = defineProps<Chip>()
11
14
  </script>
12
15
 
13
16
  <template>
14
- <div class="chip">
17
+ <div :class="['chip', `chip--icon-${iconPosition}`, { 'full-width': fullWidth, big }]">
15
18
  <span v-if="icon" class="chip__icon">
16
19
  <UIcon :name="icon"></UIcon>
17
20
  </span>
@@ -14,6 +14,8 @@ export { default as UCardCtaHeader } from './card-cta-header/u-card-cta-header.v
14
14
  export { default as UCardCtaBar } from './card-cta-bar/u-card-cta-bar.vue'
15
15
  export { default as UCardContact } from './card-contact/u-card-contact.vue'
16
16
  export { default as UCardPriceList } from './card-price-list/u-card-price-list.vue'
17
+ export { default as UCardAmountIllustrated } from './card-amount-illustrated/u-card-amount-illustrated.vue'
18
+ export { default as UCardAmount } from './card-amount/u-card-amount.vue'
17
19
 
18
20
  // Collapsible
19
21
  export { default as UCollapsible } from './collapsible/u-collapsible.vue'
@@ -62,3 +64,6 @@ export { default as USkeletonLoader } from './skeleton-loader/u-skeleton-loader.
62
64
  export { default as UCardHighlight } from './card-highlight/u-card-highlight.vue'
63
65
  export { default as URating } from './rating/u-rating.vue'
64
66
  export { default as UChip } from './chip/u-chip.vue'
67
+ export { default as USlider } from './slider/u-slider.vue'
68
+ export { default as USpriteAnimation } from './sprite-animation/u-sprite-animation.vue'
69
+ export { default as USliderProgressAnimation } from './slider-progress-animation/u-slider-progress-animation.vue'
@@ -5,22 +5,18 @@
5
5
  align-items: center;
6
6
  column-gap: a.rem(4);
7
7
  height: a.rem(10);
8
- width: #{a.rem(64 + 4 + 10)}; // progress-track + space + icon
8
+ width: 100%;
9
9
 
10
- &.full-width {
11
- width: 100%;
12
-
13
- .progress-track {
14
- width: calc(100% - #{a.rem(4 + 10)});
15
- }
10
+ .progress-track {
11
+ width: calc(100% - #{a.rem(4 + 10)});
16
12
  }
17
13
  }
18
14
 
19
15
  .progress-track {
20
- width: a.rem(64);
16
+ width: calc(100% - #{a.rem(4 + 10)});
21
17
  min-width: a.rem(64);
22
18
  height: a.rem(4);
23
- background-color: var(--e-c-mono-100);
19
+ background-color: var(--e-c-primary-01-100);
24
20
  border-radius: a.rem(4);
25
21
  overflow: hidden;
26
22
  }
@@ -1,14 +1,13 @@
1
1
  <script setup lang="ts">
2
2
  interface Props {
3
3
  value: number
4
- fullWidth?: boolean
5
4
  }
6
5
 
7
- const { fullWidth = false } = defineProps<Props>()
6
+ defineProps<Props>()
8
7
  </script>
9
8
 
10
9
  <template>
11
- <div :class="['progress-bar', { 'full-width': fullWidth }]">
10
+ <div class="progress-bar">
12
11
  <div class="progress-track">
13
12
  <div class="progress-position" :style="{ width: `${value}%` }"></div>
14
13
  </div>
@@ -16,6 +15,4 @@ const { fullWidth = false } = defineProps<Props>()
16
15
  </div>
17
16
  </template>
18
17
 
19
- <style scoped lang="scss">
20
- @use './progress-bar.scss';
21
- </style>
18
+ <style scoped lang="scss" src="./progress-bar.scss"></style>
@@ -88,6 +88,8 @@
88
88
  transition:
89
89
  text-decoration-color a.$trs-default,
90
90
  color a.$trs-default;
91
+ -webkit-font-smoothing: antialiased;
92
+ -moz-osx-font-smoothing: grayscale;
91
93
 
92
94
  &:hover {
93
95
  text-decoration-color: var(--e-c-primary-01-50);
@@ -21,7 +21,7 @@ const { type = SkeletonType.fit } = defineProps<Props>()
21
21
  </template>
22
22
 
23
23
  <template v-if="type === SkeletonType.fit">
24
- <div class="skeleton-loader fit"></div>
24
+ <div class="skeleton-loader fit" v-bind="$attrs"></div>
25
25
  </template>
26
26
  </template>
27
27