@energie360/ui-library 0.1.32 → 0.1.34

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 (63) hide show
  1. package/base/_resets.scss +4 -0
  2. package/components/badge/badge.scss +11 -4
  3. package/components/badge/u-badge.vue +3 -13
  4. package/components/button-group/button-group.scss +12 -0
  5. package/components/button-group/u-button-group.vue +15 -0
  6. package/components/card-amount/u-card-amount.vue +1 -1
  7. package/components/card-amount-illustrated/u-card-amount-illustrated.vue +1 -1
  8. package/components/card-contact/u-card-contact.vue +1 -1
  9. package/components/card-highlight/u-card-highlight.vue +2 -2
  10. package/components/card-price-list/u-card-price-list.vue +2 -2
  11. package/components/card-statistic/card-statistic.scss +31 -0
  12. package/components/card-statistic/u-card-statistic.vue +34 -0
  13. package/components/chip/chip.scss +1 -0
  14. package/components/chip/u-chip.vue +1 -0
  15. package/components/data-card/data-card.scss +15 -0
  16. package/components/data-card/u-data-card.vue +6 -1
  17. package/components/download-list-item/u-download-list-item.vue +1 -0
  18. package/components/empty/empty.scss +27 -0
  19. package/components/empty/u-empty.vue +32 -0
  20. package/components/hint/hint.scss +106 -35
  21. package/components/hint/u-hint.vue +35 -4
  22. package/components/index.js +3 -0
  23. package/components/navigation-panel-tile/navigation-panel-tile.scss +0 -18
  24. package/components/navigation-panel-tile/u-navigation-panel-tile.vue +8 -7
  25. package/components/navigation-toolbar-link/u-navigation-toolbar-link.vue +2 -2
  26. package/components/notification-item/notification-item.scss +1 -0
  27. package/components/progress-avatar/u-progress-avatar.vue +1 -1
  28. package/components/slider/u-slider.vue +1 -1
  29. package/components/slider-progress-animation/u-slider-progress-animation.vue +1 -1
  30. package/components/table/table-cell.scss +10 -0
  31. package/components/table/u-cell-icon-group.vue +1 -1
  32. package/components/table/u-cell-progress-bar.vue +1 -1
  33. package/components/table/u-table-cell.vue +3 -0
  34. package/components/text-block/u-text-block.vue +1 -1
  35. package/components/welcome/butterfly-sprite.json +9 -0
  36. package/components/welcome/butterfly-sprite.png +0 -0
  37. package/components/welcome/u-welcome.vue +69 -1
  38. package/components/welcome/welcome.scss +10 -0
  39. package/dist/base-style.css +6 -2
  40. package/dist/base-style.css.map +1 -1
  41. package/dist/elements/form.css +1 -1
  42. package/dist/layout/form-grid.css.map +1 -1
  43. package/elements/button/u-button.vue +2 -1
  44. package/elements/form/form.scss +1 -1
  45. package/i18n/i18n.ts +22 -20
  46. package/layout/form-grid/form-grid.scss +2 -0
  47. package/layout/form-grid/u-form-col.vue +1 -1
  48. package/layout/form-grid/u-form-fieldset.vue +36 -0
  49. package/layout/form-grid/u-form-row.vue +29 -3
  50. package/layout/form-grid/u-form-wrapper.vue +7 -0
  51. package/layout/index.js +2 -0
  52. package/layout/portal-block/portal-block.scss +36 -3
  53. package/layout/portal-block/u-portal-block.vue +9 -3
  54. package/modules/dialog/dialog.scss +34 -24
  55. package/modules/dialog/u-dialog.vue +14 -17
  56. package/modules/footer/footer.scss +30 -4
  57. package/modules/login-animation/login-animation.scss +1 -3
  58. package/modules/login-animation/u-login-animation.vue +11 -12
  59. package/modules/navigation-toolbar-top/u-navigation-toolbar-top.vue +24 -2
  60. package/package.json +9 -9
  61. package/utils/http/url.js +25 -0
  62. package/utils/vue/helpers.ts +27 -0
  63. package/wizard/wizard-outro/u-wizard-outro.vue +3 -0
