@energie360/ui-library 0.1.23 → 0.1.25

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 (50) 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 +4 -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/_wizard.scss +1 -1
  17. package/components/richtext/richtext.scss +2 -0
  18. package/components/skeleton-loader/u-skeleton-loader.vue +1 -1
  19. package/components/slider/slider.scss +1 -0
  20. package/components/slider/u-slider.vue +26 -15
  21. package/components/slider-progress-animation/slider-progress-animation.scss +25 -0
  22. package/components/slider-progress-animation/u-slider-progress-animation.vue +65 -0
  23. package/components/sprite-animation/sprite-animation.scss +7 -0
  24. package/components/sprite-animation/u-sprite-animation.vue +169 -0
  25. package/components/table/cell-progress-bar.scss +4 -0
  26. package/components/table/u-cell-icon-group.vue +12 -7
  27. package/components/table/u-cell-progress-bar.vue +5 -5
  28. package/components/text-block/text-block.scss +18 -14
  29. package/components/text-block/u-text-block.vue +17 -11
  30. package/dist/elements/text.css +749 -0
  31. package/dist/elements/text.css.map +1 -0
  32. package/dist/layout/container.css +29 -0
  33. package/dist/layout/container.css.map +1 -0
  34. package/dist/layout/grid.css +3253 -0
  35. package/dist/layout/grid.css.map +1 -0
  36. package/elements/index.js +0 -1
  37. package/elements/select-chip/select-chip.scss +1 -1
  38. package/elements/select-chip/u-select-chip.vue +7 -6
  39. package/modules/feedback/feedback-vote-buttons.scss +10 -0
  40. package/modules/feedback/types/feedback.type.ts +4 -2
  41. package/modules/feedback/u-feedback-vote-buttons.vue +26 -12
  42. package/modules/feedback/u-feedback.vue +2 -1
  43. package/package.json +3 -1
  44. package/utility/elements/text.scss +61 -0
  45. package/utility/layout/container.scss +1 -0
  46. package/utility/layout/grid.scss +1 -0
  47. package/utils/functions/animate.js +258 -0
  48. package/wizard/wizard-layout/u-wizard-layout-block.vue +2 -2
  49. package/wizard/wizard-top-bar/u-wizard-top-bar.vue +0 -8
  50. package/elements/range-slider/u-range-slider.vue +0 -138
