@fluid-topics/ft-floating-menu 1.0.50 → 1.0.52

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 limitValueBetween;
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,47 @@ 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
+ switch (this.horizontalAlignment) {
112
+ case "left":
113
+ left = this.actionButton.offsetLeft;
114
+ break;
115
+ case "right":
116
+ left = this.actionButton.offsetLeft + buttonWidth - menuWidth;
117
+ break;
118
+ case "center":
119
+ left = this.actionButton.offsetLeft + (buttonWidth / 2) - (menuWidth / 2);
120
+ break;
121
+ }
122
+ switch (this.verticalAlignment) {
123
+ case "bottom":
124
+ top = this.actionButton.offsetTop + buttonHeight + 4;
125
+ break;
126
+ case "top":
127
+ top = this.actionButton.offsetTop - menuHeight - 4;
128
+ break;
129
+ }
130
+ const style = this.menuWrapper.style;
131
+ style.left = this.limitValueBetween(left, 0, window.innerWidth - menuWidth) + "px";
132
+ style.top = this.limitValueBetween(top, 0, window.innerHeight - menuHeight) + "px";
133
+ this.menuWrapper.classList.add("ft-floating-menu--wrapper-positioned");
134
+ }
135
+ limitValueBetween(value, min, max) {
136
+ return Math.max(min, Math.min(value, max));
137
+ }
94
138
  }
95
139
  FtFloatingMenu.elementDefinitions = {
96
140
  "ft-button": FtButton,
@@ -108,11 +152,14 @@ __decorate([
108
152
  query(".ft-floating-menu")
109
153
  ], FtFloatingMenu.prototype, "container", void 0);
110
154
  __decorate([
111
- query(".ft-floating-menu--options")
112
- ], FtFloatingMenu.prototype, "menuContainer", void 0);
155
+ query(".ft-floating-menu--wrapper")
156
+ ], FtFloatingMenu.prototype, "menuWrapper", void 0);
157
+ __decorate([
158
+ query("#ft-floating-menu-options")
159
+ ], FtFloatingMenu.prototype, "menuContent", void 0);
113
160
  __decorate([
114
- query("ft-button")
115
- ], FtFloatingMenu.prototype, "button", void 0);
161
+ query("#actions-button")
162
+ ], FtFloatingMenu.prototype, "actionButton", void 0);
116
163
  __decorate([
117
164
  property()
118
165
  ], FtFloatingMenu.prototype, "label", void 0);