@energie360/ui-library 0.1.17 → 0.1.19

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 (100) hide show
  1. package/base/_input-resets.scss +3 -0
  2. package/components/badge/badge.scss +56 -0
  3. package/components/badge/u-badge.vue +47 -0
  4. package/components/card-contact/card-contact.scss +39 -0
  5. package/components/card-contact/u-card-contact.vue +44 -0
  6. package/components/card-cta-bar/card-cta-bar.scss +4 -0
  7. package/components/card-cta-bar/u-card-cta-bar.vue +24 -0
  8. package/components/card-cta-header/u-card-cta-header.vue +10 -7
  9. package/components/card-footer/u-card-footer.vue +5 -3
  10. package/components/card-group/u-card-group.vue +1 -1
  11. package/components/card-header/card-header.scss +29 -4
  12. package/components/card-header/u-card-header.vue +22 -3
  13. package/components/card-highlight/card-highlight.scss +87 -0
  14. package/components/card-highlight/u-card-highlight.vue +54 -0
  15. package/components/card-price-list/card-price-list.scss +39 -0
  16. package/components/card-price-list/u-card-price-list.vue +37 -0
  17. package/components/card-section/card-section.scss +21 -1
  18. package/components/card-section/u-card-section.vue +9 -1
  19. package/components/chip/chip.scss +25 -0
  20. package/components/chip/u-chip.vue +31 -0
  21. package/components/data-card/data-card.scss +34 -0
  22. package/components/data-card/u-data-card.vue +49 -0
  23. package/components/data-card-group/data-card-group.scss +12 -0
  24. package/components/data-card-group/u-data-card-group.vue +7 -0
  25. package/components/download-list/download-list.scss +58 -0
  26. package/components/download-list/u-download-list.vue +44 -0
  27. package/components/download-list-item/download-list-item.scss +267 -0
  28. package/components/download-list-item/u-download-list-item.vue +65 -0
  29. package/components/file-upload/file-list.scss +68 -0
  30. package/components/file-upload/file-upload.scss +119 -0
  31. package/components/file-upload/u-file-list.vue +55 -0
  32. package/components/file-upload/u-file-upload.vue +220 -0
  33. package/components/hint/hint.scss +67 -6
  34. package/components/hint/u-hint.vue +11 -1
  35. package/components/index.js +16 -0
  36. package/components/progress-avatar/u-progress-avatar.vue +27 -3
  37. package/components/rating/rating.scss +76 -0
  38. package/components/rating/u-rating.vue +79 -0
  39. package/components/search-group/search-group.scss +59 -0
  40. package/components/search-group/u-search-group.vue +32 -0
  41. package/components/skeleton-loader/skeleton-loader.scss +39 -0
  42. package/components/skeleton-loader/u-skeleton-loader.vue +28 -0
  43. package/components/table/cell-ctas.scss +1 -7
  44. package/components/table/cell-icon-text.scss +15 -4
  45. package/components/table/table-cell.mixins.scss +3 -2
  46. package/components/table/table-cell.scss +5 -0
  47. package/components/table/table-heading.scss +7 -0
  48. package/components/table/u-cell-ctas.vue +15 -6
  49. package/components/table/u-cell-icon-text.vue +13 -5
  50. package/components/table/u-table-cell.vue +3 -1
  51. package/components/table/u-table-heading.vue +2 -1
  52. package/components/tabs/tabs.scss +10 -1
  53. package/components/tabs/u-tabs.vue +64 -25
  54. package/dist/base-style.css +3 -0
  55. package/dist/base-style.css.map +1 -1
  56. package/dist/layout/split.css.map +1 -1
  57. package/elements/button/_button-plain-small-spaceless.scss +10 -0
  58. package/elements/button/button.scss +32 -0
  59. package/elements/button/u-button.vue +47 -4
  60. package/elements/form-field/form-field-base.scss +4 -0
  61. package/elements/numeric-stepper/u-numeric-stepper.vue +35 -12
  62. package/elements/select/u-select.vue +6 -6
  63. package/elements/text-field/text-field.scss +15 -0
  64. package/elements/text-field/text-field.types.ts +1 -0
  65. package/elements/text-field/u-text-field.vue +27 -6
  66. package/elements/toggle-switch/toggle-switch-small.scss +10 -0
  67. package/elements/toggle-switch/toggle-switch.scss +25 -21
  68. package/elements/toggle-switch/u-toggle-switch.vue +22 -12
  69. package/i18n/i18n.ts +40 -0
  70. package/layout/container/container.scss +18 -0
  71. package/layout/index.js +4 -1
  72. package/layout/portal/portal.scss +35 -7
  73. package/layout/portal/u-portal.vue +33 -4
  74. package/layout/portal-content-aside/portal-content-aside.scss +35 -0
  75. package/layout/portal-content-aside/u-portal-content-aside.vue +15 -0
  76. package/layout/responsive-container/u-responsive-container.vue +35 -0
  77. package/layout/tile-grid/tile-grid.scss +13 -0
  78. package/layout/tile-grid/tile-item.scss +31 -0
  79. package/layout/tile-grid/u-tile-grid.vue +7 -0
  80. package/layout/tile-grid/u-tile-item.vue +15 -0
  81. package/modules/content-title/content-title.scss +43 -0
  82. package/modules/content-title/u-content-title.vue +19 -0
  83. package/modules/dialog/dialog.scss +11 -3
  84. package/modules/dialog/u-dialog.vue +8 -2
  85. package/modules/footer/footer.scss +8 -1
  86. package/modules/footer/u-footer.vue +1 -1
  87. package/modules/index.js +2 -0
  88. package/modules/search-filter/search-filter.scss +106 -0
  89. package/modules/search-filter/u-search-filter.vue +54 -0
  90. package/package.json +2 -1
  91. package/utils/array/intersect.js +7 -0
  92. package/utils/functions/breakpoint.js +4 -9
  93. package/utils/functions/format-bytes.js +17 -0
  94. package/utils/global/mime-types.js +8 -0
  95. package/utils/translations/translate.js +10 -2
  96. package/wizard/index.js +1 -0
  97. package/wizard/wizard-top-bar/u-wizard-top-bar.vue +31 -0
  98. package/wizard/wizard-top-bar/wizard-top-bar.scss +35 -0
  99. package/layout/settings/settings.scss +0 -33
  100. package/layout/settings/u-settings-layout.vue +0 -19