@@ -0,0 +1,25 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .slider-progress-animation {
4
+ &.lottie-ready {
5
+ .slider-progress-animation__lottie {
6
+ visibility: visible;
7
+ }
8
+ }
9
+ }
10
+
11
+ .slider-progress-animation__lottie {
12
+ position: relative;
13
+ visibility: hidden;
14
+ margin: 0 auto var(--e-space-6);
15
+ max-width: a.rem(460);
16
+ }
17
+
18
+ .slider-progress-animation__max-amount-image {
19
+ position: absolute;
20
+ top: 0;
21
+ right: 0;
22
+ aspect-ratio: 5/2;
23
+ width: 85px;
24
+ z-index: 1;
25
+ }
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
3
+ import '@lottiefiles/lottie-player'
4
+ import { USlider } from '../'
5
+ import { Slider } from '../slider/u-slider.vue'
6
+ import { Image } from '../../elements/types'
7
+
8
+ interface Props {
9
+ lottieSrc: string
10
+ slider: Slider
11
+ maxAmountImage: Image
12
+ }
13
+
14
+ const { lottieSrc } = defineProps<Props>()
15
+ const model = defineModel<number>()
16
+
17
+ const lottieWrapperRef = useTemplateRef('lottie-wrapper')
18
+ let lottieEl
19
+ let lottie
20
+ const lottieReady = ref(false)
21
+
22
+ const onChange = (value) => {
23
+ lottie.goToAndStop(value, true)
24
+ }
25
+
26
+ onMounted(() => {
27
+ // lottie-player web-component will be ready in this callback.
28
+ const tmp = document.createElement('lottie-player')
29
+ tmp.setAttribute('src', lottieSrc)
30
+ tmp.setAttribute('speed', '2.5')
31
+ lottieEl = lottieWrapperRef.value.appendChild(tmp)
32
+
33
+ lottieEl.addEventListener('load', () => {
34
+ lottie = lottieEl.getLottie()
35
+
36
+ // Set initial state of animation
37
+ lottieReady.value = true
38
+ lottie.playSegments([0, model.value], true)
39
+ })
40
+ })
41
+
42
+ onUnmounted(() => {
43
+ if (lottieEl) {
44
+ lottieEl.remove()
45
+ }
46
+ })
47
+ </script>
48
+
49
+ <template>
50
+ <div :class="['slider-progress-animation', { 'lottie-ready': lottieReady }]">
51
+ <div ref="lottie-wrapper" class="slider-progress-animation__lottie">
52
+ <div
53
+ v-if="maxAmountImage && model === 100"
54
+ class="slider-progress-animation__max-amount-image"
55
+ >
56
+ <slot name="maxAmountImage">
57
+ <img :src="maxAmountImage.src" :alt="maxAmountImage.alt" />
58
+ </slot>
59
+ </div>
60
+ </div>
61
+ <USlider v-model="model" v-bind="slider" @change="onChange" />
62
+ </div>
63
+ </template>
64
+
65
+ <style scoped lang="scss" src="./slider-progress-animation.scss"></style>
@@ -0,0 +1,7 @@
1
+ .sprite-animation {
2
+ canvas {
3
+ display: block;
4
+ width: 100%;
5
+ height: 100%;
6
+ }
7
+ }
@@ -0,0 +1,169 @@
1
+ <script setup lang="ts">
2
+ import { computed, onMounted, useTemplateRef } from 'vue'
3
+ import { animateValue } from '../../utils/functions/animate.js'
4
+ import { clamp } from '../../utils/math/clamp'
5
+
6
+ export interface SpriteAnimation {
7
+ spritesheetPath: string
8
+ framePositions: [number, number][]
9
+ frameWidth: number
10
+ frameHeight: number
11
+ width?: number
12
+ height?: number
13
+ initialFrame?: number
14
+ duration?: number
15
+ fps?: number
16
+ easing?: (x: number) => number
17
+ }
18
+
19
+ const {
20
+ spritesheetPath,
21
+ framePositions,
22
+ frameWidth,
23
+ frameHeight,
24
+ width = undefined,
25
+ height = undefined,
26
+ initialFrame = 0,
27
+ duration = 300,
28
+ fps = undefined,
29
+ easing = (x) => x, // linear easing
30
+ } = defineProps<SpriteAnimation>()
31
+
32
+ const emits = defineEmits(['ready', 'pause'])
33
+
34
+ const canvasEl = useTemplateRef('canvas')
35
+ const canvasWidth = computed(() => width || frameWidth)
36
+ const canvasHeight = computed(() => height || frameHeight)
37
+ const devicePixelRatio = window.devicePixelRatio || 1
38
+ let currentFrame = initialFrame
39
+ let ctx: CanvasRenderingContext2D
40
+ let spritesheet: HTMLImageElement
41
+ let isAnimating = false
42
+ let animation
43
+
44
+ const loadImage = (path: string) =>
45
+ new Promise<HTMLImageElement>((resolve, reject) => {
46
+ const img = document.createElement('img')
47
+ img.addEventListener('load', () => {
48
+ resolve(img)
49
+ })
50
+
51
+ img.addEventListener('error', () => {
52
+ reject(img)
53
+ })
54
+
55
+ // Load image
56
+ img.src = path
57
+ })
58
+
59
+ const draw = () => {
60
+ // If context was not created just avoid drawing anything
61
+ if (!ctx) return
62
+
63
+ const [x, y] = framePositions[currentFrame]
64
+
65
+ ctx.save()
66
+ ctx.scale(devicePixelRatio, devicePixelRatio)
67
+ ctx.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
68
+ ctx.drawImage(
69
+ spritesheet,
70
+ x,
71
+ y,
72
+ frameWidth,
73
+ frameHeight,
74
+ 0,
75
+ 0,
76
+ canvasWidth.value,
77
+ canvasHeight.value,
78
+ )
79
+ ctx.restore()
80
+ }
81
+
82
+ const durationFromFps = () => (1000 / fps) * framePositions.length
83
+
84
+ const durationFromFrames = (start, end) =>
85
+ (Math.abs(end - start) / framePositions.length) * duration
86
+
87
+ const animate = (start, end) => {
88
+ isAnimating = true
89
+
90
+ animation = animateValue({
91
+ duration: fps ? durationFromFps() : durationFromFrames(start, end),
92
+ start,
93
+ easing: fps ? undefined : easing,
94
+ end,
95
+ onUpdate(value) {
96
+ toFrame(value)
97
+ },
98
+ onComplete(value) {
99
+ isAnimating = false
100
+ emits('pause', getFrameFromProgress(value))
101
+ },
102
+ onAbort(value) {
103
+ emits('pause', getFrameFromProgress(value))
104
+ isAnimating = false
105
+ },
106
+ })
107
+ }
108
+
109
+ const play = (start = 0, end = framePositions.length - 1) => {
110
+ animate(start, end)
111
+ }
112
+
113
+ const playReverse = (start = framePositions.length - 1, end = 0) => {
114
+ if (isAnimating) {
115
+ animation.abort()
116
+ }
117
+
118
+ animate(start, end)
119
+ }
120
+
121
+ const pause = () => {
122
+ if (isAnimating && animation) {
123
+ animation.abort()
124
+ }
125
+ }
126
+
127
+ const getFrameFromProgress = (progress: number) =>
128
+ clamp(Math.trunc(progress), 0, framePositions.length - 1)
129
+
130
+ const toFrame = (frame: number) => {
131
+ currentFrame = getFrameFromProgress(frame)
132
+ draw()
133
+ }
134
+
135
+ onMounted(async () => {
136
+ ctx = canvasEl.value.getContext('2d')
137
+ spritesheet = await loadImage(spritesheetPath)
138
+
139
+ emits('ready')
140
+
141
+ // Show initial frame
142
+ draw()
143
+ })
144
+
145
+ defineExpose({
146
+ play,
147
+ playReverse,
148
+ pause,
149
+ toFrame,
150
+ })
151
+ </script>
152
+
153
+ <template>
154
+ <div
155
+ class="sprite-animation"
156
+ :style="{
157
+ width: `${width}px` || 'auto',
158
+ height: `${height}px` || 'auto',
159
+ }"
160
+ >
161
+ <canvas
162
+ ref="canvas"
163
+ :width="canvasWidth * devicePixelRatio"
164
+ :height="canvasHeight * devicePixelRatio"
165
+ ></canvas>
166
+ </div>
167
+ </template>
168
+
169
+ <style scoped lang="scss" src="./sprite-animation.scss"></style>
@@ -21,3 +21,7 @@
21
21
  .progress-bar-label {
22
22
  @include a.type(100);
23
23
  }