package/base/_resets.scss CHANGED
@@ -58,3 +58,7 @@ fieldset {
58
58
  margin: 0;
59
59
  border: 0;
60
60
  }
61
+
62
+ legend {
63
+ padding: 0;
64
+ }
@@ -31,11 +31,18 @@ $ease-out-bounce: cubic-bezier(0.674, 1.901, 0.651, 0.744);
31
31
  }
32
32
 
33
33
  .badge__sup.number {
34
- width: 16px;
34
+ min-width: 16px;
35
35
  height: 16px;
36
36
  font-size: 10px;
37
37
  font-weight: bold;
38
- line-height: 1;
38
+ line-height: 10px;
39
+ letter-spacing: 0;
40
+ border-radius: 24px;
41
+ text-align: center;
42
+ padding: 0 2px;
43
+ top: var(--top, -5px);
44
+ right: var(--right, 3px);
45
+ transform: translateX(50%);
39
46
  }
40
47
 
41
48
  .badge__sup.state {
@@ -48,8 +55,8 @@ $ease-out-bounce: cubic-bezier(0.674, 1.901, 0.651, 0.744);
48
55
  }
49
56
 
50
57
  .badge__sup.dot {
51
- top: var(--top, -3px);
52
- right: var(--right, -3px);
58
+ top: var(--top, -1px);
59
+ right: var(--right, -1px);
53
60
  width: 8px;
54
61
  height: 8px;
55
62
  border-radius: 100%;
@@ -2,11 +2,9 @@
2
2
  export interface Badge {
3
3
  color?: string
4
4
  dot?: boolean
5
- type?: 'default' | 'success' | 'error' | 'warning' | 'info'
6
5
  value?: number
7
6
  state?: '' | 'inactive'
8
7
  show?: boolean
9
- border?: boolean
10
8
  top?: number
11
9
  right?: number
12
10
  }
@@ -17,7 +15,6 @@ const {
17
15
  top = 0,
18
16
  right = 0,
19
17
  color = 'var(--e-c-mono-900)',
20
- type = 'default',
21
18
  show = true,
22
19
  } = defineProps<Badge>()
23
20
  </script>
@@ -32,23 +29,16 @@ const {
32
29
  >
33
30
  <slot></slot>
34
31
 
35
- <sup
36
- v-if="dot"
37
- class="badge__sup dot"
38
- :class="[`type-${type}`, { border }]"
39
- :style="{ backgroundColor: color }"
40
- ></sup>
32
+ <sup v-if="dot" class="badge__sup dot" :style="{ backgroundColor: color }"></sup>
41
33
 
42
34
  <sup
43
35
  v-else-if="state"
44
36
  class="badge__sup state"
45
- :class="[state, { border }]"
37
+ :class="[state]"
46
38
  :style="{ backgroundColor: color }"
47
39
  ></sup>
48
40
 
49
- <sup v-else class="badge__sup number" :class="{ border }" :style="{ backgroundColor: color }">{{
50
- value
51
- }}</sup>
41
+ <sup v-else class="badge__sup number" :style="{ backgroundColor: color }">{{ value }}</sup>
52
42
  </span>
53
43
  </template>
54
44
 
@@ -0,0 +1,12 @@
1
+ // TODO: Check with Design if spacings are ok.
2
+ .button-group {
3
+ display: flex;
4
+ flex-wrap: wrap;
5
+ column-gap: var(--e-space-2);
6
+ row-gap: var(--e-space-4);
7
+ }
8
+
9
+ .button-group.stacked {
10
+ flex-direction: column;
11
+ align-items: flex-start;
12
+ }
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ interface Props {
3
+ type?: 'inline' | 'stacked'
4
+ }
5
+
6
+ const { type = 'inline' } = defineProps<Props>()
7
+ </script>
8
+
9
+ <template>
10
+ <div :class="['button-group', type]">
11
+ <slot />
12
+ </div>
13
+ </template>
14
+
15
+ <style scoped lang="scss" src="./button-group.scss"></style>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { UProgressBar } from '../'
2
+ import UProgressBar from '../progress-bar/u-progress-bar.vue'
3
3
 
4
4
  interface Props {
5
5
  progress: number
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { UProgressBar } from '../'
2
+ import UProgressBar from '../progress-bar/u-progress-bar.vue'
3
3
  import { useTemplateRef, inject, watch, ref, onMounted, onUnmounted } from 'vue'
4
4
  import { Image } from '../../elements/types'
5
5
  import '@lottiefiles/lottie-player'
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { Image } from '../../elements/types'
3
- import { URichtext } from '../'
3
+ import URichtext from '../richtext/u-richtext.vue'
4
4
 
5
5
  interface Props {
6
6
  name?: string
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  import { Chip } from '../chip/u-chip.vue'
3
3
  import { Image } from '../../elements/types'
4
- import { UIcon } from '../../elements'
5
- import { UChip } from '../'
4
+ import UIcon from '../../elements/icon/u-icon.vue'
5
+ import UChip from '../chip/u-chip.vue'
6
6
 
7
7
  interface Props {
8
8
  title?: string
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { UIcon } from '../../elements'
3
- import { UTooltip } from '../'
2
+ import UIcon from '../../elements/icon/u-icon.vue'
3
+ import UTooltip from '../tooltip/u-tooltip.vue'
4
4
 
5
5
  interface PriceItem {
6
6
  name: string
@@ -0,0 +1,31 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .card-statistic {
4
+ display: flex;
5
+ justify-content: space-between;
6
+ column-gap: var(--e-space-2);
7
+ }
8
+
9
+ .card-statistic__image {
10
+ width: 80px;
11
+ height: 80px;
12
+ flex: 0 0 auto;
13
+ }
14
+
15
+ .card-statistic__content {
16
+ display: flex;
17
+ flex-direction: column;
18
+ row-gap: var(--e-space-2);
19
+ }
20
+
21
+ .card-statistic__label {
22
+ @include a.type(200);
23
+
24
+ order: 2;
25
+ }
26
+
27
+ .card-statistic__value {
28
+ @include a.type(700, strong);
29
+
30
+ order: 1;
31
+ }
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import { Image } from '../../elements/types'
3
+ import { hasSlotContent } from '../../utils/vue/helpers'
4
+
5
+ interface Props {
6
+ label?: string
7
+ value?: string
8
+ image?: Image
9
+ }
10
+
11
+ defineProps<Props>()
12
+ </script>
13
+
14
+ <template>
15
+ <div class="card-statistic">
16
+ <dl class="card-statistic__content">
17
+ <dt class="card-statistic__label">
18
+ <slot name="label">{{ label }}</slot>
19
+ </dt>
20
+
21
+ <dd class="card-statistic__value">
22
+ <slot name="value">{{ value }}</slot>
23
+ </dd>
24
+ </dl>
25
+
26
+ <div v-if="image || hasSlotContent($slots.image)" class="card-statistic__image">
27
+ <slot name="image">
28
+ <img v-bind="image" />
29
+ </slot>
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <style scoped lang="scss" src="./card-statistic.scss"></style>
@@ -36,6 +36,7 @@
36
36
  }
37
37
 
38
38
  .chip__icon {
39
+ margin-left: calc(var(--e-space-1) * -1);
39
40
  color: var(--chip-icon-color);
40
41
  }
41
42
 
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ // TODO: Rename this component. It's not really a 'chip'.
2
3
  import { UIcon } from '../../elements'
3
4
 
4
5
  export interface Chip {
@@ -24,6 +24,11 @@
24
24
 
25
25
  .data-card__value {
26
26
  @include a.type(100);
27
+
28
+ &:has(.data-card__dot) {
29
+ display: flex;
30
+ column-gap: var(--e-space-2);
31
+ }
27
32
  }
28
33
 
29
34
  .data-card__ctas {
@@ -32,3 +37,13 @@
32
37
  margin-top: var(--e-space-4);
33
38
  line-height: 0;
34
39
  }
40
+
41
+ .data-card__dot {
42
+ align-self: center;
43
+ flex: 0 0 auto;
44
+ display: block;
45
+ width: 8px;
46
+ height: 8px;
47
+ border-radius: 100%;
48
+ background-color: transparent;
49
+ }
@@ -3,6 +3,7 @@
3
3
  interface dataItem {
4
4
  heading: string
5
5
  value: string
6
+ dotColor?: string
6
7
  }
7
8
 
8
9
  interface Props {
@@ -23,7 +24,11 @@ defineProps<Props>()
23
24
  <slot>
24
25
  <div v-for="(item, idx) in data" :key="idx">
25
26
  <dt class="data-card__heading">{{ item.heading }}</dt>
26
- <dd class="data-card__value" v-html="item.value"></dd>
27
+ <dd v-if="item.dotColor" class="data-card__value">
28
+ <span class="data-card__dot" :style="{ backgroundColor: item.dotColor }"></span>
29
+ <span class="data-card__value" v-html="item.value" />
30
+ </dd>
31
+ <dd v-else class="data-card__value" v-html="item.value"></dd>
27
32
  </div>
28
33
  </slot>
29
34
  </dl>
@@ -66,6 +66,7 @@ defineExpose({ click })
66
66
  <td class="download-list-item__cell cta">
67
67
  <component
68
68
  :is="url ? 'a' : 'button'"
69
+ v-bind="$attrs"
69
70
  ref="link"
70
71
  class="download-list-item__link"
71
72
  :href="url"
@@ -0,0 +1,27 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .empty {
4
+ text-align: center;
5
+ }
6
+
7
+ .empty__image {
8
+ margin: 0 auto var(--e-space-6);
9
+ width: a.rem(120);
10
+ height: a.rem(120);
11
+
12
+ > img {
13
+ object-fit: cover;
14
+ width: 100%;
15
+ height: 100%;
16
+ }
17
+ }
18
+
19
+ .empty__title {
20
+ @include a.type(600);
21
+
22
+ margin-bottom: var(--e-space-6);
23
+ }
24
+
25
+ .empty__text {
26
+ @include a.type(300, strong);
27
+ }
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import { hasSlotContent } from '../../utils/vue/helpers'
3
+
4
+ interface Props {
5
+ title?: string
6
+ text?: string
7
+ }
8
+
9
+ defineProps<Props>()
10
+ </script>
11
+
12
+ <template>
13
+ <div class="empty">
14
+ <div class="empty__image">
15
+ <slot name="image">
16
+ <img src="/static/ui-assets/images/search.svg" alt="" />
17
+ </slot>
18
+ </div>
19
+
20
+ <p v-if="title || hasSlotContent($slots.title)" class="empty__title">
21
+ <slot name="title">
22
+ {{ title }}
23
+ </slot>
24
+ </p>
25
+
26
+ <p v-if="text || hasSlotContent($slots.text)" class="empty__text">
27
+ <slot name="text"> {{ text }} </slot>
28
+ </p>
29
+ </div>
30
+ </template>
31
+
32
+ <style scoped lang="scss" src="./empty.scss"></style>
@@ -7,10 +7,6 @@
7
7
  background-color: var(--e-c-secondary-05-100);
8
8
  color: var(--e-c-secondary-05-900);
9
9
 
10
- &::before {
11
- background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1Zm1-8h-2V7h2v2Z' fill='%230096DC'/%3E%3C/svg%3E");
12
- }
13
-
14
10
  .hint__richtext {
15
11
  margin-left: var(--e-space-9);
16
12
 
@@ -19,6 +15,10 @@
19
15
  }
20
16
  }
21
17
 
18
+ .hint__icon {
19
+ color: var(--e-c-secondary-05-500);
20
+ }
21
+
22
22
  // override some richtext styles.
23
23
  .richtext {
24
24
  a {
@@ -37,10 +37,6 @@
37
37
  background-color: var(--e-c-signal-02-100);
38
38
  color: var(--e-c-signal-02-900);
39
39
 
40
- &::before {
41
- background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 21 12 2l11 19H1Zm11-3c.283 0 .52-.096.713-.288A.968.968 0 0 0 13 17a.968.968 0 0 0-.287-.712A.968.968 0 0 0 12 16a.968.968 0 0 0-.713.288A.968.968 0 0 0 11 17c0 .283.096.52.287.712.192.192.43.288.713.288Zm-1-3h2v-5h-2v5Z' fill='%23FF9800'/%3E%3C/svg%3E");
42
- }
43
-
44
40
  .hint__richtext {
45
41
  margin-left: var(--e-space-9);
46
42
 
@@ -49,6 +45,10 @@
49
45
  }
50
46
  }
51
47
 
48
+ .hint__icon {
49
+ color: var(--e-c-signal-02-500);
50
+ }
51
+
52
52
  // override some richtext styles.
53
53
  .richtext {
54
54
  a {
@@ -76,17 +76,18 @@
76
76
  border-left-color: var(--e-c-mono-700);
77
77
  color: var(--e-c-mono-900);
78
78
 
79
- &::before {
80
- background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='m12.86 3.404-.81.81 3.352 3.352.81-.81-3.353-3.352Zm.707-1.697a1 1 0 0 0-1.415 0l-1.8 1.8a1 1 0 0 0-.01 1.404L6.952 8.303a1 1 0 0 0-1.404.01l-1.84 1.84a1 1 0 0 0 0 1.414l4.342 4.342a1 1 0 0 0 1.414 0l1.84-1.84a1 1 0 0 0 0-1.414l-.092-.092.93-.93L20.6 20l1.4-1.4-8.46-8.366 1.063-1.062.091.091a1 1 0 0 0 1.415 0l1.8-1.8a1 1 0 0 0 0-1.414l-4.342-4.342ZM6.253 10.01l-.85.85 3.352 3.352.85-.85-3.352-3.352Zm1.975-.581 3.235-3.235L13.32 8.05l-3.235 3.235L8.23 9.429ZM16 21H4v-2h12v2Z' fill='%236B6B6B'/%3E%3C/svg%3E");
81
- top: 0;
82
- left: calc(
83
- -24px - 12px - 4px
84
- ); // 24px: icon width, 12px: distance to box, 4px: additonal border-width
79
+ .hint__label,
80
+ .hint__richtext {
81
+ margin-left: 0;
85
82
  }
86
83
 
87
- > p,
88
- .richtext {
89
- margin-left: 0;
84
+ &.no-label .hint__label {
85
+ height: 0;
86
+ min-height: 0;
87
+
88
+ @include a.bp(lg) {
89
+ margin-top: -8px;
90
+ }
90
91
  }
91
92
 
92
93
  .hint__link {
@@ -96,13 +97,22 @@
96
97
  }
97
98
  }
98
99
 
100
+ .hint__icon {
101
+ top: 0;
102
+ left: calc(
103
+ -24px - 12px - 4px
104
+ ); // 24px: icon width, 12px: distance to box, 4px: additonal border-width
105
+
106
+ color: var(--e-c-mono-700);
107
+ }
108
+
99
109
  @include a.bp(lg) {
100
110
  margin-top: calc(4px + 4px + 24px);
101
111
  border: 1px solid var(--e-c-mono-500);
102
112
  border-top-width: 4px;
103
113
  border-top-color: var(--e-c-mono-700);
104
114
 
105
- &::before {
115
+ .hint__icon {
106
116
  left: 0;
107
117
  top: calc(
108
118
  -24px - 4px - 4px
@@ -115,10 +125,42 @@
115
125
  background-color: var(--e-c-signal-03-100);
116
126
  color: var(--e-c-signal-03-900);
117
127
 
118
- &::before {
119
- background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.1396 0C15.4048 0 15.6592 0.105542 15.8467 0.292969L21.707 6.15332C21.8945 6.34084 22 6.59522 22 6.86035V15.1396C22 15.4048 21.8945 15.6592 21.707 15.8467L15.8467 21.707C15.6592 21.8945 15.4048 22 15.1396 22H6.86035C6.59522 22 6.34084 21.8945 6.15332 21.707L0.292969 15.8467C0.105542 15.6592 0 15.4048 0 15.1396V6.86035C0 6.59522 0.105542 6.34084 0.292969 6.15332L6.15332 0.292969C6.34084 0.105542 6.59522 0 6.86035 0H15.1396ZM11 14C10.4477 14 10 14.4477 10 15C10 15.5523 10.4477 16 11 16H11.0098C11.5621 16 12.0098 15.5523 12.0098 15C12.0098 14.4477 11.5621 14 11.0098 14H11ZM11 6C10.4477 6 10 6.44772 10 7V11C10 11.5523 10.4477 12 11 12C11.5523 12 12 11.5523 12 11V7C12 6.44772 11.5523 6 11 6Z' fill='%23FF0C3E'/%3E%3C/svg%3E");
128
+ .hint__richtext {
129
+ margin-left: var(--e-space-9);
130
+
131
+ @include a.bp(lg) {
132
+ margin-left: 0;
133
+ }
120
134
  }
121
135
 
136
+ // override some richtext styles.
137
+ .richtext {
138
+ a {
139
+ color: inherit;
140
+
141
+ &:active,
142
+ &:hover {
143
+ text-decoration-color: var(--e-c-signal-03-100);
144
+ }
145
+ }
146
+ }
147
+
148
+ .hint__link {
149
+ &:active,
150
+ &:hover {
151
+ text-decoration-color: var(--e-c-signal-03-100);
152
+ }
153
+ }
154
+
155
+ .hint__icon {
156
+ color: var(--e-c-signal-03-500);
157
+ }
158
+ }
159
+
160
+ @mixin type-task {
161
+ background-color: var(--e-c-secondary-03-100);
162
+ color: var(--e-c-signal-03-900);
163
+
122
164
  .hint__richtext {
123
165
  margin-left: var(--e-space-9);
124
166
 
@@ -127,6 +169,10 @@
127
169
  }
128
170
  }
129
171
 
172
+ .hint__icon {
173
+ color: var(--e-c-secondary-03-500);
174
+ }
175
+
130
176
  // override some richtext styles.
131
177
  .richtext {
132
178
  a {
@@ -160,7 +206,6 @@
160
206
 
161
207
  display: inline-block;
162
208
  color: inherit;
163
- margin-left: var(--e-space-2);
164
209
 
165
210
  &:active,
166
211
  &:hover {
@@ -169,11 +214,19 @@
169
214
 
170
215
  @include a.bp(lg) {
171
216
  display: block;
172
- margin-left: 0;
173
217
  }
174
218
  }
175
219
 
176
220
  .hint__label {
221
+ @include a.type(200, strong);
222
+
223
+ margin-left: var(--e-space-9);
224
+
225
+ @include a.bp(lg) {
226
+ margin-left: var(--e-space-7);
227
+ min-height: 24px;
228
+ }
229
+
177
230
  + .hint__richtext {
178
231
  margin-top: var(--e-space-1);
179
232
 
@@ -183,29 +236,35 @@
183
236
  }
184
237
  }
185
238
 
186
- &::before {
187
- content: '';
188
- position: absolute;
189
- top: var(--e-space-5);
190
- left: var(--e-space-4);
191
- width: a.rem(24);
192
- height: a.rem(24);
193
- }
194
-
195
- > p {
196
- @include a.type(200, strong);
239
+ .hint__label-text + .hint__link {
240
+ margin-left: var(--e-space-2);
197
241
 
198
- margin-left: var(--e-space-9);
242
+ @include a.bp(lg) {
243
+ margin-left: 0;
244
+ }
199
245
  }
200
246
 
201
247
  @include a.bp(lg) {
202
248
  padding: var(--e-space-4);
203
249
 
204
- &::before {
250
+ .hint__icon {
205
251
  top: var(--e-space-4);
206
252
  }
207
253
  }
208
254
 
255
+ // States
256
+ &.no-label {
257
+ .hint__label {
258
+ // This gives same layout as when `.hint__label` was removed from DOM.
259
+ // We can't remove it because wew need this element for mobile layout.
260
+ margin-top: -4px;
261
+
262
+ @include a.bp(lg) {
263
+ margin-top: 0;
264
+ }
265
+ }
266
+ }
267
+
209
268
  // Modifiers
210
269
  &.hint--warning {
211
270
  @include type-warning;
@@ -218,4 +277,16 @@
218
277
  &.hint--error {
219
278
  @include type-error;
220
279
  }
280
+
281
+ &.hint--task {
282
+ @include type-task;
283
+ }
284
+ }
285
+
286
+ .hint__icon {
287
+ position: absolute;
288
+ top: var(--e-space-5);
289
+ left: var(--e-space-4);
290
+ width: a.rem(24);
291
+ height: a.rem(24);
221
292
  }
@@ -1,21 +1,43 @@
1
1
  <script setup lang="ts">
2
- import { URichtext } from '../'
2
+ import URichtext from '../richtext/u-richtext.vue'
3
3
  import { Cta } from '../../elements/types'
4
+ import { hasSlotContent } from '../../utils/vue/helpers'
5
+ import UIcon from '../../elements/icon/u-icon.vue'
4
6
 
5
7
  interface Props {
6
- type?: 'neutral' | 'warning' | 'legal' | 'error'
8
+ type?: 'neutral' | 'warning' | 'legal' | 'error' | 'task'
7
9
  label?: string
8
10
  link?: Cta
9
11
  text?: string
10
12
  }
11
13
 
12
14
  const { label = '', link = undefined, text = '', type = 'neutral' } = defineProps<Props>()
15
+
16
+ // default mapping 'type' -> icon
17
+ const iconMap = {
18
+ neutral: 'info-circle-filled',
19
+ warning: 'alert-triangle-filled',
20
+ legal: 'legal',
21
+ error: 'alert-octagon-filled',
22
+ task: 'check-circle-filled',
23
+ }
13
24
  </script>
14
25
 
15
26
  <template>
16
- <div :class="['hint', `hint--${type}`]">
27
+ <div
28
+ :class="[
29
+ 'hint',
30
+ `hint--${type}`,
31
+ { 'no-label': !label && !hasSlotContent($slots.label) && !link },
32
+ ]"
33
+ >
34
+ <span class="hint__icon">
35
+ <slot name="icon"> <UIcon :name="iconMap[type]" /> </slot>
36
+ </span>
17
37
  <p class="hint__label">
18
- <slot name="label">{{ label }}</slot>
38
+ <span v-if="label || hasSlotContent($slots.label)" class="hint__label-text">
39
+ <slot name="label">{{ label }}</slot>
40
+ </span>
19
41
 
20
42
  <a v-if="link" :href="link.href" :target="link.target" class="hint__link">
21
43
  {{ link.label }}
@@ -68,4 +90,13 @@ const { label = '', link = undefined, text = '', type = 'neutral' } = defineProp
68
90
  }
69
91
  }
70
92
  }
93
+
94
+ .hint--error {
95
+ .hint__richtext a {
96
+ &:active,
97
+ &:hover {
98
+ text-decoration-color: var(--e-c-secondary-03-100);
99
+ }
100
+ }
101
+ }
71
102
  </style>
@@ -72,3 +72,6 @@ export { default as UNotificationItem } from './notification-item/u-notification
72
72
  export { default as UNotificationList } from './notification-list/u-notification-list.vue'
73
73
  export { default as UDefinitionList } from './definition-list/u-definition-list.vue'
74
74
  export { default as UDefinitionListItem } from './definition-list-item/u-definition-list-item.vue'
75
+ export { default as UCardStatistic } from './card-statistic/u-card-statistic.vue'
76
+ export { default as UEmpty } from './empty/u-empty.vue'
77
+ export { default as UButtonGroup } from './button-group/u-button-group.vue'