@@ -1,19 +1,47 @@
1
1
  @use '../../base/abstracts' as a;
2
+ @use '../../layout/container/container' as c;
2
3
 
3
4
  .portal {
4
- display: flex;
5
+ --side-nav-width: 80px;
6
+ }
7
+
8
+ .portal__side-navigation {
9
+ position: fixed;
5
10
  height: 100vh;
11
+ display: flex;
6
12
  }
7
13
 
8
14
  .portal__top-navigation {
9
15
  display: none;
10
16
  }
11
17
 
18
+ .portal__sub-navigation {
19
+ position: sticky;
20
+ top: 0;
21
+ z-index: 10;
22
+ background-color: var(--e-c-mono-00);
23
+ }
24
+
12
25
  .portal__main {
13
- flex: 1 1 auto;
14
26
  display: flex;
15
27
  flex-direction: column;
16
- overflow: auto;
28
+ padding-left: var(--side-nav-width);
29
+ min-height: 100vh;
30
+ }
31
+
32
+ .portal__content-container {
33
+ @include c.portal-content-container;
34
+
35
+ padding-top: var(--e-space-10);
36
+ padding-bottom: var(--e-space-10);
37
+
38
+ @include a.bp(lg) {
39
+ padding-top: var(--e-space-8);
40
+ }
41
+
42
+ @include a.bp(m) {
43
+ padding-top: var(--e-space-6);
44
+ }
17
45
  }
18
46
 
19
47
  .portal__footer {
@@ -21,10 +49,6 @@
21
49
  }
22
50
 
23
51
  @include a.bp(lg) {
24
- .portal {
25
- flex-direction: column;
26
- }
27
-
28
52
  .portal__top-navigation {
29
53
  display: block;
30
54
  }
@@ -32,4 +56,8 @@
32
56
  .portal__side-navigation {
33
57
  display: none;
34
58
  }
59
+
60
+ .portal__sub-navigation {
61
+ background-color: var(--e-c-mono-50);
62
+ }
35
63
  }
@@ -1,6 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { useTemplateRef, onMounted, ref } from 'vue'
3
+
4
+ const sideNavObserver = new ResizeObserver((entries) => {
5
+ for (const entry of entries) {
6
+ if (entry.target === sideNavEl.value) {
7
+ sideNavWidth.value = entry.contentBoxSize[0].inlineSize
8
+ }
9
+ }
10
+ })
11
+
12
+ const sideNavEl = useTemplateRef('sideNavigation')
13
+ const sideNavWidth = ref(0)
14
+
15
+ onMounted(() => {
16
+ sideNavObserver.observe(sideNavEl.value)
17
+ })
18
+ </script>
19
+
1
20
  <template>