24
+
25
+ .cell-progress-bar__progress-bar {
26
+ max-width: a.rem(78);
27
+ }
@@ -1,12 +1,15 @@
1
1
  <script setup lang="ts">
2
2
  import UIcon from '../../elements/icon/u-icon.vue'
3
3
  import UTooltip from '../tooltip/u-tooltip.vue'
4
+ import { UBadge } from '../'
5
+ import { Badge } from '../badge/u-badge.vue'
4
6
  import { TableCellIconColor } from './table.type'
5
7
 
6
8
  interface IconItem {
7
9
  icon: string
8
10
  title: string
9
11
  color: TableCellIconColor
12
+ badge: Badge
10
13
  }
11
14
 
12
15
  interface Props {
@@ -22,13 +25,15 @@ const isColorKeyword = (str) => Object.values(TableCellIconColor).includes(str)
22
25
  <div class="cell-icon-group">
23
26
  <template v-for="(item, idx) in icons" :key="idx">
24
27
  <UTooltip :title="item.title">
25
- <UIcon
26
- :name="item.icon"
27
- :class="{ [`icon-color-${item.color}`]: isColorKeyword(item.color) }"
28
- :style="{
29
- color: !isColorKeyword(item.color) ? item.color : false,
30
- }"
31
- ></UIcon>
28
+ <UBadge :show="!!item.badge" v-bind="item.badge">
29
+ <UIcon
30
+ :name="item.icon"
31
+ :class="{ [`icon-color-${item.color}`]: isColorKeyword(item.color) }"
32
+ :style="{
33
+ color: !isColorKeyword(item.color) ? item.color : false,
34
+ }"
35
+ ></UIcon>
36
+ </UBadge>
32
37
  </UTooltip>
33
38
  </template>
34
39
  </div>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import UProgressBar from '../progress-bar/u-progress-bar.vue'
2
+ import { UProgressBar } from '../'
3
3
 
