@energie360/ui-library 0.1.8 → 0.1.10

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 (48) hide show
  1. package/base/abstracts/_variables.scss +1 -0
  2. package/components/context-menu/context-menu.scss +28 -0
  3. package/components/context-menu/u-context-menu.vue +113 -0
  4. package/components/context-menu-divider/context-menu-divider.scss +6 -0
  5. package/components/context-menu-divider/u-context-menu-divider.vue +5 -0
  6. package/components/context-menu-link/context-menu-link.scss +26 -0
  7. package/components/context-menu-link/u-context-menu-link.vue +27 -0
  8. package/components/index.js +38 -5
  9. package/components/navigation-toolbar-link/navigation-toolbar-link.scss +177 -0
  10. package/components/navigation-toolbar-link/u-navigation-toolbar-link.vue +108 -0
  11. package/components/text-block/text-block.scss +58 -0
  12. package/components/text-block/u-text-block.vue +26 -0
  13. package/components/tooltip/popover.ts +74 -12
  14. package/dist/base-style.css +1 -0
  15. package/dist/base-style.css.map +1 -1
  16. package/dist/elements/text-link.css +1 -0
  17. package/dist/elements/text-link.css.map +1 -1
  18. package/dist/layout/split.css +1 -0
  19. package/dist/layout/split.css.map +1 -1
  20. package/elements/button-chip/button-chip.scss +2 -2
  21. package/elements/index.js +13 -0
  22. package/elements/text-field/u-text-field.vue +9 -1
  23. package/elements/types.ts +0 -2
  24. package/i18n/i18n.ts +8 -0
  25. package/modules/index.js +5 -0
  26. package/modules/navigation-toolbar-side/navigation-toolbar-side.scss +89 -0
  27. package/modules/navigation-toolbar-side/u-navigation-toolbar-side.vue +93 -0
  28. package/modules/navigation-toolbar-top/navigation-toolbar-top.scss +89 -0
  29. package/modules/navigation-toolbar-top/u-navigation-toolbar-top.vue +130 -0
  30. package/package.json +4 -7
  31. package/utils/a11y/focus-trap.js +128 -0
  32. package/elements/button/index.js +0 -1
  33. package/elements/button-chip/index.js +0 -1
  34. package/elements/icon/index.js +0 -1
  35. package/elements/icon-button/index.js +0 -1
  36. package/elements/image/index.js +0 -1
  37. package/elements/loader/index.js +0 -1
  38. package/elements/numeric-stepper/index.js +0 -1
  39. package/elements/password-progress/index.js +0 -1
  40. package/elements/radio/index.js +0 -1
  41. package/elements/radio-group/index.js +0 -1
  42. package/elements/select/index.js +0 -1
  43. package/elements/select-chip/index.js +0 -1
  44. package/elements/select-chips/index.js +0 -1
  45. package/elements/spectro/index.js +0 -1
  46. package/elements/text-field/index.js +0 -1
  47. package/elements/textarea/index.js +0 -1
  48. package/elements/toggle-switch/index.js +0 -1
@@ -5,9 +5,17 @@ export type Placement =
5
5
  | 'top-right'
6
6
  | 'top-left'
7
7
  | 'top-center'
8
+ | 'top-full'
8
9
  | 'bottom-right'
9
10
  | 'bottom-left'
10
11
  | 'bottom-center'
