@energie360/ui-library 0.1.4 → 0.1.5

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/components/card/card.scss +2 -25
  2. package/components/card-footer/card-footer.scss +5 -0
  3. package/components/card-footer/u-card-footer.vue +52 -0
  4. package/components/card-group/card-group.scss +29 -0
  5. package/components/card-group/u-card-group.vue +66 -0
  6. package/components/card-header/card-header.scss +1 -5
  7. package/components/card-section/card-section.scss +13 -0
  8. package/components/card-section/u-card-section.vue +7 -0
  9. package/components/tabs/tabs.scss +88 -0
  10. package/components/tabs/u-tabs.vue +140 -0
  11. package/dist/layout/split.css +6 -0
  12. package/dist/layout/split.css.map +1 -1
  13. package/elements/button/_button-base.scss +1 -1
  14. package/elements/form-field/form-field-base.scss +1 -1
  15. package/elements/icon-button/_icon-button-base.scss +1 -4
  16. package/elements/radio/index.js +1 -0
  17. package/elements/radio/radio.scss +7 -0
  18. package/elements/radio/u-radio.vue +33 -0
  19. package/elements/radio-group/index.js +1 -0
  20. package/elements/radio-group/radio-group-composables.ts +38 -0
  21. package/elements/radio-group/radio-group.scss +3 -0
  22. package/elements/radio-group/u-radio-group.vue +15 -0
  23. package/elements/select-chip/u-select-chip.vue +15 -21
  24. package/elements/select-chips/u-select-chips.vue +5 -8
  25. package/i18n/i18n.ts +5 -0
  26. package/layout/split/split.scss +5 -0
  27. package/modules/feedback/feedback-animations.scss +32 -0
  28. package/modules/feedback/feedback-form.scss +12 -0
  29. package/modules/feedback/feedback-vote-buttons.scss +73 -0
  30. package/modules/feedback/feedback.scss +31 -0
  31. package/modules/feedback/types/feedback.type.ts +33 -0
  32. package/modules/feedback/u-feedback-close.vue +32 -0
  33. package/modules/feedback/u-feedback-finish-view.vue +31 -0
  34. package/modules/feedback/u-feedback-form.vue +16 -0
  35. package/modules/feedback/u-feedback-vote-buttons.vue +59 -0
  36. package/modules/feedback/u-feedback.vue +58 -0
  37. package/modules/footer/footer.scss +13 -16
  38. package/modules/footer/u-footer.vue +4 -10
  39. package/package.json +3 -2
  40. package/utils/dom/dom.js +167 -0
  41. package/utils/functions/breakpoint.js +11 -0
  42. package/utils/functions/debounce.js +25 -0
  43. package/base-style.js +0 -1
  44. package/components/icon-teaser/icon-teaser.scss +0 -58
  45. package/components/icon-teaser/u-icon-teaser.vue +0 -35
  46. package/components/icon-teaser-group/icon-teaser-group.scss +0 -10
  47. package/components/icon-teaser-group/u-icon-teaser-group.vue +0 -19
  48. package/utility/utility-text.js +0 -1
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Wrap an element with another element
3
+ *
4
+ * @param {Node} el
5
+ * @param {string} wrapper - Tag name of wrapper element. Can also have a classname (like emmet notation)
6
+ *
7
+ * @returns {Node}
8
+ */
9
+ export const wrap = (el, wrapper) => {
10
+ const parsedWrapper = wrapper.split('.')
11
+ const wrapperEl = document.createElement(parsedWrapper[0])
12
+
13
+ if (parsedWrapper.length > 1) {
14
+ wrapperEl.className = parsedWrapper.slice(1).join(' ')
15
+ }
16
+
17
+ el.parentNode.insertBefore(wrapperEl, el)
18
+ wrapperEl.appendChild(el)
19
+
20
+ return wrapperEl
21
+ }
22
+
23
+ /**
24
+ * Get element position relative to document.
25
+ *
26
+ * @param {Node} el
27
+ * @returns {{top: number, left: number, width: number, height: number}}
28
+ */
29
+ export const getElementPosition = (el) => {
30
+ const elRect = el.getBoundingClientRect()
31
+ const scrollTop = window.scrollY
32
+ const scrollLeft = window.scrollX
33
+
34
+ return {
35
+ top: elRect.top + scrollTop,
36
+ left: elRect.left + scrollLeft,
37
+ width: elRect.width,
38
+ height: elRect.height,
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Decode HTML encoded string.
44
+ *
45
+ * @param {string} str
46
+ * @returns {string}
47
+ */
48
+ export const htmlDecode = (str) => {
49
+ const doc = new DOMParser().parseFromString(str, 'text/html')
50
+ return doc.documentElement.textContent
51
+ }
52
+
53
+ export const htmlToDocFragment = (str) => {
54
+ const tpl = document.createElement('template')
55
+ tpl.innerHTML = str
56
+ return tpl.content.cloneNode(true)
57
+ }
58
+
59
+ /**
60
+ * Reverse order of direct child nodes of given parent.
61
+ *
62
+ * @param {Node} parent
63
+ */
64
+ export const reverseChildren = (parent) => {
65
+ for (let i = 1; i < parent.childNodes.length; i++) {
66
+ parent.insertBefore(parent.childNodes[i], parent.firstChild)
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Check if element is in a slotted element.
72
+ *
73
+ * @param {Element} el
74
+ * @returns {boolean}
75
+ */
76
+ const isInSlottedElement = (el) => {
77
+ const parentEl = el.parentElement
78
+
79
+ if (parentEl === document.body || !parentEl) {
80
+ return false
81
+ }
82
+
83
+ if (parentEl.assignedSlot) {
84
+ return true
85
+ } else {
86
+ return isInSlottedElement(parentEl)
87
+ }
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param {Element} el
93
+ * @returns {boolean}
94
+ */
95
+ const isOffsetParent = (el) => {
96
+ const style = getComputedStyle(el)
97
+ return style.position === 'relative' || style.position === 'absolute'
98
+ }
99
+
100
+ /**
101
+ * Get the expected offsetParent within nested shadow roots.
102
+ *
103
+ * Because elements are nested in web components or slotted in web components we can't get desired offsetParent.
104
+ *
105
+ * @param {Element} el
106
+ * @returns {Element}
107
+ */
108
+ export const getOffsetParent = (el) => {
109
+ if (el === document.body) {
110
+ // We arrived at the top.
111
+ // 'body' must be the offsetParent then.
112
+ return el
113
+ }
114
+
115
+ const offsetParent = el.offsetParent
116
+
117
+ if (offsetParent === document.body || offsetParent === null) {
118
+ // It's possible that we're a slotted element, in which case we'll always have the potentially 'wrong' offsetParent 'body'.
119
+ // Dig deeper...
120
+ if (el.assignedSlot) {
121
+ // A <slot> doesn't have an offsetParent. Let's use the parentNode.
122
+ const parentElement = el.assignedSlot.parentElement
123
+
124
+ // Handle case where the parent node actually is an offsetParent
125
+ if (isOffsetParent(parentElement)) {
126
+ return parentElement
127
+ }
128
+
129
+ return getOffsetParent(el.assignedSlot.parentElement)
130
+ }
131
+
132
+ if (isInSlottedElement(el)) {
133
+ return getOffsetParent(el.parentElement)
134
+ }
135
+
136
+ if (el.getRootNode() instanceof ShadowRoot) {
137
+ // If we're nested in another shadow root we'll also always get 'body' as offsetParent.
138
+ // Check the offsetParent of the current host element.
139
+ return getOffsetParent(el.getRootNode().host)
140
+ }
141
+ }
142
+
143
+ return offsetParent
144
+ }
145
+
146
+ /**
147
+ * Get offset positions of parent which is not 'static'.
148
+ *
149
+ * @param {Element} el
150
+ * @returns {Object}
151
+ */
152
+ export const getOffsetParentPosition = (el) => {
153
+ const offsetParent = getOffsetParent(el)
154
+ const elRect = el.getBoundingClientRect()
155
+ const offsetParentRect = offsetParent.getBoundingClientRect()
156
+
157
+ return {
158
+ top: elRect.top - offsetParentRect.top,
159
+ left: elRect.left - offsetParentRect.left,
160
+ }
161
+ }
162
+
163
+ export const moveChildren = (sourceParent, targetParent) => {
164
+ while (sourceParent.childNodes.length > 0) {
165
+ targetParent.appendChild(sourceParent.childNodes[0])
166
+ }
167
+ }
@@ -0,0 +1,11 @@
1
+ import { mediaquery } from '@energie360/design-tokens/design-tokens.json'
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})`)
@@ -0,0 +1,25 @@
1
+ export const debounce = (callback, wait = 200) => {
2
+ let timeoutId = null
3
+
4
+ return function (...args) {
5
+ clearTimeout(timeoutId)
6
+ timeoutId = setTimeout(() => {
7
+ callback.apply(this, args)
8
+ }, wait)
9
+ }
10
+ }
11
+
12
+ export const debounceRaf = function (fn) {
13
+ let rid
14
+
15
+ return (...args) => {
16
+ if (rid) {
17
+ return
18
+ }
19
+
20
+ rid = window.requestAnimationFrame(() => {
21
+ fn(...args)
22
+ rid = undefined
23
+ })
24
+ }
25
+ }
package/base-style.js DELETED
@@ -1 +0,0 @@
1
- import './base/main-base.scss'
@@ -1,58 +0,0 @@
1
- @use '../../base/abstracts/' as a;
2
-
3
- .icon-tesaer__content {
4
- display: flex;
5
- flex-direction: column;
6
- row-gap: var(--e-space-2);
7
- }
8
-
9
- .icon-teaser__image-wrapper {
10
- margin: 0 auto var(--e-space-6);
11
- display: flex;
12
- align-items: center;
13
- justify-content: center;
14
- flex: 0 0 auto;
15
- width: a.rem(120);
16
- height: a.rem(120);
17
- border-radius: 100%;
18
- background-color: var(--e-c-primary-01-50);
19
-
20
- @include a.bp(m) {
21
- margin-bottom: var(--e-space-4);
22
- width: a.rem(96);
23
- height: a.rem(96);
24
- }
25
-
26
- img {
27
- width: a.rem(56);
28
- height: a.rem(56);
29
-
30
- @include a.bp(m) {
31
- width: a.rem(38);
32
- height: a.rem(38);
33
- }
34
- }
35
- }
36
-
37
- .icon-teaser__title {
38
- @include a.type(400, strong);
39
-
40
- text-align: center;
41
-
42
- @include a.bp(m) {
43
- @include a.type(300, strong);
44
- }
45
- }
46
-
47
- .icon-teaser__description {
48
- @include a.type(200);
49
-
50
- margin-top: var(--e-space-3);
51
- text-align: center;
52
-
53
- @include a.bp(m) {
54
- margin-top: var(--e-space-1);
55
-
56
- @include a.type(100);
57
- }
58
- }
@@ -1,35 +0,0 @@
1
- <script setup lang="ts">
2
- import { Image } from '../../elements/types.ts'
3
-
4
- export interface IconTeaser {
5
- title?: string
6
- description?: string
7
- image?: Image
8
- }
9
-
10
- defineProps<IconTeaser>()
11
- </script>
12
-
13
- <template>
14
- <div class="icon-teaser">
15
- <div class="icon-teaser__image-wrapper">
16
- <slot name="image">
17
- <img aria-hidden="true" :src="image?.src" :alt="image?.alt" />
18
- </slot>
19
- </div>
20
-
21
- <div class="icon-teaser__content">
22
- <h2 class="icon-teaser__title">
23
- <slot name="title">{{ title }}</slot>
24
- </h2>
25
-
26
- <p class="icon-teaser__description">
27
- <slot name="description">{{ description }}</slot>
28
- </p>
29
- </div>
30
- </div>
31
- </template>
32
-
33
- <style lang="scss">
34
- @use './icon-teaser.scss';
35
- </style>
@@ -1,10 +0,0 @@
1
- @use '../../base/abstracts/' as a;
2
-
3
- .icon-teaser-group {
4
- display: flex;
5
- gap: var(--e-space-10);
6
-
7
- @include a.bp(lg) {
8
- flex-direction: column;
9
- }
10
- }
@@ -1,19 +0,0 @@
1
- <script setup lang="ts">
2
- import UIconTeaser, { IconTeaser } from '../icon-teaser/u-icon-teaser.vue'
3
-
4
- interface Props {
5
- items?: IconTeaser[]
6
- }
7
-
8
- defineProps<Props>()
9
- </script>
10
-
11
- <template>
12
- <div class="icon-teaser-group">
13
- <slot><UIconTeaser v-for="(item, idx) in items" :key="idx" v-bind="item"></UIconTeaser></slot>
14
- </div>
15
- </template>
16
-
17
- <style lang="scss">
18
- @use './icon-teaser-group.scss';
19
- </style>
@@ -1 +0,0 @@
1
- import '../elements/text-link/text-link.scss'