@energie360/ui-library 0.1.20 → 0.1.21

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 (43) hide show
  1. package/components/badge/u-badge.vue +9 -1
  2. package/components/card/card.scss +3 -1
  3. package/components/card/u-card.vue +1 -3
  4. package/components/card-cta-header/u-card-cta-header.vue +1 -1
  5. package/components/card-footer/u-card-footer.vue +1 -1
  6. package/components/collapsible/u-collapsible.vue +1 -1
  7. package/components/context-menu-link/u-context-menu-link.vue +2 -2
  8. package/components/data-card/data-card.scss +1 -1
  9. package/components/download-list-item/download-list-item.scss +22 -1
  10. package/components/download-list-item/u-download-list-item.vue +46 -8
  11. package/components/hint/u-hint.vue +1 -1
  12. package/components/navigation-panel-tile/u-navigation-panel-tile.vue +5 -1
  13. package/components/navigation-toolbar-link/u-navigation-toolbar-link.vue +1 -0
  14. package/components/panel/u-panel.vue +1 -1
  15. package/components/progress-avatar/u-progress-avatar.vue +4 -4
  16. package/components/richtext/u-richtext.vue +1 -1
  17. package/components/table/cell-ctas.scss +1 -0
  18. package/components/table/u-cell-progress-bar.vue +1 -1
  19. package/components/table/u-table-cell.vue +1 -0
  20. package/components/table/u-table-heading.vue +3 -5
  21. package/components/tabs/u-tabs.vue +10 -4
  22. package/components/text-block/u-text-block.vue +1 -1
  23. package/dist/base-style.css +23 -22
  24. package/dist/base-style.css.map +1 -1
  25. package/elements/button/u-button.vue +8 -1
  26. package/elements/button-chip/u-button-chip.vue +13 -7
  27. package/elements/checkbox/u-checkbox.vue +1 -1
  28. package/elements/icon-button/u-icon-button.vue +1 -1
  29. package/elements/numeric-stepper/u-numeric-stepper.vue +1 -1
  30. package/elements/select-chip/u-select-chip.vue +4 -1
  31. package/elements/text-field/u-text-field.vue +2 -0
  32. package/elements/textarea/u-textarea.vue +1 -0
  33. package/elements/toggle-switch/u-toggle-switch.vue +1 -0
  34. package/layout/index.js +2 -1
  35. package/layout/portal/portal.scss +26 -42
  36. package/layout/portal/u-portal.vue +13 -34
  37. package/layout/portal-main/portal-main.scss +98 -0
  38. package/layout/portal-main/u-portal-main.vue +37 -0
  39. package/layout/tile-grid/u-tile-item.vue +7 -0
  40. package/modules/dialog/u-dialog.vue +8 -2
  41. package/modules/navigation-panel/navigation-panel.scss +1 -1
  42. package/package.json +7 -7
  43. package/wizard/wizard-outro/u-wizard-outro.vue +1 -1
@@ -11,7 +11,15 @@ interface Props {
11
11
  right?: number
12
12
  }
13
13
 
14
- const { color = 'var(--e-c-mono-900)', type = 'default', show = true } = defineProps<Props>()
14
+ const {
15
+ value = undefined,
16
+ state = undefined,
17
+ top = 0,
18
+ right = 0,
19
+ color = 'var(--e-c-mono-900)',
20
+ type = 'default',
21
+ show = true,
22
+ } = defineProps<Props>()
15
23
  </script>
16
24
 
17
25
  <template>
@@ -6,7 +6,9 @@
6
6
  border-radius: var(--e-brd-radius-2);
7
7
  display: flex;
8
8
  flex-direction: column;
9
- height: 100%;
9
+
10
+ // Set full-height not here, but through parent group containers, like <UCardGroup>
11
+ // height: 100%;
10
12
 
