gd-bs 6.6.90 → 6.6.92
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.
- package/build/bs.js +1 -1
- package/build/components/alert/index.js +2 -2
- package/build/components/button/index.js +13 -3
- package/build/components/custom-element.js +529 -0
- package/build/components/dropdown/index.js +30 -32
- package/build/components/floating-ui/index.js +375 -0
- package/build/components/index.js +4 -0
- package/build/components/modal/index.js +8 -2
- package/build/components/nav/index.js +7 -7
- package/build/components/nav/templates.js +1 -1
- package/build/components/popover/index.js +37 -201
- package/build/components/tooltip/index.js +40 -117
- package/build/custom-elements.js +46 -0
- package/build/index-icons.js +5 -5
- package/build/index.js +5 -5
- package/build/render.js +581 -0
- package/dev.html +229 -0
- package/dist/gd-bs-icons.js +1 -1
- package/dist/gd-bs-icons.js.LICENSE.txt +20 -216
- package/dist/gd-bs-icons.min.js +1 -1
- package/dist/gd-bs.d.ts +113 -150
- package/dist/gd-bs.js +1 -1
- package/dist/gd-bs.js.LICENSE.txt +20 -216
- package/dist/gd-bs.min.js +1 -1
- package/index.html +9 -3
- package/indexv2.html +572 -0
- package/package.json +5 -5
- package/pre-build.js +7 -0
- package/src/bs.scss +2 -2
- package/src/components/alert/index.ts +3 -3
- package/src/components/button/index.ts +12 -3
- package/src/components/custom-element.ts +532 -0
- package/src/components/dropdown/index.ts +30 -36
- package/src/components/dropdown/types.d.ts +4 -4
- package/src/components/floating-ui/index.ts +392 -0
- package/src/components/floating-ui/types.d.ts +73 -0
- package/src/components/form/controlTypes.d.ts +3 -3
- package/src/components/index.ts +6 -1
- package/src/components/modal/index.ts +10 -4
- package/src/components/modal/types.d.ts +3 -2
- package/src/components/nav/index.ts +7 -7
- package/src/components/nav/templates.ts +1 -1
- package/src/components/nav/types.d.ts +1 -0
- package/src/components/navbar/types.d.ts +2 -2
- package/src/components/popover/index.ts +39 -205
- package/src/components/popover/types.d.ts +12 -45
- package/src/components/tooltip/index.ts +33 -110
- package/src/components/tooltip/types.d.ts +9 -45
- package/src/components/tooltipGroup/types.d.ts +3 -2
- package/src/components/types.d.ts +0 -47
- package/src/custom-elements.js +46 -0
- package/src/index-icons.d.ts +1 -3
- package/src/index-icons.ts +4 -4
- package/src/index.d.ts +2 -2
- package/src/index.ts +4 -4
- package/src/render.ts +583 -0
- package/src/styles/_core.scss +0 -2
- package/src/styles/_custom.scss +3 -8
- package/src/styles/_floating-ui.scss +275 -0
- package/src/styles/_tippy.scss +0 -249
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { IDropdown, IDropdownItem, IDropdownProps } from "./types";
|
|
2
2
|
import { ICheckboxGroup, ICheckboxGroupItem } from "../checkboxGroup/types";
|
|
3
|
-
import {
|
|
3
|
+
import { IFloatingUI } from "../floating-ui/types";
|
|
4
4
|
import { Base } from "../base";
|
|
5
5
|
import { ButtonClassNames, ButtonTypes } from "../button";
|
|
6
6
|
import { CheckboxGroup, CheckboxGroupTypes } from "../checkboxGroup"
|
|
7
|
-
import {
|
|
7
|
+
import { FloatingUI, FloatingUIPlacements, FloatingUITypes } from "../floating-ui";
|
|
8
8
|
import { DropdownFormItem } from "./formItem";
|
|
9
9
|
import { DropdownItem } from "./item";
|
|
10
10
|
import { HTML, HTMLForm, HTMLNavItem, HTMLSplit } from "./templates";
|
|
@@ -12,7 +12,7 @@ import { HTML, HTMLForm, HTMLNavItem, HTMLSplit } from "./templates";
|
|
|
12
12
|
/**
|
|
13
13
|
* Dropdown Types
|
|
14
14
|
*/
|
|
15
|
-
export const DropdownPlacements =
|
|
15
|
+
export const DropdownPlacements = FloatingUIPlacements;
|
|
16
16
|
export const DropdownTypes = ButtonTypes;
|
|
17
17
|
|
|
18
18
|
// Gets the template
|
|
@@ -38,9 +38,9 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
38
38
|
private _autoSelect: boolean = null;
|
|
39
39
|
private _cb: ICheckboxGroup = null;
|
|
40
40
|
private _elMenu: HTMLElement;
|
|
41
|
+
private _floatingUI: IFloatingUI = null;
|
|
41
42
|
private _initFl: boolean = false;
|
|
42
43
|
private _items: Array<DropdownFormItem | DropdownItem> = null;
|
|
43
|
-
private _popover: IPopover = null;
|
|
44
44
|
|
|
45
45
|
// Constructor
|
|
46
46
|
constructor(props: IDropdownProps, template: string = GetHTML(props)) {
|
|
@@ -213,64 +213,58 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
213
213
|
let toggle = this.el.querySelector(".dropdown-toggle") as HTMLElement;
|
|
214
214
|
if (toggle && this._elMenu) {
|
|
215
215
|
// Set the type, based on the current dropdown type
|
|
216
|
-
let popoverType =
|
|
216
|
+
let popoverType = FloatingUITypes.LightBorder;
|
|
217
217
|
switch (this.props.type) {
|
|
218
218
|
case DropdownTypes.Danger:
|
|
219
219
|
case DropdownTypes.OutlineDanger:
|
|
220
|
-
popoverType =
|
|
220
|
+
popoverType = FloatingUITypes.Danger;
|
|
221
221
|
break;
|
|
222
222
|
case DropdownTypes.Dark:
|
|
223
223
|
case DropdownTypes.OutlineDark:
|
|
224
|
-
popoverType =
|
|
224
|
+
popoverType = FloatingUITypes.Dark;
|
|
225
225
|
break;
|
|
226
226
|
case DropdownTypes.Info:
|
|
227
227
|
case DropdownTypes.OutlineInfo:
|
|
228
|
-
popoverType =
|
|
228
|
+
popoverType = FloatingUITypes.Info;
|
|
229
229
|
break;
|
|
230
230
|
case DropdownTypes.Light:
|
|
231
231
|
case DropdownTypes.OutlineLight:
|
|
232
232
|
case DropdownTypes.Link:
|
|
233
233
|
case DropdownTypes.OutlineLink:
|
|
234
|
-
popoverType =
|
|
234
|
+
popoverType = FloatingUITypes.Light;
|
|
235
235
|
break;
|
|
236
236
|
case DropdownTypes.Primary:
|
|
237
237
|
case DropdownTypes.OutlinePrimary:
|
|
238
|
-
popoverType =
|
|
238
|
+
popoverType = FloatingUITypes.Primary;
|
|
239
239
|
break;
|
|
240
240
|
case DropdownTypes.Secondary:
|
|
241
241
|
case DropdownTypes.OutlineSecondary:
|
|
242
|
-
popoverType =
|
|
242
|
+
popoverType = FloatingUITypes.Secondary;
|
|
243
243
|
break;
|
|
244
244
|
case DropdownTypes.Success:
|
|
245
245
|
case DropdownTypes.OutlineSuccess:
|
|
246
|
-
popoverType =
|
|
246
|
+
popoverType = FloatingUITypes.Success;
|
|
247
247
|
break;
|
|
248
248
|
case DropdownTypes.Warning:
|
|
249
249
|
case DropdownTypes.OutlineWarning:
|
|
250
|
-
popoverType =
|
|
250
|
+
popoverType = FloatingUITypes.Warning;
|
|
251
251
|
break;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
// Create the
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
254
|
+
// Create the menu
|
|
255
|
+
this._floatingUI = FloatingUI({
|
|
256
|
+
className: "floating-dropdown",
|
|
257
|
+
elContent: this._elMenu,
|
|
258
|
+
elTarget: toggle,
|
|
259
|
+
placement: typeof (this.props.placement) === "number" ? this.props.placement : FloatingUIPlacements.BottomStart,
|
|
260
|
+
theme: popoverType,
|
|
259
261
|
options: {
|
|
260
262
|
arrow: false,
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
flip: true,
|
|
264
|
+
shift: true,
|
|
265
|
+
trigger: "click"
|
|
263
266
|
}
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// Call the render event
|
|
267
|
-
props = this.props.onMenuRendering ? this.props.onMenuRendering(props) : props;
|
|
268
|
-
|
|
269
|
-
// Create a popover to display the menu
|
|
270
|
-
this._popover = Popover(props);
|
|
271
|
-
|
|
272
|
-
// Set the popover content
|
|
273
|
-
this._popover.setContent(this._elMenu);
|
|
267
|
+
});
|
|
274
268
|
}
|
|
275
269
|
}
|
|
276
270
|
|
|
@@ -610,10 +604,10 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
610
604
|
get isMulti(): boolean { return this.props.multi; }
|
|
611
605
|
|
|
612
606
|
// Returns true if the dropdown menu is visible
|
|
613
|
-
get isVisible(): boolean { return this.
|
|
607
|
+
get isVisible(): boolean { return this._floatingUI ? this._floatingUI.isVisible : false; }
|
|
614
608
|
|
|
615
|
-
// The
|
|
616
|
-
get
|
|
609
|
+
// The floating ui menu
|
|
610
|
+
get floatingUI(): IFloatingUI { return this._floatingUI; }
|
|
617
611
|
|
|
618
612
|
// Sets the dropdown items
|
|
619
613
|
setItems(newItems: Array<IDropdownItem> = []) {
|
|
@@ -653,7 +647,7 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
653
647
|
}
|
|
654
648
|
|
|
655
649
|
// Sets the label of the dropdown
|
|
656
|
-
setLabel(value: string) {
|
|
650
|
+
setLabel(value: string = "") {
|
|
657
651
|
// Get the dropdown
|
|
658
652
|
let ddl = this.el.querySelector(".dropdown-toggle");
|
|
659
653
|
if (ddl) {
|
|
@@ -750,7 +744,7 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
750
744
|
// See if we are updating the label
|
|
751
745
|
if (this.props.updateLabel) {
|
|
752
746
|
// See if a value exists
|
|
753
|
-
if (value) {
|
|
747
|
+
if (value && typeof (value) === "string") {
|
|
754
748
|
// Set the label
|
|
755
749
|
this.setLabel(value);
|
|
756
750
|
}
|
|
@@ -771,7 +765,7 @@ class _Dropdown extends Base<IDropdownProps> implements IDropdown {
|
|
|
771
765
|
// Toggles the menu
|
|
772
766
|
toggle() {
|
|
773
767
|
// Toggle the popover
|
|
774
|
-
this.
|
|
768
|
+
this._floatingUI ? this._floatingUI.toggle() : null;
|
|
775
769
|
}
|
|
776
770
|
}
|
|
777
771
|
export const Dropdown = (props: IDropdownProps, template?: string): IDropdown => { return new _Dropdown(props, template); }
|
|
@@ -48,12 +48,12 @@ export const Dropdown: (props: IDropdownProps, template?: string) => IDropdown;
|
|
|
48
48
|
|
|
49
49
|
import { IBaseProps } from "../types";
|
|
50
50
|
import { IButtonTypes } from "../button/types";
|
|
51
|
-
import {
|
|
51
|
+
import { IFloatingUI, IFloatingUIProps, IFloatingUIPlacements } from "../floating-ui/types";
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Dropdown Placements
|
|
55
55
|
*/
|
|
56
|
-
export const DropdownPlacements:
|
|
56
|
+
export const DropdownPlacements: IFloatingUIPlacements;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Dropdown Types
|
|
@@ -83,7 +83,7 @@ export interface IDropdown {
|
|
|
83
83
|
isMulti: boolean;
|
|
84
84
|
|
|
85
85
|
/** The popover menu. */
|
|
86
|
-
|
|
86
|
+
floatingUI: IFloatingUI;
|
|
87
87
|
|
|
88
88
|
/** Updates the dropdown items. */
|
|
89
89
|
setItems: (items: Array<IDropdownItem>) => void;
|
|
@@ -152,7 +152,7 @@ export interface IDropdownProps extends IBaseProps<IDropdown> {
|
|
|
152
152
|
multi?: boolean;
|
|
153
153
|
navFl?: boolean;
|
|
154
154
|
onChange?: (item?: IDropdownItem | Array<IDropdownItem>, ev?: Event) => void;
|
|
155
|
-
onMenuRendering?: (props:
|
|
155
|
+
onMenuRendering?: (props: IFloatingUIProps) => IFloatingUIProps;
|
|
156
156
|
placement?: number;
|
|
157
157
|
required?: boolean;
|
|
158
158
|
title?: string;
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { arrow, autoPlacement, computePosition, flip, hide, inline, offset, shift, size, ComputePositionConfig } from "@floating-ui/dom";
|
|
2
|
+
import { setClassNames } from "../common";
|
|
3
|
+
import { IFloatingUIProps, IFloatingUI } from "./types";
|
|
4
|
+
export * as FloatingUILib from "@floating-ui/dom";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Floating UI Placements
|
|
9
|
+
*/
|
|
10
|
+
export enum FloatingUIPlacements {
|
|
11
|
+
Auto = 1,
|
|
12
|
+
AutoStart = 2,
|
|
13
|
+
AutoEnd = 3,
|
|
14
|
+
Bottom = 4,
|
|
15
|
+
BottomStart = 5,
|
|
16
|
+
BottomEnd = 6,
|
|
17
|
+
Left = 7,
|
|
18
|
+
LeftStart = 8,
|
|
19
|
+
LeftEnd = 9,
|
|
20
|
+
Right = 10,
|
|
21
|
+
RightStart = 11,
|
|
22
|
+
RightEnd = 12,
|
|
23
|
+
Top = 13,
|
|
24
|
+
TopStart = 14,
|
|
25
|
+
TopEnd = 15
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Floating UI Types
|
|
30
|
+
*/
|
|
31
|
+
export enum FloatingUITypes {
|
|
32
|
+
Danger = 1,
|
|
33
|
+
Dark = 2,
|
|
34
|
+
Info = 3,
|
|
35
|
+
Light = 4,
|
|
36
|
+
LightBorder = 5,
|
|
37
|
+
Material = 6,
|
|
38
|
+
Primary = 7,
|
|
39
|
+
Secondary = 8,
|
|
40
|
+
Success = 9,
|
|
41
|
+
Translucent = 10,
|
|
42
|
+
Warning = 11
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Floating UI Element
|
|
47
|
+
*/
|
|
48
|
+
class _FloatingUI {
|
|
49
|
+
private _elArrow: HTMLElement = null;
|
|
50
|
+
private _elTarget: HTMLElement = null;
|
|
51
|
+
private _elContent: HTMLElement = null;
|
|
52
|
+
private _options: ComputePositionConfig = null;
|
|
53
|
+
private _props: IFloatingUIProps = null;
|
|
54
|
+
|
|
55
|
+
// Static events
|
|
56
|
+
private static Events = [];
|
|
57
|
+
private static EventsCreated = false;
|
|
58
|
+
private static ScrollEvents = [];
|
|
59
|
+
|
|
60
|
+
// Constructor
|
|
61
|
+
constructor(props: IFloatingUIProps) {
|
|
62
|
+
this._elTarget = props.elTarget;
|
|
63
|
+
this._props = props;
|
|
64
|
+
|
|
65
|
+
// Create the content element
|
|
66
|
+
this._elContent = document.createElement("div");
|
|
67
|
+
this._elContent.classList.add("bs");
|
|
68
|
+
this._elContent.classList.add("floating-ui");
|
|
69
|
+
this._elContent.appendChild(props.elContent);
|
|
70
|
+
this._elContent.setAttribute("data-theme", this.getTheme(this._props.theme));
|
|
71
|
+
setClassNames(this._elContent, this._props.className);
|
|
72
|
+
|
|
73
|
+
// Add the events
|
|
74
|
+
this.addEvents(props.options?.trigger);
|
|
75
|
+
|
|
76
|
+
// Create the floating ui element
|
|
77
|
+
this.create();
|
|
78
|
+
|
|
79
|
+
// Set the visibility
|
|
80
|
+
this._props.show ? this.show() : this.hide();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private addEvents(trigger: string = "") {
|
|
84
|
+
// Events
|
|
85
|
+
if (trigger.indexOf("mouse") >= 0) {
|
|
86
|
+
this._elTarget.addEventListener("mouseenter", () => { this.show(); });
|
|
87
|
+
this._elTarget.addEventListener("mouseleave", () => { this.hide(); });
|
|
88
|
+
}
|
|
89
|
+
if (trigger.indexOf("focus") >= 0) {
|
|
90
|
+
this._elTarget.addEventListener("focus", () => { this.show(); });
|
|
91
|
+
this._elTarget.addEventListener("blur", () => { this.hide(); });
|
|
92
|
+
}
|
|
93
|
+
if (trigger.indexOf("click") >= 0) {
|
|
94
|
+
this._elTarget.addEventListener("click", (ev) => {
|
|
95
|
+
// Call the event
|
|
96
|
+
this.isVisible ? this.hide() : this.show();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Add the events
|
|
101
|
+
_FloatingUI.Events.push((ev: Event) => {
|
|
102
|
+
// See if it's outside the target element
|
|
103
|
+
if (!this._elTarget.contains(ev.target as any)) {
|
|
104
|
+
// Hide the element
|
|
105
|
+
this.hide();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
_FloatingUI.ScrollEvents.push((ev: Event) => {
|
|
109
|
+
// Refresh the content
|
|
110
|
+
this.refresh();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Ensure the click event exists
|
|
114
|
+
if (!_FloatingUI.EventsCreated) {
|
|
115
|
+
// Create the event
|
|
116
|
+
document.addEventListener("click", (ev) => {
|
|
117
|
+
// Wait for the other events to run
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
// Parse the events
|
|
120
|
+
_FloatingUI.Events.forEach(fnEvent => {
|
|
121
|
+
// Call the event
|
|
122
|
+
fnEvent(ev);
|
|
123
|
+
});
|
|
124
|
+
}, 10);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Create the scroll event
|
|
128
|
+
document.addEventListener("scroll", (ev) => {
|
|
129
|
+
// Wait for the other events to run
|
|
130
|
+
setTimeout(() => {
|
|
131
|
+
// Parse the events
|
|
132
|
+
_FloatingUI.ScrollEvents.forEach(fnEvent => {
|
|
133
|
+
// Call the event
|
|
134
|
+
fnEvent(ev);
|
|
135
|
+
});
|
|
136
|
+
}, 10);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Set the flag
|
|
140
|
+
_FloatingUI.EventsCreated = true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Creates the floating ui
|
|
145
|
+
private create() {
|
|
146
|
+
let placement = this.getPlacement(this._props.placement);
|
|
147
|
+
let middleware = this.getMiddleware(placement);
|
|
148
|
+
|
|
149
|
+
// See if we are adding an arrow
|
|
150
|
+
if (this._props.options?.arrow) {
|
|
151
|
+
// Create the element
|
|
152
|
+
this._elArrow = document.createElement("div");
|
|
153
|
+
this._elArrow.classList.add("arrow");
|
|
154
|
+
this._elContent.appendChild(this._elArrow);
|
|
155
|
+
|
|
156
|
+
// Add the plugin
|
|
157
|
+
middleware.push(arrow({ element: this._elArrow }));
|
|
158
|
+
middleware = [offset(6)].concat(middleware);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Set the options
|
|
162
|
+
this._options = {
|
|
163
|
+
middleware,
|
|
164
|
+
placement: placement.placement as any
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Returns the plugins
|
|
169
|
+
private getMiddleware(placement: { autoPlacement: boolean; placement: string; }) {
|
|
170
|
+
let middleware = [];
|
|
171
|
+
|
|
172
|
+
// See if we are adding the offset option
|
|
173
|
+
if (this._props.options?.offset) {
|
|
174
|
+
middleware.push(offset(this._props.options.offset));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// See if we are adding the auto placement option
|
|
178
|
+
if (this._props.options?.autoPlacement || placement.autoPlacement) {
|
|
179
|
+
middleware.push(autoPlacement(this._props.options.autoPlacement));
|
|
180
|
+
}
|
|
181
|
+
// Else, see if we are adding the flip option
|
|
182
|
+
else if (this._props.options?.flip) {
|
|
183
|
+
middleware.push(flip());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// See if we are adding the hide option
|
|
187
|
+
if (this._props.options?.hide) {
|
|
188
|
+
middleware.push(hide(this._props.options.hide));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// See if we are adding the inline option
|
|
192
|
+
if (this._props.options?.inline) {
|
|
193
|
+
middleware.push(inline(this._props.options.inline));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// See if we are adding the shift option
|
|
197
|
+
if (this._props.options?.shift) {
|
|
198
|
+
middleware.push(shift(this._props.options?.shift));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// See if we are adding the size option
|
|
202
|
+
if (this._props.options?.size) {
|
|
203
|
+
middleware.push(size(this._props.options?.size));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Return the middle ware
|
|
207
|
+
return middleware;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Returns the placement information
|
|
211
|
+
private getPlacement(placementValue: number): { autoPlacement: boolean; placement: string; } {
|
|
212
|
+
let autoPlacement = false;
|
|
213
|
+
let placement = "top-end";
|
|
214
|
+
|
|
215
|
+
switch (placementValue) {
|
|
216
|
+
// Auto
|
|
217
|
+
case FloatingUIPlacements.Auto:
|
|
218
|
+
autoPlacement = true;
|
|
219
|
+
break;
|
|
220
|
+
case FloatingUIPlacements.AutoEnd:
|
|
221
|
+
placement = 'end';
|
|
222
|
+
autoPlacement = true;
|
|
223
|
+
break;
|
|
224
|
+
case FloatingUIPlacements.AutoStart:
|
|
225
|
+
placement = 'start';
|
|
226
|
+
autoPlacement = true;
|
|
227
|
+
break;
|
|
228
|
+
// Bottom
|
|
229
|
+
case FloatingUIPlacements.Bottom:
|
|
230
|
+
placement = "bottom";
|
|
231
|
+
break;
|
|
232
|
+
case FloatingUIPlacements.BottomEnd:
|
|
233
|
+
placement = "bottom-end";
|
|
234
|
+
break;
|
|
235
|
+
case FloatingUIPlacements.BottomStart:
|
|
236
|
+
placement = "bottom-start";
|
|
237
|
+
break;
|
|
238
|
+
// Left
|
|
239
|
+
case FloatingUIPlacements.Left:
|
|
240
|
+
placement = "left";
|
|
241
|
+
break;
|
|
242
|
+
case FloatingUIPlacements.LeftEnd:
|
|
243
|
+
placement = "left-end";
|
|
244
|
+
break;
|
|
245
|
+
case FloatingUIPlacements.LeftStart:
|
|
246
|
+
placement = "left-start";
|
|
247
|
+
break;
|
|
248
|
+
// Right
|
|
249
|
+
case FloatingUIPlacements.Right:
|
|
250
|
+
placement = "right";
|
|
251
|
+
break;
|
|
252
|
+
case FloatingUIPlacements.RightEnd:
|
|
253
|
+
placement = "right-end";
|
|
254
|
+
break;
|
|
255
|
+
case FloatingUIPlacements.RightStart:
|
|
256
|
+
placement = "right-start";
|
|
257
|
+
break;
|
|
258
|
+
// Top
|
|
259
|
+
case FloatingUIPlacements.Top:
|
|
260
|
+
placement = "top";
|
|
261
|
+
break;
|
|
262
|
+
case FloatingUIPlacements.TopEnd:
|
|
263
|
+
placement = "top-end";
|
|
264
|
+
break;
|
|
265
|
+
case FloatingUIPlacements.TopStart:
|
|
266
|
+
placement = "top-start";
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Return the placement
|
|
271
|
+
return { autoPlacement, placement };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Returns the theme
|
|
275
|
+
private getTheme(themeValue: number) {
|
|
276
|
+
let theme = null;
|
|
277
|
+
|
|
278
|
+
// Set the theme
|
|
279
|
+
switch (themeValue) {
|
|
280
|
+
// Dark
|
|
281
|
+
case FloatingUITypes.Dark:
|
|
282
|
+
theme = "dark";
|
|
283
|
+
break;
|
|
284
|
+
// Danger
|
|
285
|
+
case FloatingUITypes.Danger:
|
|
286
|
+
theme = "danger";
|
|
287
|
+
break;
|
|
288
|
+
// Info
|
|
289
|
+
case FloatingUITypes.Info:
|
|
290
|
+
theme = "info";
|
|
291
|
+
break;
|
|
292
|
+
// Light
|
|
293
|
+
case FloatingUITypes.Light:
|
|
294
|
+
theme = "light";
|
|
295
|
+
break;
|
|
296
|
+
case FloatingUITypes.LightBorder:
|
|
297
|
+
theme = "light-border";
|
|
298
|
+
break;
|
|
299
|
+
// Material
|
|
300
|
+
case FloatingUITypes.Material:
|
|
301
|
+
theme = "material";
|
|
302
|
+
break;
|
|
303
|
+
// Primary
|
|
304
|
+
case FloatingUITypes.Primary:
|
|
305
|
+
theme = "primary";
|
|
306
|
+
break;
|
|
307
|
+
// Secondary
|
|
308
|
+
case FloatingUITypes.Secondary:
|
|
309
|
+
theme = "secondary";
|
|
310
|
+
break;
|
|
311
|
+
// Success
|
|
312
|
+
case FloatingUITypes.Success:
|
|
313
|
+
theme = "success";
|
|
314
|
+
break;
|
|
315
|
+
// Translucent
|
|
316
|
+
case FloatingUITypes.Translucent:
|
|
317
|
+
theme = "translucent";
|
|
318
|
+
break;
|
|
319
|
+
// Warning
|
|
320
|
+
case FloatingUITypes.Warning:
|
|
321
|
+
theme = "warning";
|
|
322
|
+
break;
|
|
323
|
+
// Default - Light Border
|
|
324
|
+
default:
|
|
325
|
+
theme = "light-border";
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Return the theme
|
|
330
|
+
return theme;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Refresh the element position
|
|
334
|
+
private refresh() {
|
|
335
|
+
// Create the floating ui
|
|
336
|
+
computePosition(this._elTarget, this._elContent, this._options).then(({ x, y, middlewareData }) => {
|
|
337
|
+
// Update the location
|
|
338
|
+
Object.assign(this._elContent.style, {
|
|
339
|
+
left: `${x}px`,
|
|
340
|
+
top: `${y}px`
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// See if the arrow exists
|
|
344
|
+
if (this._elArrow) {
|
|
345
|
+
let arrowX = middlewareData.arrow.x;
|
|
346
|
+
let arrowY = middlewareData.arrow.y;
|
|
347
|
+
let side = {
|
|
348
|
+
top: 'bottom',
|
|
349
|
+
right: 'left',
|
|
350
|
+
bottom: 'top',
|
|
351
|
+
left: 'right'
|
|
352
|
+
}[middlewareData.offset?.placement || this._options.placement.split('-')[0]]
|
|
353
|
+
|
|
354
|
+
// Update the location
|
|
355
|
+
Object.assign(this._elArrow.style, {
|
|
356
|
+
left: arrowX != null ? `${arrowX}px` : '',
|
|
357
|
+
top: arrowY != null ? `${arrowY}px` : '',
|
|
358
|
+
right: '',
|
|
359
|
+
bottom: '',
|
|
360
|
+
[side]: '-4px'
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Public Methods
|
|
368
|
+
*/
|
|
369
|
+
|
|
370
|
+
setContent(el) { this._elContent = el; }
|
|
371
|
+
|
|
372
|
+
// Hides the content
|
|
373
|
+
hide() {
|
|
374
|
+
// Remove it from the document
|
|
375
|
+
this._elContent.classList.add("d-none");
|
|
376
|
+
if (document.body.contains(this._elContent)) { document.body.removeChild(this._elContent); }
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Determines if the content is visible
|
|
380
|
+
get isVisible(): boolean { return !this._elContent.classList.contains("d-none"); }
|
|
381
|
+
|
|
382
|
+
// Shows the content
|
|
383
|
+
show() {
|
|
384
|
+
// Append it to the document
|
|
385
|
+
this._elContent.classList.remove("d-none");
|
|
386
|
+
if (!document.body.contains(this._elContent)) { document.body.appendChild(this._elContent); this.refresh(); }
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Toggles the floating ui
|
|
390
|
+
toggle() { this.isVisible ? this.hide() : this.show(); }
|
|
391
|
+
}
|
|
392
|
+
export const FloatingUI = (props: IFloatingUIProps): IFloatingUI => { return new _FloatingUI(props); }
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export const FloatingUI: (props: IFloatingUIProps) => IFloatingUI;
|
|
2
|
+
|
|
3
|
+
import { IBaseProps } from "../types";
|
|
4
|
+
|
|
5
|
+
export const FloatingUIPlacements: IFloatingUIPlacements;
|
|
6
|
+
|
|
7
|
+
export interface IFloatingUI {
|
|
8
|
+
hide: () => void;
|
|
9
|
+
isVisible: boolean;
|
|
10
|
+
setContent: (el: string | Element) => void;
|
|
11
|
+
show: () => void;
|
|
12
|
+
toggle: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface IFloatingUIOptions {
|
|
16
|
+
arrow?: boolean;
|
|
17
|
+
autoPlacement?: boolean | any;
|
|
18
|
+
className?: string;
|
|
19
|
+
content?: string;
|
|
20
|
+
flip?: boolean | any;
|
|
21
|
+
hide?: boolean | any;
|
|
22
|
+
inline?: boolean | any;
|
|
23
|
+
offset?: number | any;
|
|
24
|
+
shift?: boolean | any;
|
|
25
|
+
size?: boolean | any;
|
|
26
|
+
trigger?: 'click' | 'focus' | 'mouse';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface IFloatingUIProps extends IBaseProps<IFloatingUI> {
|
|
30
|
+
elContent: HTMLElement;
|
|
31
|
+
elTarget: HTMLElement;
|
|
32
|
+
options?: IFloatingUIOptions;
|
|
33
|
+
placement?: number;
|
|
34
|
+
show?: boolean;
|
|
35
|
+
theme?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Floating UI Placements
|
|
40
|
+
*/
|
|
41
|
+
export type IFloatingUIPlacements = {
|
|
42
|
+
Auto: number;
|
|
43
|
+
AutoStart: number;
|
|
44
|
+
AutoEnd: number;
|
|
45
|
+
Bottom: number;
|
|
46
|
+
BottomStart: number;
|
|
47
|
+
BottomEnd: number;
|
|
48
|
+
Left: number;
|
|
49
|
+
LeftStart: number;
|
|
50
|
+
LeftEnd: number;
|
|
51
|
+
Right: number;
|
|
52
|
+
RightStart: number;
|
|
53
|
+
RightEnd: number;
|
|
54
|
+
Top: number;
|
|
55
|
+
TopStart: number;
|
|
56
|
+
TopEnd: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Floating UI
|
|
60
|
+
*/
|
|
61
|
+
export type IFloatingUITypes = {
|
|
62
|
+
Danger: number;
|
|
63
|
+
Dark: number;
|
|
64
|
+
Info: number;
|
|
65
|
+
Light: number;
|
|
66
|
+
LightBorder: number;
|
|
67
|
+
Material: number;
|
|
68
|
+
Primary: number;
|
|
69
|
+
Secondary: number;
|
|
70
|
+
Success: number;
|
|
71
|
+
Translucent: number;
|
|
72
|
+
Warning: number;
|
|
73
|
+
}
|
|
@@ -25,7 +25,7 @@ import { ICheckboxGroup, ICheckboxGroupItem } from "../checkboxGroup/types";
|
|
|
25
25
|
import { IDropdown, IDropdownItem, IDropdownProps } from "../dropdown/types";
|
|
26
26
|
import { IInputGroup } from "../inputGroup/types";
|
|
27
27
|
import { IListBox } from "../listBox/types";
|
|
28
|
-
import {
|
|
28
|
+
import { IFloatingUIProps } from "../floating-ui/types";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Custom Controls
|
|
@@ -115,7 +115,7 @@ export interface IFormControlPropsDropdown extends IFormControlProps {
|
|
|
115
115
|
onChange?: (item: IDropdownItem, ev?: Event) => void;
|
|
116
116
|
onControlRendering?: (control: IFormControlPropsDropdown) => void | PromiseLike<IFormControlPropsDropdown>;
|
|
117
117
|
onGetValue?: (control: IFormControlPropsDropdown) => any;
|
|
118
|
-
onMenuRendering?: (props:
|
|
118
|
+
onMenuRendering?: (props: IFloatingUIProps) => IFloatingUIProps;
|
|
119
119
|
onValidate?: (control: IFormControlPropsDropdown, results: IFormControlValidationResult<IDropdownItem>) => boolean | IFormControlValidationResult<IDropdownItem>;
|
|
120
120
|
}
|
|
121
121
|
|
|
@@ -168,7 +168,7 @@ export interface IFormControlPropsMultiDropdown extends IFormControlProps {
|
|
|
168
168
|
onChange?: (item: Array<IDropdownItem>, ev?: Event) => void;
|
|
169
169
|
onControlRendering?: (control: IFormControlPropsDropdown) => void | PromiseLike<IFormControlPropsDropdown>;
|
|
170
170
|
onGetValue?: (control: IFormControlPropsDropdown) => any;
|
|
171
|
-
onMenuRendering?: (props:
|
|
171
|
+
onMenuRendering?: (props: IFloatingUIProps) => IFloatingUIProps;
|
|
172
172
|
onValidate?: (control: IFormControlPropsDropdown, results: IFormControlValidationResult<Array<IDropdownItem>>) => boolean | IFormControlValidationResult<Array<IDropdownItem>>;
|
|
173
173
|
}
|
|
174
174
|
|