@fluid-topics/ft-floating-menu 1.0.51 → 1.0.53

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.
@@ -13,13 +13,21 @@ export const FtFloatingMenuCssVariables = {
13
13
  export const styles = css `
14
14
  .ft-floating-menu {
15
15
  color: ${FtFloatingMenuCssVariables.textColor};
16
- position: relative;
17
16
  display: inline-block;
18
17
  }
19
18
 
19
+ .ft-floating-menu--wrapper {
20
+ position: absolute;
21
+ visibility: hidden;
22
+ }
23
+
24
+ .ft-floating-menu--wrapper.ft-floating-menu--wrapper-positioned {
25
+ visibility: visible;
26
+ }
27
+
20
28
  .ft-floating-menu--options {
21
29
  display: none;
22
- position: absolute;
30
+ position: relative;
23
31
  overflow: auto;
24
32
  max-width: ${FtFloatingMenuCssVariables.maxWidth};
25
33
  max-height: ${FtFloatingMenuCssVariables.maxHeight};
@@ -33,25 +41,4 @@ export const styles = css `
33
41
  .ft-floating-menu--open .ft-floating-menu--options {
34
42
  display: block;
35
43
  }
36
-
37
- .ft-floating-menu--left .ft-floating-menu--options {
38
- left: 0;
39
- }
40
-
41
- .ft-floating-menu--right .ft-floating-menu--options {
42
- right: 0;
43
- }
44
-
45
- .ft-floating-menu--center .ft-floating-menu--options {
46
- left: 50%;
47
- transform: translateX(-50%);
48
- }
49
-
50
- .ft-floating-menu--top .ft-floating-menu--options {
51
- bottom: calc(100% + 4px);
52
- }
53
-
54
- .ft-floating-menu--bottom .ft-floating-menu--options {
55
- top: calc(100% + 4px);
56
- }
57
44
  `;
@@ -2,6 +2,7 @@ import { ElementDefinitionsMap, FtLitElement } from "@fluid-topics/ft-wc-utils";
2
2
  import { FtFloatingMenuProperties, FtHorizontalAlignment, FtVerticalAlignment } from "./ft-floating-menu.properties";
3
3
  import { FtIconVariants } from "@fluid-topics/ft-icon/build/ft-icon.properties";
4
4
  import { Position } from "@fluid-topics/ft-tooltip/build/ft-tooltip.properties";
5
+ import { PropertyValues } from "lit/development";
5
6
  export declare class FloatingMenuCloseEvent extends CustomEvent<void> {
6
7
  constructor();
7
8
  }
@@ -11,15 +12,16 @@ export declare class FtFloatingMenu extends FtLitElement implements FtFloatingMe
11
12
  private menuOpen;
12
13
  forceMenuOpen: boolean;
13
14
  private container;
14
- private menuContainer;
15
- private button;
15
+ private menuWrapper;
16
+ private menuContent;
17
+ private actionButton;
16
18
  label?: string;
17
19
  tooltipPosition?: Position;
18
20
  iconVariant: FtIconVariants;
19
21
  icon: string;
20
22
  text?: string;
21
- horizontalAlignment?: FtHorizontalAlignment;
22
- verticalAlignment?: FtVerticalAlignment;
23
+ horizontalAlignment: FtHorizontalAlignment;
24
+ verticalAlignment: FtVerticalAlignment;
23
25
  disabled: boolean;
24
26
  closeMenuMatchers: string[];
25
27
  protected render(): import("lit-html").TemplateResult<1>;
@@ -30,4 +32,7 @@ export declare class FtFloatingMenu extends FtLitElement implements FtFloatingMe
30
32
  private onCloseEvent;
31
33
  private onContentClick;
32
34
  disconnectedCallback(): void;
35
+ protected contentAvailableCallback(props: PropertyValues): void;
36
+ private positionMenuWrapper;
37
+ private correctOutOfWindowPixels;
33
38
  }
@@ -24,6 +24,8 @@ class FtFloatingMenu extends FtLitElement {
24
24
  this.forceMenuOpen = false;
25
25
  this.iconVariant = FtIconVariants.fluid_topics;
26
26
  this.icon = "SHORTCUT_MENU";
27
+ this.horizontalAlignment = "left";
28
+ this.verticalAlignment = "bottom";
27
29
  this.disabled = false;
28
30
  this.closeMenuMatchers = [];
29
31
  this.hideOptions = (e) => {
@@ -34,12 +36,11 @@ class FtFloatingMenu extends FtLitElement {
34
36
  };
35
37
  }
36
38
  render() {
37
- var _a, _b;
38
39
  const classes = {
39
40
  "ft-floating-menu": true,
40
41
  "ft-floating-menu--open": this.forceMenuOpen || this.menuOpen,
41
- ["ft-floating-menu--" + ((_a = this.horizontalAlignment) !== null && _a !== void 0 ? _a : "left").toLowerCase()]: true,
42
- ["ft-floating-menu--" + ((_b = this.verticalAlignment) !== null && _b !== void 0 ? _b : "bottom").toLowerCase()]: true,
42
+ ["ft-floating-menu--" + this.horizontalAlignment.toLowerCase()]: true,
43
+ ["ft-floating-menu--" + this.verticalAlignment.toLowerCase()]: true,
43
44
  };
44
45
  return html `
45
46
  <div class="${classMap(classes)}">
@@ -56,13 +57,15 @@ class FtFloatingMenu extends FtLitElement {
56
57
  aria-expanded="${this.forceMenuOpen || this.menuOpen}">
57
58
  ${this.text}
58
59
  </ft-button>
59
- <div id="ft-floating-menu-options"
60
- class="ft-floating-menu--options"
61
- part="options"
62
- @select="${this.onClickItem}">
63
- <slot @click=${this.onContentClick}
64
- @close-ft-floating-menu=${this.onCloseEvent}
65
- ></slot>
60
+ <div class="ft-floating-menu--wrapper">
61
+ <div id="ft-floating-menu-options"
62
+ class="ft-floating-menu--options"
63
+ part="options"
64
+ @select="${this.onClickItem}">
65
+ <slot @click=${this.onContentClick}
66
+ @close-ft-floating-menu=${this.onCloseEvent}
67
+ ></slot>
68
+ </div>
66
69
  </div>
67
70
  </div>
68
71
  `;
@@ -91,6 +94,56 @@ class FtFloatingMenu extends FtLitElement {
91
94
  super.disconnectedCallback();
92
95
  document.removeEventListener("click", this.hideOptions);
93
96
  }
97
+ contentAvailableCallback(props) {
98
+ super.contentAvailableCallback(props);
99
+ if (["menuOpen"].some(p => props.has(p)) && this.menuOpen) {
100
+ this.menuWrapper.classList.remove("ft-floating-menu--wrapper-positioned");
101
+ this.positionMenuWrapper();
102
+ }
103
+ }
104
+ positionMenuWrapper() {
105
+ const menuWidth = this.menuContent.offsetWidth;
106
+ const menuHeight = this.menuContent.offsetHeight;
107
+ const buttonWidth = this.actionButton.offsetWidth;
108
+ const buttonHeight = this.actionButton.offsetHeight;
109
+ let left = 0;
110
+ let top = 0;
111
+ this.menuWrapper.style.left = "0";
112
+ this.menuWrapper.style.top = "0";
113
+ switch (this.horizontalAlignment) {
114
+ case "left":
115
+ left = this.actionButton.offsetLeft - this.menuWrapper.offsetLeft;
116
+ break;
117
+ case "right":
118
+ left = this.actionButton.offsetLeft + buttonWidth - menuWidth - this.menuWrapper.offsetLeft;
119
+ break;
120
+ case "center":
121
+ left = this.actionButton.offsetLeft + (buttonWidth / 2) - (menuWidth / 2) - this.menuWrapper.offsetLeft;
122
+ break;
123
+ }
124
+ switch (this.verticalAlignment) {
125
+ case "bottom":
126
+ top = this.actionButton.offsetTop + buttonHeight + 4 - this.menuWrapper.offsetTop;
127
+ break;
128
+ case "top":
129
+ top = this.actionButton.offsetTop - menuHeight - 4 - this.menuWrapper.offsetTop;
130
+ break;
131
+ }
132
+ const style = this.menuWrapper.style;
133
+ style.left = left + "px";
134
+ style.top = top + "px";
135
+ const boundingClientRect = this.menuWrapper.getBoundingClientRect();
136
+ let leftOutOfWindowPixels = -boundingClientRect.x;
137
+ let rightOutOfWindowPixels = (boundingClientRect.x + boundingClientRect.width) - window.innerWidth;
138
+ style.left = (left + Math.round(this.correctOutOfWindowPixels(leftOutOfWindowPixels, rightOutOfWindowPixels))) + "px";
139
+ let topOutOfWindowPixels = -boundingClientRect.y;
140
+ let bottomOutOfWindowPixels = (boundingClientRect.y + boundingClientRect.height) - window.innerHeight;
141
+ style.top = (top + Math.round(this.correctOutOfWindowPixels(topOutOfWindowPixels, bottomOutOfWindowPixels))) + "px";
142
+ this.menuWrapper.classList.add("ft-floating-menu--wrapper-positioned");
143
+ }
144
+ correctOutOfWindowPixels(leftOrTopOutOfWindowPixels, rightOrBottomOutOfWindowPixels) {
145
+ return Math.max(leftOrTopOutOfWindowPixels, Math.min(0, -rightOrBottomOutOfWindowPixels));
146
+ }
94
147
  }
95
148
  FtFloatingMenu.elementDefinitions = {
96
149
  "ft-button": FtButton,
@@ -108,11 +161,14 @@ __decorate([
108
161
  query(".ft-floating-menu")
109
162
  ], FtFloatingMenu.prototype, "container", void 0);
110
163
  __decorate([
111
- query(".ft-floating-menu--options")
112
- ], FtFloatingMenu.prototype, "menuContainer", void 0);
164
+ query(".ft-floating-menu--wrapper")
165
+ ], FtFloatingMenu.prototype, "menuWrapper", void 0);
166
+ __decorate([
167
+ query("#ft-floating-menu-options")
168
+ ], FtFloatingMenu.prototype, "menuContent", void 0);
113
169
  __decorate([
114
- query("ft-button")
115
- ], FtFloatingMenu.prototype, "button", void 0);
170
+ query("#actions-button")
171
+ ], FtFloatingMenu.prototype, "actionButton", void 0);
116
172
  __decorate([
117
173
  property()
118
174
  ], FtFloatingMenu.prototype, "label", void 0);