@eccenca/gui-elements 23.7.0-rc.2 → 23.7.0-rc.4

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 (28) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/cjs/components/Depiction/Depiction.js +4 -2
  3. package/dist/cjs/components/Depiction/Depiction.js.map +1 -1
  4. package/dist/cjs/components/MultiSelect/MultiSelect.js +5 -33
  5. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
  6. package/dist/cjs/components/Sticky/StickyTarget.js +46 -5
  7. package/dist/cjs/components/Sticky/StickyTarget.js.map +1 -1
  8. package/dist/esm/components/Depiction/Depiction.js +4 -2
  9. package/dist/esm/components/Depiction/Depiction.js.map +1 -1
  10. package/dist/esm/components/MultiSelect/MultiSelect.js +5 -33
  11. package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
  12. package/dist/esm/components/Sticky/StickyTarget.js +46 -5
  13. package/dist/esm/components/Sticky/StickyTarget.js.map +1 -1
  14. package/dist/types/cmem/ActivityControl/ActivityControlTypes.d.ts +1 -0
  15. package/dist/types/components/Depiction/Depiction.d.ts +7 -1
  16. package/dist/types/components/MultiSelect/MultiSelect.d.ts +14 -9
  17. package/dist/types/components/Sticky/StickyTarget.d.ts +14 -3
  18. package/package.json +1 -1
  19. package/src/cmem/ActivityControl/ActivityControlTypes.ts +2 -0
  20. package/src/components/Depiction/Depiction.tsx +10 -1
  21. package/src/components/Depiction/depiction.scss +25 -0
  22. package/src/components/MultiSelect/MultiSelect.tsx +25 -43
  23. package/src/components/MultiSuggestField/MultiSuggestField.stories.tsx +1 -2
  24. package/src/components/MultiSuggestField/tests/MultiSuggestField.test.tsx +90 -6
  25. package/src/components/Select/Select.stories.tsx +11 -2
  26. package/src/components/Sticky/StickyTarget.tsx +63 -7
  27. package/src/components/Sticky/sticky.scss +71 -12
  28. package/src/components/TextField/textfield.scss +3 -0
@@ -13,15 +13,26 @@ export interface StickyTargetProps extends React.HTMLAttributes<HTMLDivElement>
13
13
  * The application header is not taken into offset calculation
14
14
  */
15
15
  local?: boolean;
16
+ /**
17
+ * Set additional distance to original sticky position.
18
+ */
19
+ offset?: `${number}${string}`;
16
20
  /**
17
21
  * Set the background color used for the sticky area.
18
22
  * As it can overlay other content readability could be harmed if the overlayed content is shining through.
19
23
  */
20
24
  background?: "card" | "application" | "transparent";
21
25
  /**
22
- * Set additional distance to original sticky position.
26
+ * In some situations there could be a gap between sticky target area and the border of the related scroll area.
27
+ * The main gap is the gap towards the direction of the sticky behaviour, specified by `to`.
28
+ * You can fill this gap with a gradient or full background color.
23
29
  */