12
+ | 'bottom-full'
13
+ | 'right-top'
14
+ | 'right-center'
15
+ | 'right-bottom'
16
+ | 'left-top'
17
+ | 'left-center'
18
+ | 'left-bottom'
11
19
  export interface PopoverPositionParams {
12
20
  placement?: Placement
13
21
  offset?: number
@@ -52,6 +60,7 @@ export const getPopoverPosition = (
52
60
 
53
61
  let top = 0
54
62
  let left = 0
63
+ let right: number | string = ''
55
64
  const { vpWidth } = getViewportDimensions()
56
65
  const docHeight = document.documentElement.scrollHeight
57
66
  const scrollY = window.scrollY
@@ -64,32 +73,85 @@ export const getPopoverPosition = (
64
73
  popoverEl.style.display = ''
65
74
  }
66
75
 
76
+ const topPosition = offsetTop - popoverRect.height - options.offset
77
+ const bottomPosition = offsetTop + refRect.height + options.offset
78
+ const leftAligned = offsetLeft
79
+ const rightAligned = offsetLeft + refRect.width - popoverRect.width
80
+ const centerAligned = offsetLeft + refRect.width / 2 - popoverRect.width / 2
81
+
82
+ const rightPosition = offsetLeft + refRect.width + options.offset
83
+ const leftPosition = offsetLeft - popoverRect.width - options.offset
84
+ const topVAligned = offsetTop
85
+ const centerVAligned = offsetTop - popoverRect.height / 2 + refRect.height / 2
86
+ const bottomVAligned = offsetTop - popoverRect.height + refRect.height
87
+
67
88
  switch (options.placement) {
68
89
  case 'top-right':
69
- top = offsetTop - popoverRect.height - options.offset
70
- left = offsetLeft + refRect.width - popoverRect.width
90
+ top = topPosition
91
+ left = rightAligned
92
+ break
93
+
94
+ case 'top-center':
95
+ top = topPosition
96
+ left = centerAligned
71
97
  break
72
98
 
73
99
  case 'top-left':
74
- top = offsetTop - popoverRect.height - options.offset
75
- left = offsetLeft
100
+ top = topPosition
101
+ left = leftAligned
102
+ break
103
+
104
+ case 'top-full':
105
+ top = topPosition
106
+ left = options.viewportPadding
107
+ right = options.viewportPadding
76
108
  break
77
109
 
78
110
  case 'bottom-right':
79
- top = offsetTop + refRect.height + options.offset
80
- left = offsetLeft + refRect.width - popoverRect.width
111
+ top = bottomPosition
112
+ left = rightAligned
113
+ break
114
+
115
+ case 'bottom-center':
116
+ top = bottomPosition
117
+ left = centerAligned
81
118
  break
82
119
 
83
120
  case 'bottom-left':
84
- top = offsetTop + refRect.height + options.offset
85
- left = offsetLeft
121
+ top = bottomPosition
122
+ left = leftAligned
86
123
  break
87
124
 
88
- // TODO: add remaining placement options
89
- case 'bottom-center':
125
+ case 'bottom-full':
126
+ top = bottomPosition
127
+ left = options.viewportPadding
128
+ right = options.viewportPadding
90
129
  break
91
130
 
92
- case 'top-center':
131
+ case 'right-top':
132
+ top = topVAligned
133
+ left = rightPosition
134
+ break
135
+ case 'right-center':
136
+ top = centerVAligned
137
+ left = rightPosition
138
+ break
139
+ case 'right-bottom':
140
+ top = bottomVAligned
141
+ left = rightPosition
142
+ break
143
+
144
+ case 'left-top':
145
+ top = topVAligned
146
+ left = leftPosition
147
+ break
148
+ case 'left-center':
149
+ top = centerVAligned
150
+ left = leftPosition
151
+ break
152
+ case 'left-bottom':
153
+ top = bottomVAligned
154
+ left = leftPosition
93
155
  }
94
156
 
95
157
  // Add corrections to position if necessary
@@ -114,7 +176,7 @@ export const getPopoverPosition = (
114
176
  top = offsetTop - popoverRect.height - options.offset
115
177
  }
116
178
 
117
- return { top, left }
179
+ return { top, left, right }
118
180
  }
119
181
 
120
182
  /**
@@ -92,6 +92,7 @@ fieldset {
92
92
  border: 0;
93
93
  }
94
94
 
95
+ /* easeOutCubic */
95
96
  /* prettier-ignore */
96
97
  input,
97
98
  textarea,
@@ -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/_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;;;ADwBJ;AAAA;EAEE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AErDF;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;;;AAIA;EAEE;EACA;;;AEpDJ;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;;;ACTF;EACE;EACA;EACA;EACA;EACA;;;ACAF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ARQF;AACA;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;AACA;EACE;EACA;EACA;EACA;EACA,KACE;;AS3CJ;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;;;AV7MA;AAAA;AAAA;AAAA;EACE","file":"base-style.css"}
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;;;ADwBJ;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;;;AAIA;EAEE;EACA;;;AEpDJ;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,3 +1,4 @@
1
+ /* easeOutCubic */
1
2
  /* prettier-ignore */
2
3
  .text-link {
3
4
  font-size: var(--e-type-size-200);
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../base/abstracts/_functions.scss","../../elements/text-link/text-link.scss","../../base/abstracts/_mixins.scss"],"names":[],"mappings":"AAKA;ACyCA;ECHE;EACA;EAGE;EAMA;EAKE;EACA;EDtDJ;EACA;EACA;EACA,YACE;;AAGF;EACE;;AAGF;EACE;;AAgCF;EA3BA;;AAEA;EACE;;AAGF;EACE;;AAwBF;EAnBA;EACA;;AAEA;EACE;;AAGF;EACE","file":"text-link.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../base/abstracts/_variables.scss","../../base/abstracts/_functions.scss","../../elements/text-link/text-link.scss","../../base/abstracts/_mixins.scss"],"names":[],"mappings":"AAqCiF;AChCjF;ACyCA;ECHE;EACA;EAGE;EAMA;EAKE;EACA;EDtDJ;EACA;EACA;EACA,YACE;;AAGF;EACE;;AAGF;EACE;;AAgCF;EA3BA;;AAEA;EACE;;AAGF;EACE;;AAwBF;EAnBA;EACA;;AAEA;EACE;;AAGF;EACE","file":"text-link.css"}
@@ -1,3 +1,4 @@
1
+ /* easeOutCubic */
1
2
  /* prettier-ignore */
2
3
  .container {
3
4
  margin: 0 auto;
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../base/abstracts/_functions.scss","../../layout/container/container.scss","../../base/abstracts/_mixins.scss","../../layout/split/split.scss"],"names":[],"mappings":"AAKA;ACsBA;EAtBE;EACA;EACA;EACA;EACA;;ACYA;EDMF;IAfI;IACA;;;ACQF;EDMF;IAVI;IACA;;;ACGF;EDMF;IALI;IACA;;;;AEjBJ;EACE;EACA;EACA;EACA;EACA;;ADUA;ECfF;IAQI;IACA;IACA;IACA;IACA;IACA,qBACE;;;ADCJ;ECfF;IAmBI;IACA;;;;AAIJ;EACE;EACA;;ADXA;ECSF;IAKI;IACA;;;ADfF;ECSF;IAUI;IACA;IACA;;;;AAIJ;EACE;;AD1BA;ECyBF;IAII;IACA;;;AD9BF;ECyBF;IASI;;;;AAIJ;EACE;EACA;EACA;EACA;;AD1CA;ECsCF;IAOI;IAIA;IACA;;;ADlDF;ECsCF;IAgBI;IACA;IACA;IACA;IACA;IACA;;;AD3DF;ECsCF;IAyBI;IACA;IACA;;;;AAIJ;EACE;;ADtEA;ECqEF;IAII;;;ADzEF;ECqEF;IAQI","file":"split.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../base/abstracts/_variables.scss","../../base/abstracts/_functions.scss","../../layout/container/container.scss","../../base/abstracts/_mixins.scss","../../layout/split/split.scss"],"names":[],"mappings":"AAqCiF;AChCjF;ACsBA;EAtBE;EACA;EACA;EACA;EACA;;ACYA;EDMF;IAfI;IACA;;;ACQF;EDMF;IAVI;IACA;;;ACGF;EDMF;IALI;IACA;;;;AEjBJ;EACE;EACA;EACA;EACA;EACA;;ADUA;ECfF;IAQI;IACA;IACA;IACA;IACA;IACA,qBACE;;;ADCJ;ECfF;IAmBI;IACA;;;;AAIJ;EACE;EACA;;ADXA;ECSF;IAKI;IACA;;;ADfF;ECSF;IAUI;IACA;IACA;;;;AAIJ;EACE;;AD1BA;ECyBF;IAII;IACA;;;AD9BF;ECyBF;IASI;;;;AAIJ;EACE;EACA;EACA;EACA;;AD1CA;ECsCF;IAOI;IAIA;IACA;;;ADlDF;ECsCF;IAgBI;IACA;IACA;IACA;IACA;IACA;;;AD3DF;ECsCF;IAyBI;IACA;IACA;;;;AAIJ;EACE;;ADtEA;ECqEF;IAII;;;ADzEF;ECqEF;IAQI","file":"split.css"}
@@ -63,6 +63,8 @@
63
63
  background-color a.$trs-default,
64
64
  color a.$trs-default;
65
65
 
66
+ @include button-chip-normal;
67
+
66
68
  .icon {
67
69
  margin-left: a.rem(-10);
68
70
  }
@@ -71,8 +73,6 @@
71
73
  @include button-chip-minified;
72
74
  }
73
75
 
74
- @include button-chip-normal;
75
-
76
76
  &.inverted {
77
77
  @include button-chip-inverted;
78
78
  }
package/elements/index.js CHANGED
@@ -3,6 +3,19 @@
3
3
  * -> https://vite.dev/guide/performance#avoid-barrel-files
4
4
  */
5
5
  export { default as UButton } from './button/u-button.vue'
6
+ export { default as UButtonChip } from './button-chip/u-button-chip.vue'
6
7
  export { default as UIcon } from './icon/u-icon.vue'
7
8
  export { default as UIconButton } from './icon-button/u-icon-button.vue'
9
+ export { default as UImage } from './image/u-image.vue'
8
10
  export { default as ULoader } from './loader/u-loader.vue'
11
+ export { default as UNumericStepper } from './numeric-stepper/u-numeric-stepper.vue'
12
+ export { default as UPasswordProgress } from './password-progress/u-password-progress.vue'
13
+ export { default as URadio } from './radio/u-radio.vue'
14
+ export { default as URadioGroup } from './radio-group/u-radio-group.vue'
15
+ export { default as USelect } from './select/u-select.vue'
16
+ export { default as USelectChip } from './select-chip/u-select-chip.vue'
17
+ export { default as USelectChips } from './select-chips/u-select-chips.vue'
18
+ export { default as USpectro } from './spectro/u-spectro.vue'
19
+ export { default as UTextField } from './text-field/u-text-field.vue'
20
+ export { default as UTextarea } from './textarea/u-textarea.vue'
21
+ export { default as UToggleSwitch } from './toggle-switch/u-toggle-switch.vue'
@@ -26,6 +26,11 @@ const {
26
26
 
27
27
  const slots = useSlots()
28
28
  const model = defineModel<string>()
29
+ const emits = defineEmits<{
30
+ input: [value: string | null]
31
+ focus: [target: FocusEvent['target']]
32
+ focusout: [target: FocusEvent['target']]
33
+ }>()
29
34
 
30
35
  const input = useTemplateRef('input')
31
36
 
@@ -39,12 +44,13 @@ const spacer = '.&nbsp;'
39
44
  // In some cases we need to change the input type within the component (for example for the password-show behaviour)
40
45
  const _inputType = ref(type)
41
46
 
42
- const onFocus = () => {
47
+ const onFocus = (event: FocusEvent) => {
43
48
  if (readonly || disabled) {
44
49
  return
45
50
  }
46
51
 
47
52
  isFocused.value = true
53
+ emits('focus', event.target)
48
54
  }
49
55
 
50
56
  const onBlur = () => {
@@ -53,6 +59,7 @@ const onBlur = () => {
53
59
 
54
60
  const onInput = () => {
55
61
  hasValue.value = !!input.value && input.value.value !== ''
62
+ emits('input', input.value?.value ?? null)
56
63
  }
57
64
 
58
65
  const onHover = () => {
@@ -140,6 +147,7 @@ watch(
140
147
  :required
141
148
  @input="onInput"
142
149
  @focus="onFocus"
150
+ @focusout="$emit('focusout', $event.target)"
143
151
  @blur="onBlur"
144
152
  /></slot>
145
153
 
package/elements/types.ts CHANGED
@@ -1,5 +1,3 @@
1
- // TODO: @Dani if you have a better naming please update it.
2
-
3
1
  export interface Cta {
4
2
  label: string
5
3
  href: string
package/i18n/i18n.ts CHANGED
@@ -11,6 +11,8 @@ const translations = {
11
11
  passwordRequirements: 'Anforderungen an das Passwort',
12
12
  edit: 'Bearbeiten',
13
13
  cancel: 'Abbrechen',
14
+ openMenu: 'Menu öffnen',
15
+ closeMenu: 'Menu schliessen',
14
16
  },
15
17
  FR: {
16
18
  yes: 'Ja',
@@ -24,6 +26,8 @@ const translations = {
24
26
  passwordRequirements: 'Exigences relatives au mot de passe',
25
27
  edit: 'Modifier',
26
28
  cancel: 'Annuler',
29
+ openMenu: 'Ouvrir le menu',
30
+ closeMenu: 'Fermer le menu',
27
31
  },
28
32
  IT: {
29
33
  yes: 'Ja',
@@ -37,6 +41,8 @@ const translations = {
37
41
  passwordRequirements: 'Requisiti per la password',
38
42
  edit: 'modificare',
39
43
  cancel: 'cancellare',
44
+ openMenu: 'Apri il menu',
45
+ closeMenu: 'Chiudi menù',
40
46
  },
41
47
  EN: {
42
48
  yes: 'Ja',
@@ -50,6 +56,8 @@ const translations = {
50
56
  passwordRequirements: 'Password requirements',
51
57
  edit: 'Edit',
52
58
  cancel: 'Cancel',
59
+ openMenu: 'Open menu',
60
+ closeMenu: 'Close menu',
53
61
  },
54
62
  }
55
63
 
@@ -0,0 +1,5 @@
1
+ export { default as UFeedback } from './feedback/u-feedback.vue'
2
+ export { default as UFooter } from './footer/u-footer.vue'
3
+ export { default as UInlineEditGroup } from './inline-edit-group/u-inline-edit-group.vue'
4
+ export { default as UNavigationToolbarTop } from './navigation-toolbar-top/u-navigation-toolbar-top.vue'
5
+ export { default as UNavigationToolbarSide } from './navigation-toolbar-side/u-navigation-toolbar-side.vue'
@@ -0,0 +1,89 @@
1
+ @use '../../base/abstracts/' as a;
2
+
3
+ .navigation-toolbar-side {
4
+ --nav-width-expanded: #{a.rem(280)};
5
+ --transition-ease-out: cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic */
6
+
7
+ display: flex;
8
+ flex-direction: column;
9
+ padding: var(--e-space-6);
10
+ width: var(--nav-width-expanded);
11
+ height: 100%;
12
+ background-color: var(--e-c-secondary-01-1000);
13
+
14
+ &.collapsed {
15
+ width: a.rem(88);
16
+
17
+ .navigation-toolbar-side__logo {
18
+ width: a.rem(40);
19
+ }
20
+
21
+ .navigation-toolbar-side__nav-links,
22
+ .navigation-toolbar-side__menu-cta {
23
+ padding: 0 var(--e-space-0_5);
24
+ }
25
+ }
26
+ }
27
+
28
+ .navigation-toolbar-side__logo {
29
+ width: a.rem(196);
30
+ height: a.rem(40);
31
+ margin-bottom: var(--e-space-12);
32
+ }
33
+
34
+ .navigation-toolbar-side__nav-links {
35
+ display: flex;
36
+ flex-direction: column;
37
+ row-gap: var(--e-space-2);
38
+ }
39
+
40
+ .navigation-toolbar-side__menu-ctas {
41
+ display: flex;
42
+ flex-direction: column;
43
+ row-gap: var(--e-space-2);
44
+ margin-top: auto;
45
+ }
46
+
47
+ .navigation-toolbar-side__menu-cta {
48
+ display: block;
49
+ width: 100%;
50
+ }
51
+
52
+ .navigation-toolbar-side__top-bar-logo {
53
+ img {
54
+ height: a.rem(24);
55
+ }
56
+ }
57
+
58
+ .navigation-toolbar-side__top-bar-ctas {
59
+ display: flex;
60
+ column-gap: var(--e-space-4);
61
+ }
62
+
63
+ // Animation
64
+ .navigation-toolbar-side {
65
+ &.is-collapsing {
66
+ will-change: width;
67
+ transition: width var(--e-trs-duration-faster) var(--transition-ease-out);
68
+ width: a.rem(88);
69
+ overflow: hidden;
70
+
71
+ .navigation-toolbar-side__nav-links,
72
+ .navigation-toolbar-side__menu-ctas {
73
+ transition: padding var(--e-trs-duration-faster) var(--transition-ease-out);
74
+ padding: 0 var(--e-space-0_5);
75
+ }
76
+ }
77
+
78
+ &.is-expanding {
79
+ will-change: width;
80
+ transition: all var(--e-trs-duration-faster) var(--transition-ease-out);
81
+ width: var(--nav-width-expanded);
82
+
83
+ .navigation-toolbar-side__nav-links,
84
+ .navigation-toolbar-side__menu-ctas {
85
+ transition: padding var(--e-trs-duration-faster) var(--transition-ease-out);
86
+ padding: 0;
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,93 @@
1
+ <script setup lang="ts">
2
+ import { UNavigationToolbarLink } from '../../components'
3
+ import { UContextMenu } from '../../components'
4
+ import { Image } from '../../elements/types'
5
+ import { ref, watch, useTemplateRef } from 'vue'
6
+
7
+ interface MenuButton {
8
+ icon: string
9
+ label: string
10
+ }
11
+
12
+ interface Props {
13
+ logoLink: {
14
+ href: string
15
+ target: string
16
+ }
17
+ menuButton: MenuButton
18
+ collapsed?: boolean
19
+ logoImage: Image
20
+ logoMinifiedImage: Image
21
+ }
22
+
23
+ const { collapsed = false } = defineProps<Props>()
24
+
25
+ const el = useTemplateRef('el')
26
+ const isCollapsed = ref(collapsed)
27
+ const isCollapsing = ref(false)
28
+ const isExpanding = ref(false)
29
+
30
+ const onTransitionEnd = () => {
31
+ el.value?.removeEventListener('transitionend', onTransitionEnd)
32
+ isCollapsed.value = !isCollapsed.value
33
+
34
+ isCollapsing.value = false
35
+ isExpanding.value = false
36
+ }
37
+
38
+ watch(
39
+ () => collapsed,
40
+ (newV) => {
41
+ el.value?.addEventListener('transitionend', onTransitionEnd)
42
+
43
+ if (newV) {
44
+ isCollapsing.value = true
45
+ } else {
46
+ isExpanding.value = true
47
+ }
48
+ },
49
+ )
50
+ </script>
51
+
52
+ <template>
53
+ <div
54
+ ref="el"
55
+ :class="[
56
+ 'navigation-toolbar-side',
57
+ {
58
+ collapsed: isCollapsed,
59
+ 'is-collapsing': isCollapsing,
60
+ 'is-expanding': isExpanding,
61
+ },
62
+ ]"
63
+ >
64
+ <a class="navigation-toolbar-side__logo" :href="logoLink.href" :target="logoLink.target">
65
+ <img
66
+ v-if="isCollapsed || isExpanding"
67
+ :src="logoMinifiedImage.src"
68
+ :alt="logoMinifiedImage.alt"
69
+ />
70
+ <img v-else :src="logoImage.src" :alt="logoImage.alt" />
71
+ </a>
72
+
73
+ <nav ref="mobile-panel" class="navigation-toolbar-side__nav-panel">
74
+ <div class="navigation-toolbar-side__nav-links">
75
+ <slot name="navLinks"></slot>
76
+ </div>
77
+ </nav>
78
+
79
+ <div class="navigation-toolbar-side__menu-ctas">
80
+ <UContextMenu placement="right-bottom">
81
+ <template #trigger>
82
+ <button class="navigation-toolbar-side__menu-cta" type="button">
83
+ <UNavigationToolbarLink v-bind="menuButton" :collapsed />
84
+ </button>
85
+ </template>
86
+
87
+ <slot name="contextMenuLinks"></slot>
88
+ </UContextMenu>
89
+ </div>
90
+ </div>
91
+ </template>
92
+
93
+ <style lang="scss" src="./navigation-toolbar-side.scss" scoped></style>
@@ -0,0 +1,89 @@
1
+ @use '../../base/abstracts/' as a;
2
+
3
+ .navigation-toolbar-top {
4
+ --transition-ease-out: cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic */
5
+
6
+ display: block;
7
+ width: 100%;
8
+ padding: 0 var(--e-space-5);
9
+ height: a.rem(56);
10
+ background-color: var(--e-c-secondary-01-1000);
11
+ }
12
+
13
+ .navigation-toolbar-top__top-bar {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ height: 100%;
18
+ }
19
+
20
+ .navigation-toolbar-top__nav-panel-logo {
21
+ display: block;
22
+ height: a.rem(48);
23
+ padding-bottom: a.rem(24);
24
+ margin-bottom: var(--e-space-14);
25
+
26
+ img {
27
+ height: 100%;
28
+ }
29
+ }
30
+
31
+ .navigation-toolbar-top__nav-panel-close {
32
+ display: block;
33
+ position: absolute;
34
+ top: var(--e-space-4);
35
+ right: var(--e-space-5);
36
+ z-index: 1;
37
+ }
38
+
39
+ .navigation-toolbar-top__nav-panel {
40
+ position: fixed;
41
+ padding: var(--e-space-4) var(--e-space-5);
42
+ top: 0;
43
+ left: 0;
44
+ background-color: var(--e-c-secondary-01-1000);
45
+ width: 100%;
46
+ height: 100%;
47
+ transform: translate3d(100%, 0, 0);
48
+
49
+ .navigation-toolbar-mobile-open & {
50
+ transform: translate3d(0, 0, 0);
51
+ }
52
+
53
+ // Animation
54
+ &.is-opening {
55
+ transition: transform var(--e-trs-duration-faster) var(--transition-ease-out);
56
+ transform: translate3d(0, 0, 0);
57
+ }
58
+
59
+ &.is-closing {
60
+ transition: transform var(--e-trs-duration-faster) var(--transition-ease-out);
61
+ transform: translate3d(100%, 0, 0);
62
+ }
63
+ }
64
+
65
+ .navigation-toolbar-top__nav-links {
66
+ row-gap: var(--e-space-4);
67
+ }
68
+
69
+ .navigation-toolbar-top__nav-links {
70
+ display: flex;
71
+ flex-direction: column;
72
+ row-gap: var(--e-space-2);
73
+ }
74
+
75
+ .navigation-toolbar-top__top-bar-logo {
76
+ img {
77
+ height: a.rem(24);
78
+ }
79
+ }
80
+
81
+ .navigation-toolbar-top__top-bar-ctas {
82
+ display: flex;
83
+ column-gap: var(--e-space-4);
84
+ }
85
+
86
+ // Global
87
+ .navigation-toolbar-mobile-open {
88
+ overflow: hidden;
89
+ }