vira 32.4.0 → 33.0.0
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/dist/directives/index.d.ts +2 -0
- package/dist/directives/index.js +2 -0
- package/dist/directives/popover.directive.d.ts +29 -0
- package/dist/directives/popover.directive.js +45 -0
- package/dist/directives/tooltip.directive.d.ts +60 -0
- package/dist/directives/tooltip.directive.js +99 -0
- package/dist/elements/color/vira-color-picker.element.d.ts +1 -1
- package/dist/elements/color/vira-color-picker.element.js +17 -15
- package/dist/elements/index.d.ts +5 -5
- package/dist/elements/index.js +5 -5
- package/dist/elements/{pop-up → popover}/vira-menu-item.element.d.ts +4 -4
- package/dist/elements/{pop-up → popover}/vira-menu-item.element.js +3 -3
- package/dist/elements/popover/vira-menu-trigger.element.d.ts +56 -0
- package/dist/elements/{pop-up → popover}/vira-menu-trigger.element.js +19 -30
- package/dist/elements/popover/vira-menu.element.d.ts +35 -0
- package/dist/elements/popover/vira-menu.element.js +262 -0
- package/dist/elements/popover/vira-popover-trigger.element.d.ts +49 -0
- package/dist/elements/popover/vira-popover-trigger.element.js +301 -0
- package/dist/elements/popover/vira-tooltip.element.d.ts +10 -0
- package/dist/elements/popover/vira-tooltip.element.js +176 -0
- package/dist/elements/vira-drawer.element.js +1 -1
- package/dist/elements/vira-dropdown.element.d.ts +28 -12
- package/dist/elements/vira-dropdown.element.js +172 -59
- package/dist/elements/vira-form.element.js +10 -16
- package/dist/elements/vira-json-form.element.js +40 -36
- package/dist/elements/vira-modal.element.js +1 -1
- package/dist/elements/vira-tabs.element.d.ts +3 -9
- package/dist/elements/vira-tabs.element.js +5 -6
- package/dist/elements/vira-theme-switcher.element.js +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/util/anchored-popover.d.ts +40 -0
- package/dist/util/anchored-popover.js +70 -0
- package/dist/util/index.d.ts +4 -3
- package/dist/util/index.js +4 -3
- package/dist/util/{pop-up-helpers.d.ts → menu-helpers.d.ts} +4 -18
- package/dist/util/{pop-up-helpers.js → menu-helpers.js} +2 -17
- package/dist/util/popover-manager.d.ts +123 -0
- package/dist/util/popover-manager.js +412 -0
- package/dist/util/vira-dropdown-option.d.ts +30 -0
- package/dist/util/vira-dropdown-option.js +8 -0
- package/dist/util/vira-form-fields.d.ts +2 -2
- package/dist/util/vira-theme-client.d.ts +1 -1
- package/dist/util/vira-theme-client.js +3 -3
- package/package.json +2 -1
- package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +0 -45
- package/dist/elements/pop-up/vira-menu.element.d.ts +0 -36
- package/dist/elements/pop-up/vira-menu.element.js +0 -88
- package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +0 -109
- package/dist/elements/pop-up/vira-pop-up-trigger.element.js +0 -408
- package/dist/elements/vira-select.element.d.ts +0 -44
- package/dist/elements/vira-select.element.js +0 -418
- package/dist/util/pop-up-manager.d.ts +0 -200
- package/dist/util/pop-up-manager.js +0 -258
- package/dist/util/vira-select-option.d.ts +0 -31
- package/dist/util/vira-select-option.js +0 -8
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import { assert } from '@augment-vir/assert';
|
|
2
|
-
import { mapObjectValues } from '@augment-vir/common';
|
|
3
|
-
import { findOverflowAncestor } from '@augment-vir/web';
|
|
4
|
-
import { NavActivateEvent, NavDirection } from 'device-navigation';
|
|
5
|
-
import { listenToPageActivation } from 'page-active';
|
|
6
|
-
import { ListenTarget, defineTypedCustomEvent, defineTypedEvent, listenToGlobal, } from 'typed-event-target';
|
|
7
|
-
/**
|
|
8
|
-
* Used to prevent pop-ups from closing when a text input is active.
|
|
9
|
-
*
|
|
10
|
-
* @category Internal
|
|
11
|
-
*/
|
|
12
|
-
export function isInputLikeElement(element) {
|
|
13
|
-
return ((element instanceof HTMLInputElement &&
|
|
14
|
-
(element.type === 'text' ||
|
|
15
|
-
element.type === 'search' ||
|
|
16
|
-
element.type === 'email' ||
|
|
17
|
-
element.type === 'url' ||
|
|
18
|
-
element.type === 'tel' ||
|
|
19
|
-
element.type === 'password' ||
|
|
20
|
-
element.type === 'number')) ||
|
|
21
|
-
element instanceof HTMLTextAreaElement ||
|
|
22
|
-
(element instanceof HTMLElement && element.isContentEditable));
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Determines if a mouse event landed on a scrollbar rather than on element content. Scrollbar
|
|
26
|
-
* interactions fire mouse events on the scrolling element itself (or on `<html>` for the page
|
|
27
|
-
* scrollbar), so an outside-click check would otherwise treat dragging a scrollbar as a click away
|
|
28
|
-
* from the pop-up and dismiss it mid-drag.
|
|
29
|
-
*
|
|
30
|
-
* @category Internal
|
|
31
|
-
*/
|
|
32
|
-
export function isMouseEventOnScrollbar(event) {
|
|
33
|
-
const target = event.composedPath()[0];
|
|
34
|
-
if (!(target instanceof Element)) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
const rect = target.getBoundingClientRect();
|
|
38
|
-
/**
|
|
39
|
-
* `clientLeft` and `clientTop` are the border widths, which also include the scrollbar itself
|
|
40
|
-
* when it's rendered on the leading edge (RTL layouts).
|
|
41
|
-
*/
|
|
42
|
-
const clientLeft = rect.left + target.clientLeft;
|
|
43
|
-
const clientTop = rect.top + target.clientTop;
|
|
44
|
-
const outsideHorizontally = event.clientX < clientLeft || event.clientX >= clientLeft + target.clientWidth;
|
|
45
|
-
const outsideVertically = event.clientY < clientTop || event.clientY >= clientTop + target.clientHeight;
|
|
46
|
-
return ((outsideHorizontally && target.scrollHeight > target.clientHeight) ||
|
|
47
|
-
(outsideVertically && target.scrollWidth > target.clientWidth));
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* The default empty {@link PositionRect}, with all values set to 0.
|
|
51
|
-
*
|
|
52
|
-
* @category Internal
|
|
53
|
-
*/
|
|
54
|
-
export const emptyPositionRect = {
|
|
55
|
-
top: 0,
|
|
56
|
-
left: 0,
|
|
57
|
-
right: 0,
|
|
58
|
-
bottom: 0,
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* An event fired from {@link PopUpManager} when the pop up should be hidden.
|
|
62
|
-
*
|
|
63
|
-
* @category PopUp
|
|
64
|
-
*/
|
|
65
|
-
export class HidePopUpEvent extends defineTypedEvent('hide-pop-up') {
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* An event fired from {@link PopUpManager} when an individual item in the pop up has been selected
|
|
69
|
-
* by the user.
|
|
70
|
-
*
|
|
71
|
-
* @category PopUp
|
|
72
|
-
*/
|
|
73
|
-
export class NavSelectEvent extends defineTypedCustomEvent()('nav-select') {
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* A "pop up" manager for items that pop up from the HTML page, like dropdowns or menus.
|
|
77
|
-
*
|
|
78
|
-
* @category PopUp
|
|
79
|
-
*/
|
|
80
|
-
export class PopUpManager {
|
|
81
|
-
navController;
|
|
82
|
-
listenTarget = new ListenTarget();
|
|
83
|
-
options = {
|
|
84
|
-
minDownSpace: 200,
|
|
85
|
-
minRightSpace: 400,
|
|
86
|
-
verticalDiffThreshold: 20,
|
|
87
|
-
horizontalDiffThreshold: 100,
|
|
88
|
-
supportNavigation: true,
|
|
89
|
-
};
|
|
90
|
-
/** Callbacks that remove the global listeners attached while a pop up is shown. */
|
|
91
|
-
cleanupCallbacks = [];
|
|
92
|
-
lastRootElement;
|
|
93
|
-
constructor(navController, options) {
|
|
94
|
-
this.navController = navController;
|
|
95
|
-
this.options = {
|
|
96
|
-
...this.options,
|
|
97
|
-
...options,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Attaches the global listeners (page activation, navigation, mousedown, and keydown) that
|
|
102
|
-
* control the currently shown pop up.
|
|
103
|
-
*/
|
|
104
|
-
attachGlobalListeners() {
|
|
105
|
-
this.cleanupCallbacks = [
|
|
106
|
-
listenToPageActivation(false, (isPageActive) => {
|
|
107
|
-
if (!isPageActive) {
|
|
108
|
-
this.removePopUp();
|
|
109
|
-
}
|
|
110
|
-
}),
|
|
111
|
-
this.navController.listen(NavActivateEvent, (event) => {
|
|
112
|
-
const target = event.composedPath()[0];
|
|
113
|
-
if (target instanceof Element && isInputLikeElement(target)) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (event.detail.success) {
|
|
117
|
-
this.listenTarget.dispatch(new NavSelectEvent({
|
|
118
|
-
detail: event.detail.coords,
|
|
119
|
-
}));
|
|
120
|
-
this.navController.currentNavEntry?.entry.focus(true);
|
|
121
|
-
event.stopImmediatePropagation();
|
|
122
|
-
event.preventDefault();
|
|
123
|
-
}
|
|
124
|
-
}),
|
|
125
|
-
listenToGlobal('mousedown', (event) => {
|
|
126
|
-
if (
|
|
127
|
-
/** Ignore clicks that came from the pop up host itself. */
|
|
128
|
-
(this.lastRootElement &&
|
|
129
|
-
event.composedPath().includes(this.lastRootElement)) ||
|
|
130
|
-
isMouseEventOnScrollbar(event)) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this.removePopUp();
|
|
134
|
-
}, {
|
|
135
|
-
passive: true,
|
|
136
|
-
}),
|
|
137
|
-
listenToGlobal('keydown', (event) => {
|
|
138
|
-
const keyCode = event.code;
|
|
139
|
-
if (keyCode === 'Escape') {
|
|
140
|
-
this.removePopUp();
|
|
141
|
-
}
|
|
142
|
-
else if (this.options.supportNavigation) {
|
|
143
|
-
const target = event.composedPath()[0];
|
|
144
|
-
if (target instanceof Element && isInputLikeElement(target)) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
if (keyCode === 'ArrowDown') {
|
|
148
|
-
event.stopImmediatePropagation();
|
|
149
|
-
event.preventDefault();
|
|
150
|
-
this.navController.navigate({
|
|
151
|
-
direction: NavDirection.Down,
|
|
152
|
-
allowWrapping: false,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
else if (keyCode === 'ArrowUp') {
|
|
156
|
-
event.stopImmediatePropagation();
|
|
157
|
-
event.preventDefault();
|
|
158
|
-
this.navController.navigate({
|
|
159
|
-
direction: NavDirection.Up,
|
|
160
|
-
allowWrapping: false,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
else if (keyCode === 'ArrowLeft') {
|
|
164
|
-
event.stopImmediatePropagation();
|
|
165
|
-
event.preventDefault();
|
|
166
|
-
this.navController.navigate({
|
|
167
|
-
direction: NavDirection.Left,
|
|
168
|
-
allowWrapping: false,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
else if (keyCode === 'ArrowRight') {
|
|
172
|
-
event.stopImmediatePropagation();
|
|
173
|
-
event.preventDefault();
|
|
174
|
-
this.navController.navigate({
|
|
175
|
-
direction: NavDirection.Right,
|
|
176
|
-
allowWrapping: false,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
else if ((keyCode === 'Enter' || keyCode === 'Return' || keyCode === 'Space') &&
|
|
180
|
-
this.navController.enterInto({
|
|
181
|
-
fallbackToActivate: true,
|
|
182
|
-
}).success) {
|
|
183
|
-
event.stopImmediatePropagation();
|
|
184
|
-
event.preventDefault();
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}),
|
|
188
|
-
];
|
|
189
|
-
}
|
|
190
|
-
/** Listen to events emitted from a {@link PopUpManager} instance. */
|
|
191
|
-
listen(event, listener, options) {
|
|
192
|
-
return this.listenTarget.listen(event, listener, options);
|
|
193
|
-
}
|
|
194
|
-
/** Trigger removal or hiding of the pop up. */
|
|
195
|
-
removePopUp() {
|
|
196
|
-
this.cleanupCallbacks.forEach((callback) => callback());
|
|
197
|
-
this.listenTarget.dispatch(new HidePopUpEvent());
|
|
198
|
-
}
|
|
199
|
-
/** Trigger showing the pop up. */
|
|
200
|
-
showPopUp(rootElement, options) {
|
|
201
|
-
this.lastRootElement = rootElement;
|
|
202
|
-
const currentOptions = {
|
|
203
|
-
...this.options,
|
|
204
|
-
...options,
|
|
205
|
-
};
|
|
206
|
-
const container = findOverflowAncestor(rootElement);
|
|
207
|
-
assert.instanceOf(container, HTMLElement);
|
|
208
|
-
const rootRect = rootElement.getBoundingClientRect();
|
|
209
|
-
const containerRect = container.getBoundingClientRect();
|
|
210
|
-
const containerScrollbarWidth = container.offsetWidth - container.clientWidth;
|
|
211
|
-
const containerScrollbarHeight = container.offsetHeight - container.clientHeight;
|
|
212
|
-
const containerPosition = container === document.body
|
|
213
|
-
? {
|
|
214
|
-
top: 0,
|
|
215
|
-
left: 0,
|
|
216
|
-
right: containerRect.width,
|
|
217
|
-
bottom: containerRect.height,
|
|
218
|
-
}
|
|
219
|
-
: {
|
|
220
|
-
top: containerRect.top,
|
|
221
|
-
left: containerRect.left,
|
|
222
|
-
right: containerRect.right - containerScrollbarWidth,
|
|
223
|
-
bottom: containerRect.bottom - containerScrollbarHeight,
|
|
224
|
-
};
|
|
225
|
-
const rootPosition = mapObjectValues(emptyPositionRect, (key) => {
|
|
226
|
-
return rootRect[key];
|
|
227
|
-
});
|
|
228
|
-
const diff = mapObjectValues(emptyPositionRect, (key) => {
|
|
229
|
-
const containerDimension = containerPosition[key];
|
|
230
|
-
const hostDimension = rootPosition[key];
|
|
231
|
-
return Math.abs(containerDimension - hostDimension);
|
|
232
|
-
});
|
|
233
|
-
const useUp = diff.top > diff.bottom + currentOptions.verticalDiffThreshold &&
|
|
234
|
-
diff.bottom < currentOptions.minDownSpace;
|
|
235
|
-
const useLeft = diff.left > diff.right + currentOptions.horizontalDiffThreshold &&
|
|
236
|
-
diff.right < currentOptions.minRightSpace;
|
|
237
|
-
this.attachGlobalListeners();
|
|
238
|
-
return {
|
|
239
|
-
popDown: !useUp,
|
|
240
|
-
popRight: !useLeft,
|
|
241
|
-
positions: {
|
|
242
|
-
container: containerPosition,
|
|
243
|
-
root: rootPosition,
|
|
244
|
-
diff,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Cleanup and destroy the {@link PopUpManager} instance. This:
|
|
250
|
-
*
|
|
251
|
-
* - Removes the existing pop up
|
|
252
|
-
* - Cleans up all internal and external listeners
|
|
253
|
-
*/
|
|
254
|
-
destroy() {
|
|
255
|
-
this.removePopUp();
|
|
256
|
-
this.listenTarget.destroy();
|
|
257
|
-
}
|
|
258
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
-
/**
|
|
3
|
-
* Options for `ViraSelect` and `ViraDropdown`.
|
|
4
|
-
*
|
|
5
|
-
* @category Dropdown
|
|
6
|
-
* @category Elements
|
|
7
|
-
* @see https://electrovir.github.io/vira/book/elements/vira-select
|
|
8
|
-
*/
|
|
9
|
-
export type ViraSelectOption = {
|
|
10
|
-
/** A value or id, used to keep track of which option is selected. */
|
|
11
|
-
value: string;
|
|
12
|
-
label: string;
|
|
13
|
-
} & PartialWithUndefined<{
|
|
14
|
-
disabled: boolean;
|
|
15
|
-
}>;
|
|
16
|
-
/**
|
|
17
|
-
* A group of options for `ViraSelect`, rendered as an `<optgroup>`.
|
|
18
|
-
*
|
|
19
|
-
* @category Dropdown
|
|
20
|
-
* @category Elements
|
|
21
|
-
*/
|
|
22
|
-
export type ViraSelectOptionGroup = {
|
|
23
|
-
groupName: string;
|
|
24
|
-
options: ReadonlyArray<Readonly<ViraSelectOption>>;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Type guard to determine if a `ViraSelect` options entry is a group.
|
|
28
|
-
*
|
|
29
|
-
* @category Internal
|
|
30
|
-
*/
|
|
31
|
-
export declare function isViraSelectOptionGroup(entry: Readonly<ViraSelectOption> | Readonly<ViraSelectOptionGroup>): entry is Readonly<ViraSelectOptionGroup>;
|