24
- offset?: `${number}${string}`;
30
+ fillMainGap?: "full" | "gradient";
31
+ /**
32
+ * The secondary gap is the gap against the direction of the sticky behaviour.
33
+ * So in case of `to="top"` this is rendered on the bottom of the sticky area.
34
+ */
35
+ fillSecondaryGap?: "full" | "gradient";
25
36
  /**
26
37
  * Callback that returns an DOM element.
27
38
  * The position of `StickyTarget` is then calculated relative to that element.
@@ -37,8 +48,10 @@ export const StickyTarget = ({
37
48
  className,
38
49
  to = "top",
39
50
  local = false,
40
- background = "transparent",
41
51
  offset,
52
+ background = "transparent",
53
+ fillMainGap,
54
+ fillSecondaryGap,
42
55
  style,
43
56
  getConnectedElement,
44
57
  ...otherDivProps
@@ -50,8 +63,13 @@ export const StickyTarget = ({
50
63
  offsetStyle = { ...style, "--eccgui-sticky-target-localoffset": offset } as CSSProperties;
51
64
  }
52
65
 
53
- let connectedOffset = 0;
54
66
  React.useEffect(() => {
67
+ let removeEventForConnectedOffset = () => {
68
+ /* no event need to be removed */
69
+ };
70
+ let removeEventForStickynessCheck = () => {
71
+ /* no event need to be removed */
72
+ };
55
73
  /**
56
74
  * If the target should be sticky to a defined element then:
57
75
  * * check for the element and its scroll parent
@@ -64,6 +82,7 @@ export const StickyTarget = ({
64
82
  const scrollParentFallback = !scrollParent ? document.documentElement : false;
65
83
  if (scrollParent || scrollParentFallback) {
66
84
  const updateTargetOffset = () => {
85
+ let connectedOffset = 0;
67
86
  const scrollParentPosition = (
68
87
  (scrollParent || scrollParentFallback) as HTMLElement
69
88
  ).getBoundingClientRect();
@@ -85,20 +104,55 @@ export const StickyTarget = ({
85
104
  `${connectedOffset}px`
86
105
  );
87
106
  };
107
+
88
108
  updateTargetOffset();
89
109
  const eventListeningTarget = scrollParent || window;
90
110
  const eventListeningMethod = (_event: Event) => {
91
111
  updateTargetOffset();
92
112
  };
93
113
  eventListeningTarget.addEventListener("scroll", eventListeningMethod);
94
- return () => {
114
+ removeEventForConnectedOffset = () => {
95
115
  eventListeningTarget.removeEventListener("scroll", eventListeningMethod);
96
116
  };
97
117
  }
98
118
  }
99
119
  }
100
- return;
101
- }, [getConnectedElement, stickyTargetRef, to]);
120
+ /**
121
+ * Check if sticky target element is currently in sticky mode.
122
+ * sticky mode = current position === defined sticky position
123
+ */
124
+ if (stickyTargetRef && (fillMainGap || fillSecondaryGap)) {
125
+ const stickyTarget = stickyTargetRef.current as Element;
126
+ const scrollParent = utils.getScrollParent(stickyTarget);
127
+ const checkStickyness = () => {
128
+ const definedPosition = parseInt(window.getComputedStyle(stickyTarget)[to], 10);
129
+ const scrollParentPosition = scrollParent ? scrollParent.getBoundingClientRect()[to] : 0;
130
+ const currentPosition =
131
+ (to === "top" ? 1 : -1) * (stickyTarget.getBoundingClientRect()[to] - scrollParentPosition);
132
+ // check stickyness in a small position range (not exact value) because of float values
133
+ const isSticky = currentPosition <= definedPosition + 1 && currentPosition >= definedPosition - 1;
134
+ if (isSticky && !stickyTarget.classList.contains(`${eccgui}-sticky__target--issticky`)) {
135
+ stickyTarget.classList.add(`${eccgui}-sticky__target--issticky`);
136
+ }
137
+ if (!isSticky && stickyTarget.classList.contains(`${eccgui}-sticky__target--issticky`)) {
138
+ stickyTarget.classList.remove(`${eccgui}-sticky__target--issticky`);
139
+ }
140
+ };
141
+ checkStickyness();
142
+ const eventListeningTarget = scrollParent || window;
143
+ const eventListeningMethod = (_event: Event) => {
144
+ checkStickyness();
145
+ };
146
+ eventListeningTarget.addEventListener("scroll", eventListeningMethod);
147
+ removeEventForStickynessCheck = () => {
148
+ eventListeningTarget.removeEventListener("scroll", eventListeningMethod);
149
+ };
150
+ }
151
+ return () => {
152
+ removeEventForConnectedOffset();
153
+ removeEventForStickynessCheck();
154
+ };
155
+ }, [getConnectedElement, stickyTargetRef, to, fillMainGap, fillSecondaryGap]);
102
156
 