2
- <div class="portal">
3
- <div class="portal__side-navigation">
21
+ <div
22
+ class="portal"
23
+ :style="{
24
+ '--side-nav-width': `${sideNavWidth}px`,
25
+ }"
26
+ >
27
+ <div ref="sideNavigation" class="portal__side-navigation">
4
28
  <slot name="side-navigation"></slot>
5
29
  </div>
6
30
 
@@ -9,7 +33,13 @@
9
33
  </div>
10
34
 
11
35
  <div class="portal__main">
12
- <slot></slot>
36
+ <div class="portal__sub-navigation">
37
+ <slot name="sub-navigation"></slot>
38
+ </div>
39
+
40
+ <div class="portal__content-container">
41
+ <slot></slot>
42
+ </div>
13
43
 
14
44
  <div class="portal__footer">
15
45
  <slot name="footer"></slot>
@@ -18,5 +48,4 @@
18
48
  </div>
19
49
  </template>
20
50
 
21
- <script setup lang="ts"></script>
22
51
  <style scoped lang="scss" src="./portal.scss"></style>
@@ -0,0 +1,35 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .portal-content-aside-container {
4
+ container-type: inline-size;
5
+
6
+ @container (width <= 1020px) {
7
+ .portal-content-aside {
8
+ display: flex;
9
+ flex-direction: column;
10
+ row-gap: var(--e-space-6);
11
+ }
12
+ }
13
+ }
14
+
15
+ .portal-content-aside {
16
+ display: grid;
17
+ grid-template-columns: auto a.rem(320);
18
+ grid-template-rows: repeat(2, auto);
19
+ grid-column-gap: var(--e-space-24);
20
+ grid-row-gap: var(--e-space-12);
21
+
22
+ // @include a.bp(lg) {
23
+ // display: flex;
24
+ // flex-direction: column;
25
+ // row-gap: var(--e-space-6);
26
+ // }
27
+ }
28
+
29
+ .portal-content-aside__main {
30
+ grid-area: 1 / 1 / 3 / 2;
31
+ }
32
+
33
+ .portal-content-aside__aside {
34
+ grid-area: 1 / 2 / 3 / 3;
35
+ }
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div class="portal-content-aside-container">
3
+ <div class="portal-content-aside">
4
+ <div class="portal-content-aside__main">
5
+ <slot />
6
+ </div>
7
+
8
+ <aside class="portal-content-aside__aside">
9
+ <slot name="aside"></slot>
10
+ </aside>
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <style scoped lang="scss" src="./portal-content-aside.scss"></style>
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, onUnmounted, useTemplateRef, ref } from 'vue'
3
+
4
+ interface Props {
5
+ breakpoint: number
6
+ }
7
+
8
+ const root = useTemplateRef('root')
9
+ const containerWidth = ref(0)
10
+ const resizeObserver = new ResizeObserver((entries) => {
11
+ containerWidth.value = entries[0].contentBoxSize[0].inlineSize
12
+ })
13
+
14
+ defineProps<Props>()
15
+
16
+ onMounted(() => {
17
+ resizeObserver.observe(root.value)
18
+ })
19
+
20
+ onUnmounted(() => {
21
+ resizeObserver.disconnect()
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <div ref="root" class="responsive-container">
27
+ <template v-if="containerWidth >= breakpoint">
28
+ <slot name="above"></slot>
29
+ </template>
30
+
31
+ <template v-else>
32
+ <slot name="below"></slot>
33
+ </template>
34
+ </div>
35
+ </template>
@@ -0,0 +1,13 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .tile-grid {
4
+ display: grid;
5
+ grid-template-columns: repeat(12, 1fr);
6
+ width: 100%;
7
+ gap: var(--e-space-6);
8
+ container: tile-grid / inline-size;
9
+
10
+ @include a.bp(m) {
11
+ gap: var(--e-space-4);
12
+ }
13
+ }
@@ -0,0 +1,31 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .tile-item {
4
+ grid-column: span 12;
5
+
6
+ &[data-width='1'] {
7
+ grid-column: span 12;
8
+ }
9
+
10
+ &[data-width='1/2'] {
11
+ grid-column: span 6;
12
+ }
13
+
14
+ &[data-width='1/3'] {
15
+ grid-column: span 4;
16
+ }
17
+
18
+ &[data-width='2/3'] {
19
+ grid-column: span 8;
20
+ }
21
+ }
22
+
23
+ @container tile-grid (width < 920px) {
24
+ .tile-item {
25
+ &[data-width='1/2'],
26
+ &[data-width='1/3'],
27
+ &[data-width='2/3'] {
28
+ grid-column: span 12;
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <div class="tile-grid">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <style scoped lang="scss" src="./tile-grid.scss"></style>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ interface Props {
3
+ width?: '1' | '1/2' | '1/3' | '2/3'
4
+ }
5
+
6
+ const { width = '1' } = defineProps<Props>()
7
+ </script>
8
+
9
+ <template>
10
+ <div class="tile-item" :data-width="width">
11
+ <slot />
12
+ </div>
13
+ </template>
14
+
15
+ <style scoped lang="scss" src="./tile-item.scss"></style>
@@ -0,0 +1,43 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ .content-title {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--e-space-8);
7
+ justify-content: flex-end;
8
+
9
+ @include a.bp(xl) {
10
+ flex-wrap: wrap;
11
+ }
12
+
13
+ @include a.bp(m) {
14
+ row-gap: var(--e-space-6);
15
+ }
16
+ }
17
+
18
+ .content-title__content {
19
+ margin-right: auto;
20
+
21
+ @include a.bp(xl) {
22
+ width: 100%;
23
+ }
24
+ }
25
+
26
+ .content-title__title {
27
+ @include a.type(500, strong);
28
+
29
+ min-width: max-content;
30
+ }
31
+
32
+ .content-title__text {
33
+ @include a.type(100);
34
+
35
+ margin-top: var(--e-space-2);
36
+ color: var(--e-c-mono-700);
37
+ }
38
+
39
+ .content-title__custom-content {
40
+ @include a.bp(xl) {
41
+ width: 100%;
42
+ }
43
+ }
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="content-title">
3
+ <div class="content-title__content">
4
+ <h1 class="content-title__title">
5
+ <slot />
6
+ </h1>
7
+
8
+ <p v-if="$slots.text" class="content-title__text">
9
+ <slot name="text" />
10
+ </p>
11
+ </div>
12
+
13
+ <div v-if="$slots['custom']" class="content-title__custom-content">
14
+ <slot name="custom"></slot>
15
+ </div>
16
+ </div>
17
+ </template>
18
+
19
+ <style scoped lang="scss" src="./content-title.scss"></style>
@@ -50,15 +50,21 @@
50
50
  padding: var(--e-space-7) var(--e-space-7) 0;
51
51
  height: a.rem(670);
52
52
  max-height: 80vh;
53
- max-width: a.rem(480);
54
- width: 100%;
53
+ max-width: a.rem(540);
54
+ min-width: a.rem(480);
55
+
56
+ &.auto-height {
57
+ height: auto;
58
+ }
55
59
 
56
60
  * + .dialog__content-image {
57
61
  margin-top: var(--e-space-5);
58
62
  }
59
63
 
60
64
  @include a.bp(m) {
65
+ width: 100%;
61
66
  max-width: none;
67
+ min-width: 0;
62
68
  height: auto;
63
69
  min-height: a.rem(440);
64
70
  padding-left: var(--e-space-5);
@@ -89,7 +95,8 @@
89
95
  }
90
96
  }
91
97
 
92
- .content-title + .content-text {
98
+ .content-title + .content-text,
99
+ .content-title + .content-custom {
93
100
  margin-top: var(--e-space-2);
94
101
 
95
102
  @include a.bp(m) {
@@ -109,6 +116,7 @@
109
116
  position: sticky;
110
117
  display: flex;
111
118
  flex-direction: column;
119
+ row-gap: var(--e-space-4);
112
120
  bottom: 0;
113
121
  margin-top: var(--overflow-gradient-height);
114
122
  padding: var(--e-space-8) var(--e-space-1) var(--e-space-7);
@@ -11,6 +11,7 @@ interface Props {
11
11
  headerImage?: Image
12
12
  contentImage?: Image
13
13
  closeBtnLabel?: string
14
+ autoHeight?: boolean
14
15
  mobileDialogStyle?: 'modal' | 'slideout'
15
16
  }
16
17
 
@@ -82,7 +83,7 @@ watch(visible, (newV) => {
82
83
  },
83
84
  ]"
84
85
  >
85
- <div class="dialog">
86
+ <div :class="['dialog', { 'auto-height': autoHeight }]">
86
87
  <div class="dialog__header-image-container">
87
88
  <slot name="header-image">
88
89
  <img v-bind="headerImage" />
@@ -96,7 +97,7 @@ watch(visible, (newV) => {
96
97
  </h3>
97
98
  </div>
98
99
 
99
- <div class="content-text">
100
+ <div v-if="$slots.text || text" class="content-text">
100
101
  <div class="richtext">
101
102
  <slot name="text">
102
103
  <div v-html="text"></div>
@@ -104,6 +105,10 @@ watch(visible, (newV) => {
104
105
  </div>
105
106
  </div>
106
107
 
108
+ <div v-if="$slots.custom" class="content-custom">
109
+ <slot name="custom"></slot>
110
+ </div>
111
+
107
112
  <div class="dialog__content-image">
108
113
  <slot name="content-image">
109
114
  <img v-bind="contentImage" />
@@ -112,6 +117,7 @@ watch(visible, (newV) => {
112
117
  </div>
113
118
 
114
119
  <div class="cta-container">
120
+ <slot name="cta"></slot>
115
121
  <UButton @click="visible = false">{{ closeBtnLabel }}</UButton>
116
122
  </div>
117
123
  </div>
@@ -1,8 +1,9 @@
1
- @use '../../base/abstracts/' as a;
1
+ @use '../../base/abstracts' as a;
2
2
  @use '../../elements/text-link/text-link.scss' as t;
3
3
  @use '../../layout/container/container.scss' as l;
4
4
 
5
5
  .footer {
6
+ &.portal,
6
7
  &.reduced {
7
8
  .footer__top {
8
9
  display: none;
@@ -25,6 +26,12 @@
25
26
  position: static;
26
27
  }
27
28
  }
29
+
30
+ &.portal {
31
+ .footer__container {
32
+ @include l.portal-content-container;
33
+ }
34
+ }
28
35
  }
29
36
 
30
37
  .footer__top {
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  interface Props {
3
- variant?: 'normal' | 'reduced'
3
+ variant?: 'normal' | 'reduced' | 'portal'
4
4
  }
5
5
 
6
6
  const { variant = 'normal' } = defineProps<Props>()
package/modules/index.js CHANGED
@@ -8,3 +8,5 @@ export { default as UProgressIndicator } from './progress-indicator/u-progress-i
8
8
  export { default as UToast } from './toast/u-toast.vue'
9
9
  export { toast } from './toast/useToast.ts'
10
10
  export { default as UDialog } from './dialog/u-dialog.vue'
11
+ export { default as USearchFilter } from './search-filter/u-search-filter.vue'
12
+ export { default as UContentTitle } from './content-title/u-content-title.vue'
@@ -0,0 +1,106 @@
1
+ @use '../../base/abstracts' as a;
2
+
3
+ @mixin collapsed-desktop {
4
+ grid-template-columns: 100%;
5
+
6
+ .search-filter__search {
7
+ display: flex;
8
+ column-gap: var(--e-space-4);
9
+ flex-direction: row-reverse;
10
+ grid-area: auto;
11
+ }
12
+
13
+ .search-filter__filter-toggle {
14
+ display: block;
15
+ }
16
+
17
+ .search-filter__filter {
18
+ display: none;
19
+ grid-area: auto;
20
+ }
21
+
22
+ &.show-filters {
23
+ .search-filter__filter {
24
+ display: grid;
25
+ grid-template-columns: repeat(calc(var(--field-count) - 1), 1fr);
26
+ }
27
+ }
28
+ }
29
+
30
+ @mixin mobile-filters {
31
+ @include a.bp(m) {
32
+ grid-template-columns: 100%;
33
+
34
+ .search-filter__search {
35
+ display: grid;
36
+ column-gap: var(--e-space-4);
37
+ grid-template-columns: auto min-content;
38
+ grid-area: auto;
39
+ }
40
+
41
+ .search-filter__filter {
42
+ display: none;
43
+ grid-area: auto;
44
+ grid-template-columns: 1fr;
45
+ }
46
+
47
+ .search-filter__filter-toggle {
48
+ flex: 0 0 auto;
49
+ display: block;
50
+ }
51
+
52
+ &.show-filters {
53
+ .search-filter__filter {
54
+ display: grid;
55
+ grid-template-columns: 1fr;
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ .search-filter {
62
+ --field-count: 1;
63
+
64
+ display: grid;
65
+ grid-template-columns: repeat(var(--field-count), minmax(0, 240px));
66
+ gap: var(--e-space-6) var(--e-space-4);
67
+
68
+ @include a.bp(xl) {
69
+ grid-template-columns: repeat(var(--field-count), 1fr);
70
+ }
71
+
72
+ .search-filter__search {
73
+ grid-area: 1 / var(--field-count) / 1 / calc(var(--field-count) + 1);
74
+ }
75
+
76
+ .search-filter__filter {
77
+ display: grid;
78
+ grid-template-columns: repeat(calc(var(--field-count) - 1), minmax(0, #{a.rem(240)}));
79
+ gap: var(--e-space-6) var(--e-space-4);
80
+ grid-area: 1 / 1 / 1 / var(--field-count);
81
+
82
+ @include a.bp(xl) {
83
+ grid-template-columns: repeat(calc(var(--field-count) - 1), 1fr);
84
+ }
85
+ }
86
+
87
+ .search-filter__filter-toggle {
88
+ display: none;
89
+ }
90
+
91
+ &.show-filters {
92
+ .search-filter__filter-toggle .icon-button {
93
+ &::before {
94
+ background-color: var(--e-c-primary-01-100);
95
+ border-color: var(--e-c-primary-01-100);
96
+ }
97
+ }
98
+ }
99
+
100
+ @include mobile-filters;
101
+ }
102
+
103
+ .search-filter.collapsed-desktop {
104
+ @include collapsed-desktop;
105
+ @include mobile-filters;
106
+ }
@@ -0,0 +1,54 @@
1
+ <script setup lang="ts">
2
+ import { ref, useTemplateRef, onMounted } from 'vue'
3
+ import { UIconButton } from '../../elements'
4
+ import { UBadge } from '../../components'
5
+
6
+ interface Props {
7
+ activeFilter?: boolean
8
+ }
9
+
10
+ defineProps<Props>()
11
+
12
+ const showFilters = ref(false)
13
+ const filtersEl = useTemplateRef('filters')
14
+ const filterCount = ref(0)
15
+
16
+ onMounted(() => {
17
+ filterCount.value = filtersEl.value.children.length
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <div
23
+ :class="[
24
+ 'search-filter',
25
+ { 'show-filters': showFilters, 'collapsed-desktop': filterCount + 1 >= 4 },
26
+ ]"
27
+ :style="{
28
+ '--field-count': filterCount + 1,
29
+ }"
30
+ >
31
+ <div class="search-filter__search">
32
+ <slot name="search" />
33
+
34
+ <div class="search-filter__filter-toggle">
35
+ <UBadge
36
+ dot
37
+ border
38
+ :show="activeFilter && !showFilters"
39
+ color="var(--e-c-secondary-05-500)"
40
+ :top="11"
41
+ :right="11"
42
+ >
43
+ <UIconButton icon="filter" variant="plain" @click="showFilters = !showFilters" />
44
+ </UBadge>
45
+ </div>
46
+ </div>
47
+
48
+ <div ref="filters" class="search-filter__filter">
49
+ <slot name="filters" />
50
+ </div>
51
+ </div>
52
+ </template>
53
+
54
+ <style scoped lang="scss" src="./search-filter.scss"></style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@energie360/ui-library",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,6 +15,7 @@
15
15
  "./wizard": "./wizard/index.js",
16
16
  "./utility/elements/*": "./dist/elements/*",
17
17
  "./utility/layout/*": "./dist/layout/*",
18
+ "./utils/*": "./utils/*",
18
19
  "./base/abstracts": "./base/abstracts/index.scss",
19
20
  "./styles/form": "./elements/form/form.scss",
20
21
  "./styles/form-grid": "./layout/form-grid/form-grid.scss"
@@ -0,0 +1,7 @@
1
+ /**
2
+ *
3
+ * @param {Array} a
4
+ * @param {Array} b
5
+ * @returns {Array}
6
+ */
7
+ export const intersect = (a, b) => a.filter((x) => b.includes(x))
@@ -1,11 +1,6 @@
1
1
  import { mediaquery } from '@energie360/design-tokens/design-tokens.json'
2
2
 
3
- // TODO: return .matches value
4
-
5
- export const isSmall = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.s})`)
6
-
7
- export const isMedium = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.m})`)
8
-
9
- export const isLarge = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.lg})`)
10
-
11
- export const isXLarge = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.xl})`)
3
+ export const isSmall = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.s})`).matches
4
+ export const isMedium = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.m})`).matches
5
+ export const isLarge = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.lg})`).matches
6
+ export const isXLarge = () => window.matchMedia(`(max-width: ${mediaquery.breakpoint.xl})`).matches