11
13
  &::after {
12
14
  pointer-events: none;
@@ -28,6 +28,4 @@ watch(
28
28
  </section>
29
29
  </template>
30
30
 
31
- <style lang="scss">
32
- @use './card.scss';
33
- </style>
31
+ <style lang="scss" src="./card.scss"></style>
@@ -5,7 +5,7 @@ interface Props {
5
5
  disabled?: boolean
6
6
  }
7
7
 
8
- const { disabled = false } = defineProps<Props>()
8
+ const { title = '', subtitle = '', disabled = false } = defineProps<Props>()
9
9
  </script>
10
10
 
11
11
  <template>
@@ -19,7 +19,7 @@ interface Props {
19
19
  cta?: Radio | Link
20
20
  }
21
21
 
22
- const { cta } = defineProps<Props>()
22
+ const { cta = undefined } = defineProps<Props>()
23
23
 
24
24
  const { toggleActiveCard } = inject('card')
25
25
  const { currentValue } = inject('card-group', {})
@@ -10,7 +10,7 @@ interface Props {
10
10
  }
11
11
 
12
12
  const cId = useId()
13
- const { level = 3, expanded = false } = defineProps<Props>()
13
+ const { header = '', panel = '', level = 3, expanded = false } = defineProps<Props>()
14
14
 
15
15
  // Initial state
16
16
  const panelHidden = ref(!expanded)
@@ -10,7 +10,7 @@ interface Props {
10
10
  active?: boolean
11
11
  }
12
12
 
13
- const { href, active = false } = defineProps<Props>()
13
+ const { label = '', href = '', target = '', active = false } = defineProps<Props>()
14
14
 
15
15
  const tag = computed(() => {
16
16
  return href ? 'a' : 'span'
@@ -18,7 +18,7 @@ const tag = computed(() => {
18
18
  </script>
19
19
 
20
20
  <template>
21
- <component :is="tag" class="context-menu-link" :class="{ active }">
21
+ <component :is="tag" class="context-menu-link" :class="{ active }" :href :target>
22
22
  <UIcon :name="icon" />
23
23
  <slot>{{ label }}</slot>
24
24
  </component>
@@ -29,6 +29,6 @@
29
29
  .data-card__ctas {
30
30
  display: flex;
31
31
  column-gap: var(--e-space-4);
32
- align-items: flex-start;
33
32
  margin-top: var(--e-space-4);
33
+ line-height: 0;
34
34
  }
@@ -57,6 +57,24 @@
57
57
  }
58
58
  }
59
59
 
60
+ &.loading {
61
+ pointer-events: none;
62
+
63
+ .download-list-item__cell {
64
+ color: var(--e-c-mono-500);
65
+ }
66
+
67
+ .download-list-item__link {
68
+ ~ * .download {
69
+ animation-name: arrow-anim;
70
+ animation-delay: 100ms;
71
+ animation-duration: var(--e-trs-duration-slowest);
72
+ animation-timing-function: ease-out;
73
+ animation-iteration-count: infinite;
74
+ }
75
+ }
76
+ }
77
+
60
78
  &.visited {
61
79
  .download-list-item__cell {
62
80
  background: var(--e-c-mono-50);
@@ -124,7 +142,9 @@
124
142
 
125
143
  padding: var(--e-space-5) var(--e-space-6);
126
144
  background-color: var(--e-c-secondary-01-50);
127
- transition: background-color a.$trs-default;
145
+ transition:
146
+ background-color a.$trs-default,
147
+ color a.$trs-default;
128
148
 
129
149
  + .download-list-item__cell {
130
150
  padding-left: var(--e-space-2);
@@ -171,6 +191,7 @@
171
191
  border-radius: var(--e-brd-radius-2);
172
192
  border: 2px solid transparent;
173
193
  transition: border a.$trs-default;
194
+ cursor: pointer;
174
195
 
175
196
  &:hover {
176
197
  border: 2px solid var(--e-c-secondary-01-100);
@@ -1,24 +1,59 @@
1
1
  <script setup lang="ts">
2
- import { ref, computed, inject } from 'vue'
2
+ import { computed, inject, useTemplateRef, ref, watch } from 'vue'
3
3
  import { UIcon } from '../../elements'
4
+ import { getCurrentInstance } from 'vue'
4
5
 
5
6
  interface Props {
6
7
  data: string[]
7
- url: string
8
+ url?: string
8
9
  compact?: boolean
9
10
  headings?: string[]
11
+ visited?: boolean
12
+ loading?: boolean
10
13
  }
11
14
 
12
- const { data, compact = false, headings = inject('headings', []) } = defineProps<Props>()
15
+ const {
16
+ visited,
17
+ url = '',
18
+ data,
19
+ compact = false,
20
+ headings = inject('headings', []),
21
+ } = defineProps<Props>()
13
22
 
14
- const visited = ref(false)
23
+ const linkRef = useTemplateRef('link')
24
+ const instance = getCurrentInstance()
25
+ const emit = defineEmits(['click'])
15
26
  const isCompact = inject('compact', compact)
27
+ const isVisited = ref(false)
16
28
  const label = computed(() => data.join(', '))
29
+
30
+ const onClick = (e: Event) => {
31
+ if (!url) {
32
+ e.preventDefault()
33
+ emit('click', instance)
34
+ return
35
+ }
36
+
37
+ isVisited.value = true
38
+ }
39
+
40
+ const click = () => {
41
+ linkRef.value.click()
42
+ }
43
+
44
+ watch(
45
+ () => visited,
46
+ () => {
47
+ isVisited.value = visited
48
+ },
49
+ )
50
+
51
+ defineExpose({ click })
17
52
  </script>
18
53
 
19
54
  <template>
20
55
  <tr
21
- :class="['download-list-item', { visited, compact: isCompact }]"
56
+ :class="['download-list-item', { visited: isVisited, loading, compact: isCompact }]"
22
57
  :style="{ '--rows': Math.round(data.length / 2) }"
23
58
  >
24
59
  <td v-for="(cell, idx) in data" :key="idx" class="download-list-item__cell">
@@ -29,15 +64,18 @@ const label = computed(() => data.join(', '))
29
64
  </td>
30
65
 
31
66
  <td class="download-list-item__cell cta">
32
- <a
67
+ <component
68
+ :is="url ? 'a' : 'button'"
69
+ ref="link"
33
70
  class="download-list-item__link"
34
71
  :href="url"
35
72
  target="_blank"
36
73
  download
37
74
  :aria-label="label"
38
- @click="visited = true"
75
+ :disabled="loading"
76
+ @click="onClick"
39
77
  >
40
- </a>
78
+ </component>
41
79
  <div class="download-list-item__icon-wrapper">
42
80
  <UIcon name="mini-check" class="download-list-item__check" />
43
81
 
@@ -9,7 +9,7 @@ interface Props {
9
9
  text?: string
10
10
  }
11
11
 
12
- const { type = 'neutral' } = defineProps<Props>()
12
+ const { label = '', link = undefined, text = '', type = 'neutral' } = defineProps<Props>()
13
13
  </script>
14
14
 
15
15
  <template>
@@ -17,6 +17,10 @@ interface Props {
17
17
  }
18
18
 
19
19
  const {
20
+ description = '',
21
+ icon = '',
22
+ iconBadge = undefined,
23
+ title = '',
20
24
  href = '',
21
25
  target = '_self',
22
26
  active = false,
@@ -59,7 +63,7 @@ const tag = computed(() => (href ? 'a' : 'div'))
59
63
 
60
64
  <style lang="scss" scoped src="./navigation-panel-tile.scss"></style>
61
65
  <style lang="scss">
62
- @use '../../base/abstracts/' as a;
66
+ @use '../../base/abstracts' as a;
63
67
 
64
68
  .navigation-panel-tile__description {
65
69
  @include a.bp(lg) {
@@ -15,6 +15,7 @@ interface Props {
15
15
  }
16
16
 
17
17
  const {
18
+ label = '',
18
19
  active = false,
19
20
  collapsed = false,
20
21
  labelHidden = false,
@@ -10,7 +10,7 @@ interface Props {
10
10
  image?: Image
11
11
  }
12
12
 
13
- const { image = null } = defineProps<Props>()
13
+ const { title = '', text = '', image = null } = defineProps<Props>()
14
14
 
15
15
  const slots = useSlots()
16
16
 
@@ -18,7 +18,9 @@ const observer = new IntersectionObserver(
18
18
  if (entries[0].isIntersecting) {
19
19
  observer.disconnect()
20
20
 
21
- _progress.value = progress
21
+ setTimeout(() => {
22
+ _progress.value = progress
23
+ }, 200)
22
24
  }
23
25
  },
24
26
  {
@@ -28,9 +30,7 @@ const observer = new IntersectionObserver(
28
30
  )
29
31
 
30
32
  onMounted(() => {
31
- setTimeout(() => {
32
- observer.observe(el.value)
33
- }, 200)
33
+ observer.observe(el.value)
34
34
  })
35
35
  </script>
36
36
 
@@ -5,7 +5,7 @@ interface Props {
5
5
  inverted?: boolean
6
6
  }
7
7
 
8
- const { small = false, inverted = false } = defineProps<Props>()
8
+ const { text = '', small = false, inverted = false } = defineProps<Props>()
9
9
 
10
10
  const classes = ['richtext', { 'richtext--small': small, 'richtext--inverted': inverted }]
11
11
  </script>
@@ -3,4 +3,5 @@
3
3
  .cell-ctas {
4
4
  display: flex;
5
5
  column-gap: var(--e-space-4);
6
+ line-height: 0;
6
7
  }
@@ -7,7 +7,7 @@ interface Props {
7
7
  labelPosition?: 'top' | 'right'
8
8
  }
9
9
 
10
- const { labelPosition = 'top' } = defineProps<Props>()
10
+ const { label = '', labelPosition = 'top' } = defineProps<Props>()
11
11
  </script>
12
12
 
13
13
  <template>
@@ -10,6 +10,7 @@ interface Props extends TableCellBase {
10
10
  }
11
11
 
12
12
  const {
13
+ infoText = '',
13
14
  textStyle = TableCellTextStyle.normal,
14
15
  hAlign = TableCellHAlign.left,
15
16
  vAlign = TableCellVAlign.center,
@@ -6,17 +6,15 @@ interface Props {
6
6
  nowrap?: boolean
7
7
  }
8
8
 
9
- const { hAlign = 'left', vAlign = 'top' } = defineProps<Props>()
9
+ const { text = '', hAlign = 'left', vAlign = 'top' } = defineProps<Props>()
10
10
  </script>
11
11
 
12
12
  <template>
13
13
  <div role="cell" :class="['table-heading', `h-align-${hAlign}`, `v-align-${vAlign}`]">
14
14
  <div :class="['cell-content', { nowrap }]">
15
- <slot :text="text">{{ text }}</slot>
15
+ <slot>{{ text }}</slot>
16
16
  </div>
17
17
  </div>
18
18
  </template>
19
19
 
20
- <style scoped lang="scss">
21
- @use './table-heading.scss';
22
- </style>
20
+ <style scoped lang="scss" src="./table-heading.scss"></style>
@@ -97,11 +97,17 @@ const positionActiveBar = () => {
97
97
  activeTabEl = tabs.value.find((item) => item.value === model.value)
98
98
  }
99
99
 
100
- const activeTabRelPos = getOffsetParentPosition(activeTabEl)
100
+ try {
101
+ const activeTabRelPos = getOffsetParentPosition(activeTabEl)
101
102
 
102
- activeBarStyles.value = {
103
- width: `${activeTabEl.offsetWidth}px`,
104
- left: `${activeTabRelPos.left + list.value.scrollLeft}px`,
103
+ activeBarStyles.value = {
104
+ width: `${activeTabEl.offsetWidth}px`,
105
+ left: `${activeTabRelPos.left + list.value.scrollLeft}px`,
106
+ }
107
+ } catch {
108
+ // This will sometimes fail during resizing. Not sure why it happens.
109
+ // Also when coverage-testing this will fail.
110
+ // We don't need to do anything here.
105
111
  }
106
112
  }
107
113
 
@@ -6,7 +6,7 @@ interface Props {
6
6
  centered?: boolean
7
7
  }
8
8
 
9
- const { centered = false } = defineProps<Props>()
9
+ const { title = '', text = '', centered = false } = defineProps<Props>()
10
10
  </script>
11
11
 
12
12
  <template>
@@ -3,28 +3,6 @@
3
3
  Base styling and resets for all vue-components/custom-elements.
4
4
  This must be loaded before all other styles.
5
5
  */
6
- /**
7
- * @license
8
- * MyFonts Webfont Build ID 3943012, 2020-09-02T07:30:46-0400
9
- *
10
- * The fonts listed in this notice are subject to the End User License
11
- * Agreement(s) entered into by the website owner. All other parties are
12
- * explicitly restricted from using the Licensed Webfonts(s).
13
- *
14
- * Webfont: Glober-Bold by Fontfabric
15
- * URL: https://www.myfonts.com/fonts/font-fabric/glober/bold/
16
- * Copyright: Copyright (c) 2019 by Svet Simov. All rights reserved.
17
- *
18
- *
19
- * Webfont: Glober-Regular by Fontfabric
20
- * URL: https://www.myfonts.com/fonts/font-fabric/glober/regular/
21
- * Copyright: Copyright (c) 2019 by Svet Simov. All rights reserved.
22
- *
23
- *
24
- * © 2020 MyFonts Inc
25
- */
26
- /* @import must be at top of file, otherwise CSS will not work */
27
- @import url("//hello.myfonts.net/count/3c2a64");
28
6
  body {
29
7
  margin: 0;
30
8
  min-height: 100vh;
@@ -180,6 +158,29 @@ body {
180
158
  outline: none;
181
159
  }
182
160
 
161
+ /**
162
+ * @license
163
+ * MyFonts Webfont Build ID 3943012, 2020-09-02T07:30:46-0400
164
+ *
165
+ * The fonts listed in this notice are subject to the End User License
166
+ * Agreement(s) entered into by the website owner. All other parties are
167
+ * explicitly restricted from using the Licensed Webfonts(s).
168
+ *
169
+ * Webfont: Glober-Bold by Fontfabric
170
+ * URL: https://www.myfonts.com/fonts/font-fabric/glober/bold/
171
+ * Copyright: Copyright (c) 2019 by Svet Simov. All rights reserved.
172
+ *
173
+ *
174
+ * Webfont: Glober-Regular by Fontfabric
175
+ * URL: https://www.myfonts.com/fonts/font-fabric/glober/regular/
176
+ * Copyright: Copyright (c) 2019 by Svet Simov. All rights reserved.
177
+ *
178
+ *
179
+ * © 2020 MyFonts Inc
180
+ */
181
+ /* @import must be at top of file, otherwise CSS will not work */
182
+ /* TODO: Add this import only for production build. Currently It causes weird warnings in dev mode. */
183
+ /* @import url('//hello.myfonts.net/count/3c2a64'); */
183
184
  /* TODO: Assets path is hardcoded here. Should be configurable */
184
185
  /* Regular */
185
186
  @font-face {
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../base/main-base.scss","../node_modules/@energie360/design-tokens/dist/fonts/fonts.css","../base/_resets.scss","../base/abstracts/_resets.scss","../base/abstracts/_variables.scss","../base/abstracts/_functions.scss","../base/_input-resets.scss","../base/abstracts/_mixins.scss","../base/_html.scss","../base/_body.scss","../base/_focus-handling.scss","../node_modules/@energie360/design-tokens/dist/css/design-tokens.css"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA;AACQ;ACpBR;EACE;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AC1BA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADuBJ;AAAA;EAEE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AErB+E;AChCjF;ACHA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EC8BE;EACA;EAKE;;;AD7BF;EACE;;AAGF;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAIA;EACE;;;AAIJ;EACE;;;AAGF;EAEE;;AAEA;EAEE;EACA;;;AEvDJ;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;ACTF;EACE;EACA;EACA;EACA;EACA;;;ACAF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ATQF;AACA;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AU3CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;;;AX7MA;AAAA;AAAA;AAAA;EACE","file":"base-style.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../base/main-base.scss","../base/_resets.scss","../base/abstracts/_resets.scss","../base/abstracts/_variables.scss","../base/abstracts/_functions.scss","../base/_input-resets.scss","../base/abstracts/_mixins.scss","../base/_html.scss","../base/_body.scss","../base/_focus-handling.scss","../node_modules/@energie360/design-tokens/dist/fonts/fonts.css","../node_modules/@energie360/design-tokens/dist/css/design-tokens.css"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;ACEA;EACE;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AC1BA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADuBJ;AAAA;EAEE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AErB+E;AChCjF;ACHA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EC8BE;EACA;EAKE;;;AD7BF;EACE;;AAGF;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAIA;EACE;;;AAIJ;EACE;;;AAGF;EAEE;;AAEA;EAEE;EACA;;;AEvDJ;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;ACTF;EACE;EACA;EACA;EACA;EACA;;;ACAF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AChBF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA;AAEA;AAEA;AAEA;AAEA;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;;;AX7MA;AAAA;AAAA;AAAA;EACE","file":"base-style.css"}
@@ -18,7 +18,14 @@ interface ButtonProps {
18
18
  hideLabelLg?: boolean
19
19
  }
20
20
 
21
- const { asSpan = false } = defineProps<ButtonProps>()
21
+ const {
22
+ label = '',
23
+ variant = 'filled',
24
+ icon = '',
25
+ href = '',
26
+ target = '',
27
+ asSpan = false,
28
+ } = defineProps<ButtonProps>()
22
29
 
23
30
  const buttonTag = computed(() => (asSpan ? 'span' : 'button'))
24
31
  </script>
@@ -15,7 +15,13 @@ interface Props {
15
15
  target?: string
16
16
  }
17
17
 
18
- const { variant = ButtonChipVariant.normal } = defineProps<Props>()
18
+ const {
19
+ label = '',
20
+ icon = '',
21
+ href = '',
22
+ target = '',
23
+ variant = ButtonChipVariant.normal,
24
+ } = defineProps<Props>()
19
25
  </script>
20
26
 
21
27
  <template>
@@ -23,9 +29,9 @@ const { variant = ButtonChipVariant.normal } = defineProps<Props>()
23
29
  <a :class="['button-chip', variant]" :href :target>
24
30
  <UIcon v-if="icon" :name="icon"></UIcon>
25
31
 
26
- <span class="button-chip__label"
27
- ><slot>{{ label }}</slot></span
28
- >
32
+ <span class="button-chip__label">
33
+ <slot>{{ label }}</slot>
34
+ </span>
29
35
  </a>
30
36
  </template>
31
37
 
@@ -33,9 +39,9 @@ const { variant = ButtonChipVariant.normal } = defineProps<Props>()
33
39
  <button :class="['button-chip', variant]" :disabled>
34
40
  <UIcon v-if="icon" :name="icon"></UIcon>
35
41
 
36
- <span class="button-chip__label"
37
- ><slot>{{ label }}</slot></span
38
- >
42
+ <span class="button-chip__label">
43
+ <slot>{{ label }}</slot>
44
+ </span>
39
45
  </button>
40
46
  </template>
41
47
  </template>
@@ -9,7 +9,7 @@ interface Props {
9
9
  errorMessage?: string
10
10
  }
11
11
 
12
- const { errorMessage = '' } = defineProps<Props>()
12
+ const { label = '', errorMessage = '' } = defineProps<Props>()
13
13
 
14
14
  const model = defineModel<boolean>()
15
15
  const cId = `checkbox-${useId()}`
@@ -10,7 +10,7 @@ interface Props {
10
10
  target?: string
11
11
  }
12
12
 
13
- const { target = '_blank', variant = 'filled' } = defineProps<Props>()
13
+ const { label = '', href = '', target = '_blank', variant = 'filled' } = defineProps<Props>()
14
14
  </script>
15
15
 
16
16
  <template>
@@ -5,7 +5,6 @@ import { getTranslation } from '../../utils/translations/translate'
5
5
 
6
6
  interface Props {
7
7
  label?: string
8
- value?: string | number
9
8
  name: string
10
9
  disabled?: boolean
11
10
  readonly?: boolean
@@ -24,6 +23,7 @@ const {
24
23
  max = '',
25
24
  step = '1',
26
25
  error = false,
26
+ errorMessage = '',
27
27
  } = defineProps<Props>()
28
28
 
29
29
  const cId = `numeric-stepper-${useId()}`
@@ -11,6 +11,7 @@ interface Props {
11
11
  provideKey?: string
12
12
  }
13
13
  const {
14
+ label = '',
14
15
  name,
15
16
  disabled = false,
16
17
  value = '',
@@ -30,7 +31,9 @@ const classes = computed(() =>
30
31
  <div class="select-chip">
31
32
  <label :class="classes" class="select-chip__button button">
32
33
  <UIcon v-if="model === value" name="mini-check" />
33
- {{ label }}
34
+ <slot name="label">
35
+ {{ label }}
36
+ </slot>
34
37
 
35
38
  <slot>
36
39
  <input v-model="model" type="radio" :name :value :disabled @change="onChange" />
@@ -16,6 +16,8 @@ interface Props extends FormFieldBase {
16
16
  const inputId = useId()
17
17
 
18
18
  const {
19
+ placeholder = '',
20
+ unit = '',
19
21
  disabled = false,
20
22
  readonly = false,
21
23
  required = false,
@@ -10,6 +10,7 @@ interface Props extends FormFieldBase {
10
10
  }
11
11
 
12
12
  const {
13
+ placeholder = '',
13
14
  required = false,
14
15
  disabled = false,
15
16
  readonly = false,
@@ -14,6 +14,7 @@ export interface ToggleSwitch {
14
14
  }
15
15
 
16
16
  const {
17
+ label = '',
17
18
  variant = 'big',
18
19
  labelPosition = 'right',
19
20
  disabled = false,
package/layout/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { default as UPortalLayout } from './portal/u-portal.vue'
2
+ export { default as UPortalMain } from './portal-main/u-portal-main.vue'
3
+ export { default as UPortalContentAside } from './portal-content-aside/u-portal-content-aside.vue'
2
4
  export { default as UTileGrid } from './tile-grid/u-tile-grid.vue'
3
5
  export { default as UTileItem } from './tile-grid/u-tile-item.vue'
4
6
  export { default as UResponsiveContainer } from './responsive-container/u-responsive-container.vue'
5
- export { default as UPortalContentAside } from './portal-content-aside/u-portal-content-aside.vue'
@@ -2,62 +2,46 @@
2
2
  @use '../../layout/container/container' as c;
3
3
 
4
4
  .portal {
5
- --side-nav-width: 80px;
6
- }
5
+ width: 100%;
6
+ display: grid;
7
+ grid:
8
+ 'nav body' 1fr
9
+ / auto 1fr;
7
10
 
8
- .portal__side-navigation {
9
- position: fixed;
10
- height: 100vh;
11
- display: flex;
12
- }
13
-
14
- .portal__top-navigation {
15
- display: none;
11
+ @include a.bp(lg) {
12
+ grid-template-areas: none;
13
+ grid-template-columns: 1fr;
14
+ grid-template-rows: 56px auto;
15
+ min-height: 100vh;
16
+ }
16
17
  }
17
18
 
18
- .portal__sub-navigation {
19
+ .portal__side-navigation {
20
+ grid-area: nav;
19
21
  position: sticky;
20
22
  top: 0;
21
- z-index: 10;
22
- background-color: var(--e-c-mono-00);
23
- }
24
-
25
- .portal__main {
26
- display: flex;
27
- flex-direction: column;
28
- padding-left: var(--side-nav-width);
29
- min-height: 100vh;
30
- }
31
-
32
- .portal__content-container {
33
- padding-top: var(--e-space-10);
34
- padding-bottom: var(--e-space-10);
35
-
36
- @include c.portal-content-container;
23
+ height: 100vh;
24
+ z-index: 1;
37
25
 
38
26
  @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);
27
+ display: none;
44
28
  }
45
29
  }
46
30
 
47
- .portal__footer {
48
- margin-top: auto;
49
- }
31
+ .portal__top-navigation {
32
+ display: none;
33
+ position: relative;
34
+ z-index: 20;
50
35
 
51
- @include a.bp(lg) {
52
- .portal__top-navigation {
36
+ @include a.bp(lg) {
53
37
  display: block;
54
38
  }
39
+ }
55
40
 
56
- .portal__side-navigation {
57
- display: none;
58
- }
41
+ .portal__body {
42
+ grid-area: body;
59
43
 
60
- .portal__sub-navigation {
61
- background-color: var(--e-c-mono-50);
44
+ @include a.bp(lg) {
45
+ grid-area: auto;
62
46
  }
63
47
  }
@@ -1,49 +1,28 @@
1
1
  <script setup lang="ts">
2
- import { useTemplateRef, onMounted, ref } from 'vue'
2
+ import { provide } from 'vue'
3
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
- })
4
+ const slots = defineSlots<{
5
+ default()
6
+ sideNavigation()
7
+ topNavigation()
8
+ footer()
9
+ }>()
11
10
 
12
- const sideNavEl = useTemplateRef('sideNavigation')
13
- const sideNavWidth = ref(0)
14
-
15
- onMounted(() => {
16
- sideNavObserver.observe(sideNavEl.value)
17
- })
11
+ provide('portal-footer-slot', slots.footer)
18
12
  </script>
19
13
 
20
14
  <template>
21
- <div
22
- class="portal"
23
- :style="{
24
- '--side-nav-width': `${sideNavWidth}px`,
25
- }"
26
- >
15
+ <div class="portal">
27
16
  <div ref="sideNavigation" class="portal__side-navigation">
28
- <slot name="side-navigation"></slot>
17
+ <slot name="sideNavigation"></slot>
29
18
  </div>
30
19
 
31
20
  <div class="portal__top-navigation">
32
- <slot name="top-navigation"></slot>
21
+ <slot name="topNavigation"></slot>
33
22
  </div>
34
23
 
35
- <div class="portal__main">
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>
43
-
44
- <div class="portal__footer">
45
- <slot name="footer"></slot>
46
- </div>
24
+ <div class="portal__body">
25
+ <slot></slot>
47
26
  </div>
48
27
  </div>
49
28
  </template>
@@ -0,0 +1,98 @@
1
+ @use '../../base/abstracts' as a;
2
+ @use '../../layout/container/container' as c;
3
+
4
+ .portal-main {
5
+ --panel-width: 300px;
6
+ --panel-height-mobile: 180px;
7
+
8
+ width: 100%;
9
+ display: grid;
10
+ grid-template-rows: 1fr;
11
+ grid-template-columns: 0 minmax(0, 1fr);
12
+ grid-template-areas: 'panel main';
13
+ transition: grid a.$trs-default;
14
+
15
+ &.show-panel {
16
+ grid-template-columns: var(--panel-width) minmax(0, 1fr);
17
+
18
+ .portal-main__panel {
19
+ transform: none;
20
+ opacity: 1;
21
+ }
22
+ }
23
+
24
+ @include a.bp(lg) {
25
+ grid-template-areas: none;
26
+ grid-template-columns: minmax(0, 1fr);
27
+ grid-template-rows: 0 auto;
28
+ height: 100%;
29
+
30
+ &.show-panel {
31
+ grid-template-columns: minmax(0, 1fr);
32
+ grid-template-rows: var(--panel-height-mobile) auto;
33
+ }
34
+ }
35
+ }
36
+
37
+ .portal-main__main {
38
+ grid-area: main;
39
+ display: flex;
40
+ flex-direction: column;
41
+
42
+ @include a.bp(lg) {
43
+ grid-area: auto;
44
+ }
45
+ }
46
+
47
+ .portal-main__panel {
48
+ grid-area: panel;
49
+ position: sticky;
50
+ top: 0;
51
+ min-width: 0;
52
+ height: 100vh;
53
+ width: var(--panel-width);
54
+ opacity: 0;
55
+ transform: translateX(-100%);
56
+ overflow: hidden;
57
+ transition:
58
+ transform a.$trs-default,
59
+ opacity a.$trs-default;
60
+
61
+ @include a.bp(lg) {
62
+ grid-area: auto;
63
+ position: static;
64
+ width: 100%;
65
+ height: var(--panel-height-mobile);
66
+ transform: translateY(-100%);
67
+ }
68
+ }
69
+
70
+ .portal-main__sub-navigation {
71
+ position: sticky;
72
+ top: 0;
73
+ z-index: 10;
74
+ background-color: var(--e-c-mono-00);
75
+
76
+ @include a.bp(lg) {
77
+ background-color: var(--e-c-mono-50);
78
+ }
79
+ }
80
+
81
+ .portal-main__content {
82
+ padding-top: var(--e-space-10);
83
+ padding-bottom: var(--e-space-10);
84
+
85
+ @include c.portal-content-container;
86
+
87
+ @include a.bp(lg) {
88
+ padding-top: var(--e-space-8);
89
+ }
90
+
91
+ @include a.bp(m) {
92
+ padding-top: var(--e-space-6);
93
+ }
94
+ }
95
+
96
+ .portal-main__footer {
97
+ margin-top: auto;
98
+ }
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { inject } from 'vue'
3
+
4
+ interface Props {
5
+ showPanel?: boolean
6
+ }
7
+
8
+ defineProps<Props>()
9
+
10
+ const portalFooterSlot = inject('portal-footer-slot')
11
+ </script>
12
+
13
+ <template>
14
+ <div :class="['portal-main', { 'show-panel': showPanel }]">
15
+ <div class="portal-main__panel">
16
+ <slot name="panel"></slot>
17
+ </div>
18
+
19
+ <div class="portal-main__main">
20
+ <div class="portal-main__sub-navigation">
21
+ <slot name="subNavigation"></slot>
22
+ </div>
23
+
24
+ <div class="portal-main__content">
25
+ <slot></slot>
26
+ </div>
27
+
28
+ <div v-if="portalFooterSlot || $slots.footer" class="portal-main__footer">
29
+ <slot name="footer">
30
+ <component :is="vnode" v-for="(vnode, idx) in portalFooterSlot()" :key="idx" />
31
+ </slot>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </template>
36
+
37
+ <style scoped lang="scss" src="./portal-main.scss"></style>
@@ -13,3 +13,10 @@ const { width = '1' } = defineProps<Props>()
13
13
  </template>
14
14
 
15
15
  <style scoped lang="scss" src="./tile-item.scss"></style>
16
+ <style lang="scss">
17
+ .tile-item {
18
+ .card {
19
+ height: 100%;
20
+ }
21
+ }
22
+ </style>
@@ -15,8 +15,14 @@ interface Props {
15
15
  mobileDialogStyle?: 'modal' | 'slideout'
16
16
  }
17
17
 
18
- const { mobileDialogStyle = 'modal', closeBtnLabel = getTranslation('close') } =
19
- defineProps<Props>()
18
+ const {
19
+ title = '',
20
+ text = '',
21
+ headerImage = undefined,
22
+ contentImage = undefined,
23
+ mobileDialogStyle = 'modal',
24
+ closeBtnLabel = getTranslation('close'),
25
+ } = defineProps<Props>()
20
26
 
21
27
  const visible = defineModel<boolean>('visible')
22
28
  const dialogEl = useTemplateRef('dialog')
@@ -1,4 +1,4 @@
1
- @use '../../base/abstracts/' as a;
1
+ @use '../../base/abstracts' as a;
2
2
 
3
3
  .navigation-panel {
4
4
  overflow: auto;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@energie360/ui-library",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,21 +24,21 @@
24
24
  "author": "",
25
25
  "license": "MIT",
26
26
  "devDependencies": {
27
- "@tsconfig/node22": "^22.0.1",
28
- "@types/node": "^22.14.0",
27
+ "@tsconfig/node22": "^22.0.2",
28
+ "@types/node": "^22.16.5",
29
29
  "@vue/tsconfig": "^0.7.0",
30
30
  "autoprefixer": "^10.4.21",
31
31
  "chokidar": "^4.0.3",
32
- "postcss": "^8.5.3",
33
- "sass": "^1.86.3",
32
+ "postcss": "^8.5.6",
33
+ "sass": "^1.89.2",
34
34
  "typescript": "^5.8.3"
35
35
  },
36
36
  "dependencies": {
37
37
  "@energie360/design-tokens": "^1.3.0"
38
38
  },
39
39
  "peerDependencies": {
40
- "vue": "^3.5.0",
41
- "sass": "^1.86.3"
40
+ "sass": "^1.86.3",
41
+ "vue": "^3.5.0"
42
42
  },
43
43
  "scripts": {
44
44
  "watch": "node ./watch.js",
@@ -10,7 +10,7 @@ interface Props {
10
10
  cta?: Cta
11
11
  }
12
12
 
13
- const { text, cta } = defineProps<Props>()
13
+ const { text = '', image = undefined, cta = undefined, title = '' } = defineProps<Props>()
14
14
 
15
15
  const slots = useSlots()
16
16
  const hasCta = computed(() => !!slots.cta || cta)