103
157
  return (
104
158
  <div
@@ -108,6 +162,8 @@ export const StickyTarget = ({
108
162
  (to ? ` ${eccgui}-sticky__target--${to}` : "") +
109
163
  (local ? ` ${eccgui}-sticky__target--localscrollarea` : "") +
110
164
  (background ? ` ${eccgui}-sticky__target--bg-${background}` : "") +
165
+ (fillMainGap ? ` ${eccgui}-sticky__target--maingapfill-${fillMainGap}` : "") +
166
+ (fillSecondaryGap ? ` ${eccgui}-sticky__target--secondarygapfill-${fillSecondaryGap}` : "") +
111
167
  (className ? ` ${className}` : "")
112
168
  }
113
169
  style={offset ? offsetStyle : style}
@@ -5,11 +5,14 @@
5
5
  .#{$eccgui}-sticky__target {
6
6
  position: sticky;
7
7
  z-index: 1;
8
+ background-color: var(--eccgui-sticky-target-bgcolor, transparent);
8
9
 
9
10
  --eccgui-sticky-target-applicationoffset: 0px;
11
+ --eccgui-sticky-target-maingap: 0px;
10
12
 
11
13
  .#{$eccgui}-application__content &:not(.#{$eccgui}-sticky__target--localscrollarea) {
12
- --eccgui-sticky-target-applicationoffset: $eccgui-size-block-whitespace;
14
+ --eccgui-sticky-target-applicationoffset: #{$eccgui-size-block-whitespace};
15
+ --eccgui-sticky-target-maingap: #{$eccgui-size-block-whitespace};
13
16
  }
14
17
 
15
18
  .#{$eccgui}-application__header
@@ -17,53 +20,109 @@
17
20
  &:not(.#{$eccgui}-sticky__target--localscrollarea) {
18
21
  --eccgui-sticky-target-applicationoffset: calc(#{mini-units(8)} + #{$eccgui-size-block-whitespace});
19
22
  }
23
+
24
+ &[class*="#{$eccgui}-sticky__target--maingapfill"]:before,
25
+ &[class*="#{$eccgui}-sticky__target--secondarygapfill"]:after {
26
+ position: absolute;
27
+ left: 0;
28
+ width: 100%;
29
+ height: calc(var(--eccgui-sticky-target-maingap) + var(--eccgui-sticky-target-localoffset, 0px));
30
+ }
31
+
32
+ &[class*="#{$eccgui}-sticky__target--secondarygapfill"]:after {
33
+ height: $eccgui-size-block-whitespace * 0.5;
34
+ }
20
35
  }
21
36
 
22
37
  .#{$eccgui}-sticky__target--top {
23
38
  top: calc(var(--eccgui-sticky-target-applicationoffset) + var(--eccgui-sticky-target-localoffset, 0px));
39
+
40
+ &[class*="#{$eccgui}-sticky__target--maingapfill"]:before {
41
+ bottom: 100%;
42
+ }
43
+
44
+ &[class*="#{$eccgui}-sticky__target--secondarygapfill"]:after {
45
+ top: 100%;
46
+ }
47
+
48
+ &.#{$eccgui}-sticky__target--maingapfill-gradient:before {
49
+ background: linear-gradient(transparent, 10%, var(--eccgui-sticky-target-bgcolor, transparent));
50
+ }
51
+
52
+ &.#{$eccgui}-sticky__target--secondarygapfill-gradient:after {
53
+ background: linear-gradient(var(--eccgui-sticky-target-bgcolor, transparent), transparent);
54
+ }
24
55
  }
25
56
 
26
57
  .#{$eccgui}-sticky__target--bottom {
27
58
  --eccgui-sticky-target-applicationoffset: 0px;
28
59
 
29
60
  bottom: calc(var(--eccgui-sticky-target-applicationoffset) + var(--eccgui-sticky-target-localoffset, 0px));
61
+
62
+ &[class*="#{$eccgui}-sticky__target--maingapfill"]:before {
63
+ top: 100%;
64
+ }
65
+
66
+ &[class*="#{$eccgui}-sticky__target--secondarygapfill"]:after {
67
+ bottom: 100%;
68
+ }
69
+
70
+ &.#{$eccgui}-sticky__target--maingapfill-gradient:before {
71
+ background: linear-gradient(var(--eccgui-sticky-target-bgcolor, 90%, transparent), transparent);
72
+ }
73
+
74
+ &.#{$eccgui}-sticky__target--secondarygapfill-gradient:after {
75
+ background: linear-gradient(transparent, var(--eccgui-sticky-target-bgcolor, transparent));
76
+ }
30
77
  }
