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.
Files changed (56) hide show
  1. package/dist/directives/index.d.ts +2 -0
  2. package/dist/directives/index.js +2 -0
  3. package/dist/directives/popover.directive.d.ts +29 -0
  4. package/dist/directives/popover.directive.js +45 -0
  5. package/dist/directives/tooltip.directive.d.ts +60 -0
  6. package/dist/directives/tooltip.directive.js +99 -0
  7. package/dist/elements/color/vira-color-picker.element.d.ts +1 -1
  8. package/dist/elements/color/vira-color-picker.element.js +17 -15
  9. package/dist/elements/index.d.ts +5 -5
  10. package/dist/elements/index.js +5 -5
  11. package/dist/elements/{pop-up → popover}/vira-menu-item.element.d.ts +4 -4
  12. package/dist/elements/{pop-up → popover}/vira-menu-item.element.js +3 -3
  13. package/dist/elements/popover/vira-menu-trigger.element.d.ts +56 -0
  14. package/dist/elements/{pop-up → popover}/vira-menu-trigger.element.js +19 -30
  15. package/dist/elements/popover/vira-menu.element.d.ts +35 -0
  16. package/dist/elements/popover/vira-menu.element.js +262 -0
  17. package/dist/elements/popover/vira-popover-trigger.element.d.ts +49 -0
  18. package/dist/elements/popover/vira-popover-trigger.element.js +301 -0
  19. package/dist/elements/popover/vira-tooltip.element.d.ts +10 -0
  20. package/dist/elements/popover/vira-tooltip.element.js +176 -0
  21. package/dist/elements/vira-drawer.element.js +1 -1
  22. package/dist/elements/vira-dropdown.element.d.ts +28 -12
  23. package/dist/elements/vira-dropdown.element.js +172 -59
  24. package/dist/elements/vira-form.element.js +10 -16
  25. package/dist/elements/vira-json-form.element.js +40 -36
  26. package/dist/elements/vira-modal.element.js +1 -1
  27. package/dist/elements/vira-tabs.element.d.ts +3 -9
  28. package/dist/elements/vira-tabs.element.js +5 -6
  29. package/dist/elements/vira-theme-switcher.element.js +3 -3
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/util/anchored-popover.d.ts +40 -0
  33. package/dist/util/anchored-popover.js +70 -0
  34. package/dist/util/index.d.ts +4 -3
  35. package/dist/util/index.js +4 -3
  36. package/dist/util/{pop-up-helpers.d.ts → menu-helpers.d.ts} +4 -18
  37. package/dist/util/{pop-up-helpers.js → menu-helpers.js} +2 -17
  38. package/dist/util/popover-manager.d.ts +123 -0
  39. package/dist/util/popover-manager.js +412 -0
  40. package/dist/util/vira-dropdown-option.d.ts +30 -0
  41. package/dist/util/vira-dropdown-option.js +8 -0
  42. package/dist/util/vira-form-fields.d.ts +2 -2
  43. package/dist/util/vira-theme-client.d.ts +1 -1
  44. package/dist/util/vira-theme-client.js +3 -3
  45. package/package.json +2 -1
  46. package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +0 -45
  47. package/dist/elements/pop-up/vira-menu.element.d.ts +0 -36
  48. package/dist/elements/pop-up/vira-menu.element.js +0 -88
  49. package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +0 -109
  50. package/dist/elements/pop-up/vira-pop-up-trigger.element.js +0 -408
  51. package/dist/elements/vira-select.element.d.ts +0 -44
  52. package/dist/elements/vira-select.element.js +0 -418
  53. package/dist/util/pop-up-manager.d.ts +0 -200
  54. package/dist/util/pop-up-manager.js +0 -258
  55. package/dist/util/vira-select-option.d.ts +0 -31
  56. 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>;
@@ -1,8 +0,0 @@
1
- /**
2
- * Type guard to determine if a `ViraSelect` options entry is a group.
3
- *
4
- * @category Internal
5
- */
6
- export function isViraSelectOptionGroup(entry) {
7
- return 'groupName' in entry;
8
- }