4
4
  interface Props {
5
5
  label?: string
@@ -13,10 +13,10 @@ const { label = '', labelPosition = 'top' } = defineProps<Props>()
13
13
  <template>
14
14
  <div :class="['cell-progress-bar', `label-position-${labelPosition}`]">
15
15
  <p v-if="label" class="progress-bar-label">{{ label }}</p>
16
- <UProgressBar :value="value"></UProgressBar>
16
+ <div class="cell-progress-bar__progress-bar">
17
+ <UProgressBar :value="value"></UProgressBar>
18
+ </div>
17
19
  </div>
18
20
  </template>
19
21
 
20
- <style scoped lang="scss">
21
- @use './cell-progress-bar.scss';
22
- </style>
22
+ <style scoped lang="scss" src="./cell-progress-bar.scss"></style>
@@ -1,58 +1,62 @@
1
1
  @use '../../base/abstracts' as a;
2
2
 
3
- .wizard-text-block {
4
- .wizard-text-block__title {
3
+ .text-block {
4
+ .text-block__title {
5
5
  @include a.type(800, strong);
6
6
 
7
- + .wizard-text-block__text {
7
+ + .text-block__text {
8
8
  margin-top: var(--e-space-4);
9
9
  }
10
10
  }
11
11
 
12
- .wizard-text-block__title--small {
12
+ .text-block__title--small {
13
13
  @include a.type(500, strong);
14
14
  }
15
15
 
16
- .wizard-text-block__text {
16
+ .text-block__text {
17
17
  @include a.type(300);
18
18
  }
19
19
 
20
20
  @include a.bp(lg) {
21
- .wizard-text-block__title {
21
+ .text-block__title {
22
22
  @include a.type(700, strong);
23
23
 
24
- + .wizard-text-block__text {
24
+ + .text-block__text {
25
25
  margin-top: var(--e-space-3);
26
26
  }
27
27
  }
28
28
  }
29
29
 
30
30
  // Modifiers
31
- &.wizard-text-block--sub {
32
- .wizard-text-block__title {
31
+ &.text-block--sub {
32
+ .text-block__title {
33
33
  @include a.type(300, strong);
34
34
 
35
- + .wizard-text-block__text {
35
+ + .text-block__text {
36
36
  margin-top: var(--e-space-2);
37
37
  }
38
38
  }
39
39
 
40
- .wizard-text-block__text {
40
+ .text-block__text {
41
41
  @include a.type(300);
42
42
  }
43
43
 
44
44
  @include a.bp(lg) {
45
- .wizard-text-block__title {
45
+ .text-block__title {
46
46
  @include a.type(200, strong);
47
47
 
48
- + .wizard-text-block__text {
48
+ + .text-block__text {
49
49
  margin-top: var(--e-space-2);
50
50
  }
51
51
  }
52
52
 
53
- .wizard-text-block__text {
53
+ .text-block__text {
54
54
  @include a.type(200);
55
55
  }
56
56
  }
57
57
  }
58
+
59
+ &.centered {
60
+ text-align: center;
61
+ }
58
62
  }
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { URichtext } from '../'
3
+
2
4
  interface Props {
3
5
  variant: 'lead' | 'sub'
4
6
  title?: string
@@ -6,21 +8,25 @@ interface Props {
6
8
  centered?: boolean
7
9
  }
8
10
 
9
- const { title = '', text = '', centered = false } = defineProps<Props>()
11
+ const { title = '', text = '' } = defineProps<Props>()
10
12
  </script>
11
13
 
12
14
  <template>
13
- <div :class="['wizard-text-block', `wizard-text-block--${variant}`, { centered }]">
14
- <h2 v-if="title" class="wizard-text-block__title" v-html="title" />
15
+ <div :class="['text-block', `text-block--${variant}`, { centered }]">
16
+ <h2 v-if="$slots.title || title" class="text-block__title">
17
+ <slot name="title">
18
+ <span v-html="title"></span>
19
+ </slot>
20
+ </h2>
15
21
 
16
- <div v-if="text" class="wizard-text-block__text richtext" v-html="text" />
22
+ <div v-if="$slots.text || text" class="text-block__text">
23
+ <URichtext>
24
+ <slot name="text">
25
+ <div v-html="text" />
26
+ </slot>
27
+ </URichtext>
28
+ </div>
17
29
  </div>
18
30
  </template>
19
31
 
20
- <style scoped lang="scss">
21
- @use './text-block.scss';
22
-
23
- .centered {
24
- text-align: center;
25
- }
26
- </style>
32
+ <style scoped lang="scss" src="./text-block.scss"></style>