31
78
 
32
79
  .#{$eccgui}-sticky__target--bg-card {
33
- background-color: $card-background-color;
80
+ --eccgui-sticky-target-bgcolor: #{$card-background-color};
34
81
 
35
82
  .#{$eccgui}-card.#{$eccgui}-intent--primary & {
36
- background-color: color.mix($eccgui-color-primary, $card-background-color, 5%);
83
+ --eccgui-sticky-target-bgcolor: #{color.mix($eccgui-color-primary, $card-background-color, 5%)};
37
84
  }
38
85
  .#{$eccgui}-card.#{$eccgui}-intent--accent & {
39
- background-color: color.mix($eccgui-color-accent, $card-background-color, 10%);
86
+ --eccgui-sticky-target-bgcolor: #{color.mix($eccgui-color-accent, $card-background-color, 10%)};
40
87
  }
41
88
  .#{$eccgui}-card.#{$eccgui}-intent--success & {
42
- background-color: $eccgui-color-success-background;
89
+ --eccgui-sticky-target-bgcolor: #{$eccgui-color-success-background};
43
90
  }
44
91
  .#{$eccgui}-card.#{$eccgui}-intent--info & {
45
- background-color: $eccgui-color-info-background;
92
+ --eccgui-sticky-target-bgcolor: #{$eccgui-color-info-background};
46
93
  }
47
94
  .#{$eccgui}-card.#{$eccgui}-intent--warning & {
48
- background-color: $eccgui-color-warning-background;
95
+ --eccgui-sticky-target-bgcolor: #{$eccgui-color-warning-background};
49
96
  }
50
97
  .#{$eccgui}-card.#{$eccgui}-intent--danger & {
51
- background-color: $eccgui-color-danger-background;
98
+ --eccgui-sticky-target-bgcolor: #{$eccgui-color-danger-background};
52
99
  }
53
100
 
54
101
  .#{$eccgui}-card.#{$ns}-interactive:hover & {
55
- background-color: $button-background-color-hover;
102
+ --eccgui-sticky-target-bgcolor: #{$button-background-color-hover};
56
103
  }
57
104
 
58
105
  .#{$eccgui}-card.#{$ns}-selected & {
59
- background-color: $card-selected-background-color;
106
+ --eccgui-sticky-target-bgcolor: #{$card-selected-background-color};
60
107
  }
61
108
 
62
109
  .#{$eccgui}-card--elevated & {
63
- background-color: $button-background-color-active;
110
+ --eccgui-sticky-target-bgcolor: #{$button-background-color-active};
64
111
  }
65
112
  }
66
113
 
67
114
  .#{$eccgui}-sticky__target--bg-application {
68
- background-color: $eccgui-color-application-background;
115
+ --eccgui-sticky-target-bgcolor: #{$eccgui-color-application-background};
116
+ }
117
+
118
+ .#{$eccgui}-sticky__target--issticky {
119
+ &[class*="#{$eccgui}-sticky__target--maingapfill"]:before,
120
+ &[class*="#{$eccgui}-sticky__target--secondarygapfill"]:after {
121
+ content: "";
122
+ }
123
+ }
124
+
125
+ .#{$eccgui}-sticky__target--maingapfill-full:before,
126
+ .#{$eccgui}-sticky__target--secondarygapfill-full:after {
127
+ background: var(--eccgui-sticky-target-bgcolor, transparent);
69
128
  }
@@ -37,6 +37,9 @@ $input-button-height-small: math.div($eccgui-size-textfield-height-small, $eccgu
37
37
  // fixes
38
38
 
39
39
  .#{$ns}-input-group {
40
+ // fix for z-index rule of input group left icon
41
+ z-index: 0;
42
+
40
43
  // fix for correct fill/fullWidth option
41
44
  display: inline-block;
42
45
  &.#{$ns}-fill {