vira 28.19.6 → 28.19.7
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/elements/define-vira-element.d.ts +18 -0
- package/dist/elements/define-vira-element.js +19 -0
- package/dist/elements/form/vira-form-fields.d.ts +100 -0
- package/dist/elements/form/vira-form-fields.js +60 -0
- package/dist/elements/form/vira-form.element.d.ts +35 -0
- package/dist/elements/form/vira-form.element.js +151 -0
- package/dist/elements/index.js +25 -0
- package/dist/elements/pop-up/pop-up-helpers.d.ts +33 -0
- package/dist/elements/pop-up/pop-up-helpers.js +58 -0
- package/{src/elements/pop-up/pop-up-menu-item.ts → dist/elements/pop-up/pop-up-menu-item.d.ts} +3 -4
- package/dist/elements/pop-up/pop-up-menu-item.js +1 -0
- package/dist/elements/pop-up/vira-menu-item.element.d.ts +19 -0
- package/{src/elements/pop-up/vira-menu-item.element.ts → dist/elements/pop-up/vira-menu-item.element.js} +11 -28
- package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +41 -0
- package/dist/elements/pop-up/vira-menu-trigger.element.js +121 -0
- package/dist/elements/pop-up/vira-menu.element.d.ts +38 -0
- package/{src/elements/pop-up/vira-menu.element.ts → dist/elements/pop-up/vira-menu.element.js} +49 -76
- package/dist/elements/pop-up/vira-pop-up-menu.element.d.ts +35 -0
- package/{src/elements/pop-up/vira-pop-up-menu.element.ts → dist/elements/pop-up/vira-pop-up-menu.element.js} +22 -34
- package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +105 -0
- package/{src/elements/pop-up/vira-pop-up-trigger.element.ts → dist/elements/pop-up/vira-pop-up-trigger.element.js} +104 -199
- package/dist/elements/shared-text-input-logic.d.ts +63 -0
- package/dist/elements/shared-text-input-logic.js +101 -0
- package/dist/elements/vira-bold-text.element.d.ts +9 -0
- package/{src/elements/vira-bold-text.element.ts → dist/elements/vira-bold-text.element.js} +7 -8
- package/dist/elements/vira-button.element.d.ts +31 -0
- package/{src/elements/vira-button.element.ts → dist/elements/vira-button.element.js} +35 -66
- package/dist/elements/vira-card.element.d.ts +18 -0
- package/{src/elements/vira-card.element.ts → dist/elements/vira-card.element.js} +13 -16
- package/dist/elements/vira-checkbox.element.d.ts +34 -0
- package/{src/elements/vira-checkbox.element.ts → dist/elements/vira-checkbox.element.js} +28 -71
- package/dist/elements/vira-collapsible-wrapper.element.d.ts +14 -0
- package/{src/elements/vira-collapsible-wrapper.element.ts → dist/elements/vira-collapsible-wrapper.element.js} +16 -18
- package/dist/elements/vira-dropdown.element.d.ts +46 -0
- package/{src/elements/vira-dropdown.element.ts → dist/elements/vira-dropdown.element.js} +48 -94
- package/dist/elements/vira-error.element.d.ts +7 -0
- package/{src/elements/vira-error.element.ts → dist/elements/vira-error.element.js} +5 -6
- package/dist/elements/vira-icon.element.d.ts +13 -0
- package/{src/elements/vira-icon.element.ts → dist/elements/vira-icon.element.js} +6 -13
- package/dist/elements/vira-image.element.d.ts +45 -0
- package/{src/elements/vira-image.element.ts → dist/elements/vira-image.element.js} +43 -63
- package/dist/elements/vira-input.element.d.ts +62 -0
- package/{src/elements/vira-input.element.ts → dist/elements/vira-input.element.js} +85 -151
- package/dist/elements/vira-link.element.d.ts +73 -0
- package/{src/elements/vira-link.element.ts → dist/elements/vira-link.element.js} +11 -62
- package/dist/elements/vira-modal.element.d.ts +39 -0
- package/{src/elements/vira-modal.element.ts → dist/elements/vira-modal.element.js} +50 -89
- package/dist/elements/vira-overflow-switch.element.d.ts +21 -0
- package/dist/elements/vira-overflow-switch.element.js +110 -0
- package/dist/elements/vira-progress.element.d.ts +18 -0
- package/{src/elements/vira-progress.element.ts → dist/elements/vira-progress.element.js} +11 -26
- package/dist/elements/vira-select.element.d.ts +48 -0
- package/{src/elements/vira-select.element.ts → dist/elements/vira-select.element.js} +41 -96
- package/dist/icons/icon-color.test-helper.d.ts +6 -0
- package/dist/icons/icon-color.test-helper.js +9 -0
- package/dist/icons/icon-css-vars.d.ts +14 -0
- package/{src/icons/icon-css-vars.ts → dist/icons/icon-css-vars.js} +1 -2
- package/dist/icons/icon-svg.d.ts +27 -0
- package/dist/icons/icon-svg.js +48 -0
- package/dist/icons/icon-svgs/bell-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/bell-24.icon.ts → dist/icons/icon-svgs/bell-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/chat-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/chat-24.icon.ts → dist/icons/icon-svgs/chat-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/check-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/check-24.icon.ts → dist/icons/icon-svgs/check-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/chevron-down-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/chevron-down-24.icon.ts → dist/icons/icon-svgs/chevron-down-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/chevron-up-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/chevron-up-24.icon.ts → dist/icons/icon-svgs/chevron-up-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/close-x-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/close-x-24.icon.ts → dist/icons/icon-svgs/close-x-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/commit-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/commit-24.icon.ts → dist/icons/icon-svgs/commit-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/copy-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/copy-24.icon.ts → dist/icons/icon-svgs/copy-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/document-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/document-24.icon.ts → dist/icons/icon-svgs/document-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/document-search-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/document-search-24.icon.ts → dist/icons/icon-svgs/document-search-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/double-chevron-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/double-chevron-24.icon.ts → dist/icons/icon-svgs/double-chevron-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/element-16.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/element-16.icon.ts → dist/icons/icon-svgs/element-16.icon.js} +4 -5
- package/dist/icons/icon-svgs/element-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/element-24.icon.ts → dist/icons/icon-svgs/element-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/external-link-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/external-link-24.icon.ts → dist/icons/icon-svgs/external-link-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/eye-closed-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/eye-closed-24.icon.ts → dist/icons/icon-svgs/eye-closed-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/eye-open-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/eye-open-24.icon.ts → dist/icons/icon-svgs/eye-open-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/filter-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/filter-24.icon.ts → dist/icons/icon-svgs/filter-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/link-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/link-24.icon.ts → dist/icons/icon-svgs/link-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/loader-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/loader-24.icon.ts → dist/icons/icon-svgs/loader-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/loader-animated-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/loader-animated-24.icon.ts → dist/icons/icon-svgs/loader-animated-24.icon.js} +6 -8
- package/dist/icons/icon-svgs/lock-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/lock-24.icon.ts → dist/icons/icon-svgs/lock-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/options-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/options-24.icon.ts → dist/icons/icon-svgs/options-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/pencil-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/pencil-24.icon.ts → dist/icons/icon-svgs/pencil-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/shield-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/shield-24.icon.ts → dist/icons/icon-svgs/shield-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/sort-ascending-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/sort-ascending-24.icon.ts → dist/icons/icon-svgs/sort-ascending-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/sort-descending-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/sort-descending-24.icon.ts → dist/icons/icon-svgs/sort-descending-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/speaker-loud-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/speaker-loud-24.icon.ts → dist/icons/icon-svgs/speaker-loud-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/speaker-medium-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/speaker-medium-24.icon.ts → dist/icons/icon-svgs/speaker-medium-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/speaker-muted-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/speaker-muted-24.icon.ts → dist/icons/icon-svgs/speaker-muted-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/speaker-quiet-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/speaker-quiet-24.icon.ts → dist/icons/icon-svgs/speaker-quiet-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/star-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/star-24.icon.ts → dist/icons/icon-svgs/star-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/status-failure-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/status-failure-24.icon.ts → dist/icons/icon-svgs/status-failure-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/status-in-progress-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/status-in-progress-24.icon.ts → dist/icons/icon-svgs/status-in-progress-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/status-success-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/status-success-24.icon.ts → dist/icons/icon-svgs/status-success-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/status-unknown-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/status-unknown-24.icon.ts → dist/icons/icon-svgs/status-unknown-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/status-warning-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/status-warning-24.icon.ts → dist/icons/icon-svgs/status-warning-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/upload-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/upload-24.icon.ts → dist/icons/icon-svgs/upload-24.icon.js} +4 -5
- package/dist/icons/icon-svgs/x-24.icon.d.ts +8 -0
- package/{src/icons/icon-svgs/x-24.icon.ts → dist/icons/icon-svgs/x-24.icon.js} +4 -5
- package/dist/icons/index.d.ts +86 -0
- package/{src/icons/index.ts → dist/icons/index.js} +39 -43
- package/dist/index.js +4 -0
- package/dist/styles/border.d.ts +9 -0
- package/{src/styles/border.ts → dist/styles/border.js} +1 -2
- package/dist/styles/disabled.d.ts +6 -0
- package/{src/styles/disabled.ts → dist/styles/disabled.js} +2 -3
- package/dist/styles/durations.d.ts +22 -0
- package/{src/styles/durations.ts → dist/styles/durations.js} +1 -2
- package/dist/styles/focus.d.ts +34 -0
- package/{src/styles/focus.ts → dist/styles/focus.js} +8 -29
- package/dist/styles/font.d.ts +9 -0
- package/{src/styles/font.ts → dist/styles/font.js} +1 -2
- package/dist/styles/form-styles.d.ts +20 -0
- package/{src/styles/form-styles.ts → dist/styles/form-styles.js} +1 -6
- package/{src/styles/index.ts → dist/styles/index.d.ts} +0 -1
- package/dist/styles/index.js +13 -0
- package/dist/styles/native-styles.d.ts +13 -0
- package/{src/styles/native-styles.ts → dist/styles/native-styles.js} +3 -5
- package/dist/styles/scrollbar.d.ts +6 -0
- package/{src/styles/scrollbar.ts → dist/styles/scrollbar.js} +3 -4
- package/dist/styles/shadows.d.ts +20 -0
- package/{src/styles/shadows.ts → dist/styles/shadows.js} +6 -8
- package/dist/styles/user-select.d.ts +6 -0
- package/{src/styles/user-select.ts → dist/styles/user-select.js} +2 -3
- package/dist/styles/vira-color-palette.d.ts +95 -0
- package/{src/styles/vira-color-palette.ts → dist/styles/vira-color-palette.js} +1 -11
- package/dist/styles/vira-color-theme.d.ts +1184 -0
- package/dist/styles/vira-color-theme.js +1138 -0
- package/dist/util/define-table.d.ts +110 -0
- package/dist/util/define-table.js +115 -0
- package/dist/util/dynamic-element.d.ts +63 -0
- package/dist/util/dynamic-element.js +61 -0
- package/dist/util/index.js +3 -0
- package/dist/util/pop-up-manager.d.ts +186 -0
- package/dist/util/pop-up-manager.js +214 -0
- package/package.json +6 -6
- package/src/elements/define-vira-element.ts +0 -29
- package/src/elements/form/vira-form-fields.ts +0 -140
- package/src/elements/form/vira-form.element.ts +0 -204
- package/src/elements/pop-up/pop-up-helpers.ts +0 -85
- package/src/elements/pop-up/vira-menu-trigger.element.ts +0 -158
- package/src/elements/shared-text-input-logic.ts +0 -173
- package/src/elements/vira-overflow-switch.element.ts +0 -137
- package/src/icons/icon-color.test-helper.ts +0 -9
- package/src/icons/icon-svg.ts +0 -71
- package/src/styles/vira-color-theme.ts +0 -1142
- package/src/util/define-table.ts +0 -279
- package/src/util/dynamic-element.ts +0 -129
- package/src/util/pop-up-manager.ts +0 -380
- /package/{src/elements/index.ts → dist/elements/index.d.ts} +0 -0
- /package/{src/index.ts → dist/index.d.ts} +0 -0
- /package/{src/util/index.ts → dist/util/index.d.ts} +0 -0
|
@@ -0,0 +1,214 @@
|
|
|
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
|
+
* The default empty {@link PositionRect}, with all values set to 0.
|
|
26
|
+
*
|
|
27
|
+
* @category Internal
|
|
28
|
+
*/
|
|
29
|
+
export const emptyPositionRect = {
|
|
30
|
+
top: 0,
|
|
31
|
+
left: 0,
|
|
32
|
+
right: 0,
|
|
33
|
+
bottom: 0,
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* An event fired from {@link PopUpManager} when the pop up should be hidden.
|
|
37
|
+
*
|
|
38
|
+
* @category PopUp
|
|
39
|
+
*/
|
|
40
|
+
export class HidePopUpEvent extends defineTypedEvent('hide-pop-up') {
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* An event fired from {@link PopUpManager} when an individual item in the pop up has been selected
|
|
44
|
+
* by the user.
|
|
45
|
+
*
|
|
46
|
+
* @category PopUp
|
|
47
|
+
*/
|
|
48
|
+
export class NavSelectEvent extends defineTypedCustomEvent()('nav-select') {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A "pop up" manager for items that pop up from the HTML page, like dropdowns or menus.
|
|
52
|
+
*
|
|
53
|
+
* @category PopUp
|
|
54
|
+
*/
|
|
55
|
+
export class PopUpManager {
|
|
56
|
+
navController;
|
|
57
|
+
listenTarget = new ListenTarget();
|
|
58
|
+
options = {
|
|
59
|
+
minDownSpace: 200,
|
|
60
|
+
minRightSpace: 400,
|
|
61
|
+
verticalDiffThreshold: 20,
|
|
62
|
+
horizontalDiffThreshold: 100,
|
|
63
|
+
supportNavigation: true,
|
|
64
|
+
};
|
|
65
|
+
cleanupCallbacks = [];
|
|
66
|
+
lastRootElement;
|
|
67
|
+
constructor(navController, options) {
|
|
68
|
+
this.navController = navController;
|
|
69
|
+
this.options = { ...this.options, ...options };
|
|
70
|
+
}
|
|
71
|
+
attachGlobalListeners() {
|
|
72
|
+
this.cleanupCallbacks = [
|
|
73
|
+
listenToPageActivation(false, (isPageActive) => {
|
|
74
|
+
if (!isPageActive) {
|
|
75
|
+
this.removePopUp();
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
this.navController.listen(NavActivateEvent, (event) => {
|
|
79
|
+
const target = event.composedPath()[0];
|
|
80
|
+
if (target instanceof Element && isInputLikeElement(target)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (event.detail.success) {
|
|
84
|
+
this.listenTarget.dispatch(new NavSelectEvent({ detail: event.detail.coords }));
|
|
85
|
+
this.navController.currentNavEntry?.entry.focus(true);
|
|
86
|
+
event.stopImmediatePropagation();
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
listenToGlobal('mousedown', (event) => {
|
|
91
|
+
if (this.lastRootElement &&
|
|
92
|
+
event.composedPath().includes(this.lastRootElement)) {
|
|
93
|
+
/** Ignore clicks that came from the pop up host itself. */
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.removePopUp();
|
|
97
|
+
}, { passive: true }),
|
|
98
|
+
listenToGlobal('keydown', (event) => {
|
|
99
|
+
const keyCode = event.code;
|
|
100
|
+
if (keyCode === 'Escape') {
|
|
101
|
+
this.removePopUp();
|
|
102
|
+
}
|
|
103
|
+
else if (this.options.supportNavigation) {
|
|
104
|
+
const target = event.composedPath()[0];
|
|
105
|
+
if (target instanceof Element && isInputLikeElement(target)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (keyCode === 'ArrowDown') {
|
|
109
|
+
event.stopImmediatePropagation();
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
this.navController.navigate({
|
|
112
|
+
direction: NavDirection.Down,
|
|
113
|
+
allowWrapping: false,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else if (keyCode === 'ArrowUp') {
|
|
117
|
+
event.stopImmediatePropagation();
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
this.navController.navigate({
|
|
120
|
+
direction: NavDirection.Up,
|
|
121
|
+
allowWrapping: false,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else if (keyCode === 'ArrowLeft') {
|
|
125
|
+
event.stopImmediatePropagation();
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
this.navController.navigate({
|
|
128
|
+
direction: NavDirection.Left,
|
|
129
|
+
allowWrapping: false,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else if (keyCode === 'ArrowRight') {
|
|
133
|
+
event.stopImmediatePropagation();
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
this.navController.navigate({
|
|
136
|
+
direction: NavDirection.Right,
|
|
137
|
+
allowWrapping: false,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else if ((keyCode === 'Enter' || keyCode === 'Return' || keyCode === 'Space') &&
|
|
141
|
+
this.navController.enterInto({ fallbackToActivate: true }).success) {
|
|
142
|
+
event.stopImmediatePropagation();
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}),
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
/** Listen to events emitted from a {@link PopUpManager} instance. */
|
|
150
|
+
listen(event, listener, options) {
|
|
151
|
+
return this.listenTarget.listen(event, listener, options);
|
|
152
|
+
}
|
|
153
|
+
/** Trigger removal or hiding of the pop up. */
|
|
154
|
+
removePopUp() {
|
|
155
|
+
this.cleanupCallbacks.forEach((callback) => callback());
|
|
156
|
+
this.listenTarget.dispatch(new HidePopUpEvent());
|
|
157
|
+
}
|
|
158
|
+
/** Trigger showing the pop up. */
|
|
159
|
+
showPopUp(rootElement, options) {
|
|
160
|
+
this.lastRootElement = rootElement;
|
|
161
|
+
const currentOptions = { ...this.options, ...options };
|
|
162
|
+
const container = findOverflowAncestor(rootElement);
|
|
163
|
+
assert.instanceOf(container, HTMLElement);
|
|
164
|
+
const rootRect = rootElement.getBoundingClientRect();
|
|
165
|
+
const containerRect = container.getBoundingClientRect();
|
|
166
|
+
const containerScrollbarWidth = container.offsetWidth - container.clientWidth;
|
|
167
|
+
const containerScrollbarHeight = container.offsetHeight - container.clientHeight;
|
|
168
|
+
const containerPosition = container === document.body
|
|
169
|
+
? {
|
|
170
|
+
top: 0,
|
|
171
|
+
left: 0,
|
|
172
|
+
right: containerRect.width,
|
|
173
|
+
bottom: containerRect.height,
|
|
174
|
+
}
|
|
175
|
+
: {
|
|
176
|
+
top: containerRect.top,
|
|
177
|
+
left: containerRect.left,
|
|
178
|
+
right: containerRect.right - containerScrollbarWidth,
|
|
179
|
+
bottom: containerRect.bottom - containerScrollbarHeight,
|
|
180
|
+
};
|
|
181
|
+
const rootPosition = mapObjectValues(emptyPositionRect, (key) => {
|
|
182
|
+
return rootRect[key];
|
|
183
|
+
});
|
|
184
|
+
const diff = mapObjectValues(emptyPositionRect, (key) => {
|
|
185
|
+
const containerDimension = containerPosition[key];
|
|
186
|
+
const hostDimension = rootPosition[key];
|
|
187
|
+
return Math.abs(containerDimension - hostDimension);
|
|
188
|
+
});
|
|
189
|
+
const useUp = diff.top > diff.bottom + currentOptions.verticalDiffThreshold &&
|
|
190
|
+
diff.bottom < currentOptions.minDownSpace;
|
|
191
|
+
const useLeft = diff.left > diff.right + currentOptions.horizontalDiffThreshold &&
|
|
192
|
+
diff.right < currentOptions.minRightSpace;
|
|
193
|
+
this.attachGlobalListeners();
|
|
194
|
+
return {
|
|
195
|
+
popDown: !useUp,
|
|
196
|
+
popRight: !useLeft,
|
|
197
|
+
positions: {
|
|
198
|
+
container: containerPosition,
|
|
199
|
+
root: rootPosition,
|
|
200
|
+
diff,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Cleanup and destroy the {@link PopUpManager} instance. This:
|
|
206
|
+
*
|
|
207
|
+
* - Removes the existing pop up
|
|
208
|
+
* - Cleans up all internal and external listeners
|
|
209
|
+
*/
|
|
210
|
+
destroy() {
|
|
211
|
+
this.removePopUp();
|
|
212
|
+
this.listenTarget.destroy();
|
|
213
|
+
}
|
|
214
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vira",
|
|
3
|
-
"version": "28.19.
|
|
3
|
+
"version": "28.19.7",
|
|
4
4
|
"description": "A simple and highly versatile design system using element-vir.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"type": "module",
|
|
30
|
-
"main": "
|
|
31
|
-
"module": "
|
|
32
|
-
"types": "
|
|
30
|
+
"main": "dist/index.js",
|
|
31
|
+
"module": "dist/index.js",
|
|
32
|
+
"types": "dist/index.d.ts",
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "npm run docs",
|
|
35
35
|
"compile": "virmator compile",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"colorjs.io": "^0.6.1",
|
|
45
45
|
"date-vir": "^8.1.0",
|
|
46
46
|
"device-navigation": "^4.5.5",
|
|
47
|
-
"lit-css-vars": "^3.
|
|
47
|
+
"lit-css-vars": "^3.2.2",
|
|
48
48
|
"observavir": "^2.3.1",
|
|
49
49
|
"page-active": "^1.0.3",
|
|
50
50
|
"spa-router-vir": "^6.4.1",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"esbuild": "^0.27.2",
|
|
62
62
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
63
63
|
"markdown-code-example-inserter": "^3.0.3",
|
|
64
|
-
"theme-vir": "^28.18.
|
|
64
|
+
"theme-vir": "^28.18.3",
|
|
65
65
|
"typedoc": "^0.28.16",
|
|
66
66
|
"typescript": "5.9.3",
|
|
67
67
|
"vite": "^7.3.1",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {wrapDefineElement} from 'element-vir';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Required prefix for all vira elements.
|
|
5
|
-
*
|
|
6
|
-
* @category Internal
|
|
7
|
-
*/
|
|
8
|
-
export const ViraTagNamePrefix = `vira-`;
|
|
9
|
-
/**
|
|
10
|
-
* Required tag name for all vira elements. This includes {@link ViraTagNamePrefix} in it.
|
|
11
|
-
*
|
|
12
|
-
* @category Internal
|
|
13
|
-
*/
|
|
14
|
-
export type ViraTagName = `${typeof ViraTagNamePrefix}${string}`;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Define a vira element with custom requirements (like the `vira-` element tag prefix).
|
|
18
|
-
*
|
|
19
|
-
* @category Internal
|
|
20
|
-
*/
|
|
21
|
-
export const defineViraElement = wrapDefineElement<ViraTagName>({
|
|
22
|
-
assertInputs: (inputs) => {
|
|
23
|
-
if (!inputs.tagName.startsWith(ViraTagNamePrefix)) {
|
|
24
|
-
throw new Error(
|
|
25
|
-
`Tag name should start with '${ViraTagNamePrefix}' but got '${inputs.tagName}'`,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
});
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import {check} from '@augment-vir/assert';
|
|
2
|
-
import {addSuffix, getObjectTypedValues, type PartialWithUndefined} from '@augment-vir/common';
|
|
3
|
-
import {type ViraIconSvg} from '../../icons/icon-svg.js';
|
|
4
|
-
import {type ViraSelectOption} from '../vira-select.element.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Form field types for {@link ViraFormField}.
|
|
8
|
-
*
|
|
9
|
-
* @category Internal
|
|
10
|
-
*/
|
|
11
|
-
export enum ViraFormFieldType {
|
|
12
|
-
Text = 'text',
|
|
13
|
-
/** Allows auto complete for _existing_ passwords used on this website (for login). */
|
|
14
|
-
ExistingPassword = 'existing-password',
|
|
15
|
-
/** Allows auto complete for _new_ passwords used on this website (for login). */
|
|
16
|
-
NewPassword = 'new-password',
|
|
17
|
-
/** Uses a password input without any attributes applied for auto complete hints. */
|
|
18
|
-
PlainPassword = 'plain-password',
|
|
19
|
-
Email = 'email',
|
|
20
|
-
Select = 'select',
|
|
21
|
-
Checkbox = 'checkbox',
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* {@link ViraFormField} properties that are shared between all field types.
|
|
26
|
-
*
|
|
27
|
-
* @category Internal
|
|
28
|
-
*/
|
|
29
|
-
export type CommonViraFormFields = {
|
|
30
|
-
label: string;
|
|
31
|
-
} & PartialWithUndefined<{
|
|
32
|
-
/** Applies a test id to the form field element. */
|
|
33
|
-
testId: string;
|
|
34
|
-
/**
|
|
35
|
-
* When `true`, visually indicates the form field as required and affects form validation.
|
|
36
|
-
*
|
|
37
|
-
* @default false
|
|
38
|
-
*/
|
|
39
|
-
isRequired: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* When `true`, marks this form field element with error styling.
|
|
42
|
-
*
|
|
43
|
-
* @default false
|
|
44
|
-
*/
|
|
45
|
-
hasError: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* When `true`, hides this form field entirely.
|
|
48
|
-
*
|
|
49
|
-
* @default false
|
|
50
|
-
*/
|
|
51
|
-
isHidden: boolean;
|
|
52
|
-
/**
|
|
53
|
-
* When `true`, continues showing the form field but prevents edits.
|
|
54
|
-
*
|
|
55
|
-
* @default false
|
|
56
|
-
*/
|
|
57
|
-
isDisabled: boolean;
|
|
58
|
-
}>;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* An individual form field for {@link ViraFormFields}.
|
|
62
|
-
*
|
|
63
|
-
* @category Internal
|
|
64
|
-
*/
|
|
65
|
-
export type ViraFormField =
|
|
66
|
-
| ({
|
|
67
|
-
type:
|
|
68
|
-
| ViraFormFieldType.Text
|
|
69
|
-
| ViraFormFieldType.ExistingPassword
|
|
70
|
-
| ViraFormFieldType.NewPassword
|
|
71
|
-
| ViraFormFieldType.PlainPassword
|
|
72
|
-
| ViraFormFieldType.Email;
|
|
73
|
-
value: string | undefined;
|
|
74
|
-
} & PartialWithUndefined<{
|
|
75
|
-
placeholder: string;
|
|
76
|
-
icon: ViraIconSvg;
|
|
77
|
-
isUsername: boolean;
|
|
78
|
-
}> &
|
|
79
|
-
CommonViraFormFields)
|
|
80
|
-
| ({
|
|
81
|
-
type: ViraFormFieldType.Select;
|
|
82
|
-
value: string | undefined;
|
|
83
|
-
options: ReadonlyArray<Readonly<ViraSelectOption>>;
|
|
84
|
-
} & PartialWithUndefined<{
|
|
85
|
-
placeholder: string;
|
|
86
|
-
icon: ViraIconSvg;
|
|
87
|
-
}> &
|
|
88
|
-
CommonViraFormFields)
|
|
89
|
-
| ({
|
|
90
|
-
type: ViraFormFieldType.Checkbox;
|
|
91
|
-
value: boolean | undefined;
|
|
92
|
-
} & CommonViraFormFields);
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* A collection of form fields for `ViraForm`.
|
|
96
|
-
*
|
|
97
|
-
* @category Internal
|
|
98
|
-
*/
|
|
99
|
-
export type ViraFormFields = Record<string, ViraFormField>;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Appends a `'*'` to a label if it exist sand if it is required.
|
|
103
|
-
*
|
|
104
|
-
* @category Internal
|
|
105
|
-
*/
|
|
106
|
-
export function applyRequiredLabel(
|
|
107
|
-
label: string | undefined,
|
|
108
|
-
isRequired: boolean,
|
|
109
|
-
): string | undefined {
|
|
110
|
-
if (label) {
|
|
111
|
-
if (isRequired) {
|
|
112
|
-
return addSuffix({value: label, suffix: '*'});
|
|
113
|
-
} else {
|
|
114
|
-
return label;
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
return undefined;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Checks if all the {@link ViraFormField} entries in a given {@link ViraFormFields} are valid through
|
|
123
|
-
* the following checks:
|
|
124
|
-
*
|
|
125
|
-
* - Checks that required fields are provided (not `undefined`)
|
|
126
|
-
* - Ignores hidden fields
|
|
127
|
-
*
|
|
128
|
-
* @category Internal
|
|
129
|
-
*/
|
|
130
|
-
export function areFormFieldsValid(formFields: Readonly<ViraFormFields>) {
|
|
131
|
-
return getObjectTypedValues(formFields).every((formField) => {
|
|
132
|
-
if (formField.isHidden || !formField.isRequired) {
|
|
133
|
-
return true;
|
|
134
|
-
} else if (check.isString(formField.value)) {
|
|
135
|
-
return !!formField.value;
|
|
136
|
-
} else {
|
|
137
|
-
return formField.value != undefined;
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import {getObjectTypedEntries, type PartialWithUndefined} from '@augment-vir/common';
|
|
2
|
-
import {css, defineElementEvent, html, listen, nothing, testId} from 'element-vir';
|
|
3
|
-
import {defineViraElement} from '../define-vira-element.js';
|
|
4
|
-
import {ViraCheckbox} from '../vira-checkbox.element.js';
|
|
5
|
-
import {ViraInput, ViraInputType} from '../vira-input.element.js';
|
|
6
|
-
import {ViraSelect} from '../vira-select.element.js';
|
|
7
|
-
import {
|
|
8
|
-
applyRequiredLabel,
|
|
9
|
-
areFormFieldsValid,
|
|
10
|
-
type ViraFormField,
|
|
11
|
-
type ViraFormFields,
|
|
12
|
-
ViraFormFieldType,
|
|
13
|
-
} from './vira-form-fields.js';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* A form element.
|
|
17
|
-
*
|
|
18
|
-
* @category Elements
|
|
19
|
-
* @see https://electrovir.github.io/vira/book/elements/vira-form
|
|
20
|
-
*/
|
|
21
|
-
export const ViraForm = defineViraElement<
|
|
22
|
-
Readonly<
|
|
23
|
-
{
|
|
24
|
-
fields: Readonly<ViraFormFields>;
|
|
25
|
-
} & PartialWithUndefined<{
|
|
26
|
-
showClearButtons: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* When `true`, all fields in this form are disabled. Note that this will not (and can
|
|
29
|
-
* not) disable any child elements you've inserted via <slot>.
|
|
30
|
-
*
|
|
31
|
-
* @default false
|
|
32
|
-
*/
|
|
33
|
-
isDisabled: boolean;
|
|
34
|
-
/**
|
|
35
|
-
* If true, no `'*'` is appended to required form field labels.
|
|
36
|
-
*
|
|
37
|
-
* @default false
|
|
38
|
-
*/
|
|
39
|
-
hideRequiredMarkers: boolean;
|
|
40
|
-
}>
|
|
41
|
-
>
|
|
42
|
-
>()({
|
|
43
|
-
tagName: 'vira-form',
|
|
44
|
-
events: {
|
|
45
|
-
valueChange: defineElementEvent<
|
|
46
|
-
{
|
|
47
|
-
key: string;
|
|
48
|
-
} & ViraFormField
|
|
49
|
-
>(),
|
|
50
|
-
validChange: defineElementEvent<{
|
|
51
|
-
allFieldsAreValid: boolean;
|
|
52
|
-
}>(),
|
|
53
|
-
},
|
|
54
|
-
styles: css`
|
|
55
|
-
:host {
|
|
56
|
-
display: flex;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
form {
|
|
60
|
-
display: flex;
|
|
61
|
-
flex-grow: 1;
|
|
62
|
-
flex-direction: column;
|
|
63
|
-
align-items: stretch;
|
|
64
|
-
gap: 10px;
|
|
65
|
-
|
|
66
|
-
> * {
|
|
67
|
-
width: unset;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
`,
|
|
71
|
-
state() {
|
|
72
|
-
return {
|
|
73
|
-
lastIsValid: false,
|
|
74
|
-
};
|
|
75
|
-
},
|
|
76
|
-
render({inputs, dispatch, events, state, updateState}) {
|
|
77
|
-
const currentIsValid = areFormFieldsValid(inputs.fields);
|
|
78
|
-
if (currentIsValid !== state.lastIsValid) {
|
|
79
|
-
updateState({
|
|
80
|
-
lastIsValid: currentIsValid,
|
|
81
|
-
});
|
|
82
|
-
dispatch(new events.validChange({allFieldsAreValid: currentIsValid}));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const formFieldTemplates = getObjectTypedEntries(inputs.fields).map(
|
|
86
|
-
([
|
|
87
|
-
key,
|
|
88
|
-
field,
|
|
89
|
-
]) => {
|
|
90
|
-
if (field.isHidden) {
|
|
91
|
-
return nothing;
|
|
92
|
-
} else if (field.type === ViraFormFieldType.Checkbox) {
|
|
93
|
-
return html`
|
|
94
|
-
<${ViraCheckbox.assign({
|
|
95
|
-
value: field.value || false,
|
|
96
|
-
disabled: inputs.isDisabled || field.isDisabled,
|
|
97
|
-
hasError: field.hasError,
|
|
98
|
-
label: applyRequiredLabel(
|
|
99
|
-
field.label,
|
|
100
|
-
!!field.isRequired && !inputs.hideRequiredMarkers,
|
|
101
|
-
),
|
|
102
|
-
})}
|
|
103
|
-
${field.testId ? testId(field.testId) : nothing}
|
|
104
|
-
${listen(ViraCheckbox.events.valueChange, (event) => {
|
|
105
|
-
dispatch(
|
|
106
|
-
new events.valueChange({
|
|
107
|
-
key,
|
|
108
|
-
...field,
|
|
109
|
-
value: event.detail,
|
|
110
|
-
}),
|
|
111
|
-
);
|
|
112
|
-
})}
|
|
113
|
-
></${ViraCheckbox}>
|
|
114
|
-
`;
|
|
115
|
-
} else if (field.type === ViraFormFieldType.Select) {
|
|
116
|
-
return html`
|
|
117
|
-
<${ViraSelect.assign({
|
|
118
|
-
options: field.options,
|
|
119
|
-
value: field.value,
|
|
120
|
-
placeholder: field.placeholder,
|
|
121
|
-
disabled: inputs.isDisabled || field.isDisabled,
|
|
122
|
-
label: applyRequiredLabel(
|
|
123
|
-
field.label,
|
|
124
|
-
!!field.isRequired && !inputs.hideRequiredMarkers,
|
|
125
|
-
),
|
|
126
|
-
hasError: field.hasError,
|
|
127
|
-
icon: field.icon,
|
|
128
|
-
})}
|
|
129
|
-
${field.testId ? testId(field.testId) : nothing}
|
|
130
|
-
${listen(ViraSelect.events.valueChange, (event) => {
|
|
131
|
-
dispatch(
|
|
132
|
-
new events.valueChange({
|
|
133
|
-
key,
|
|
134
|
-
...field,
|
|
135
|
-
value: event.detail,
|
|
136
|
-
}),
|
|
137
|
-
);
|
|
138
|
-
})}
|
|
139
|
-
></${ViraSelect}>
|
|
140
|
-
`;
|
|
141
|
-
} else {
|
|
142
|
-
return html`
|
|
143
|
-
<${ViraInput.assign({
|
|
144
|
-
value: field.value || '',
|
|
145
|
-
disabled: inputs.isDisabled || field.isDisabled,
|
|
146
|
-
hasError: field.hasError,
|
|
147
|
-
icon: field.icon,
|
|
148
|
-
label: applyRequiredLabel(
|
|
149
|
-
field.label,
|
|
150
|
-
!!field.isRequired && !inputs.hideRequiredMarkers,
|
|
151
|
-
),
|
|
152
|
-
placeholder: field.placeholder,
|
|
153
|
-
showClearButton: inputs.showClearButtons,
|
|
154
|
-
attributePassthrough: field.isUsername
|
|
155
|
-
? {
|
|
156
|
-
autocomplete: 'username',
|
|
157
|
-
}
|
|
158
|
-
: field.type === ViraFormFieldType.NewPassword
|
|
159
|
-
? {
|
|
160
|
-
autocomplete: 'new-password',
|
|
161
|
-
}
|
|
162
|
-
: field.type === ViraFormFieldType.ExistingPassword
|
|
163
|
-
? {
|
|
164
|
-
autocomplete: 'password',
|
|
165
|
-
}
|
|
166
|
-
: field.type === ViraFormFieldType.Email
|
|
167
|
-
? {
|
|
168
|
-
autocomplete: 'email',
|
|
169
|
-
}
|
|
170
|
-
: {},
|
|
171
|
-
type: [
|
|
172
|
-
ViraFormFieldType.NewPassword,
|
|
173
|
-
ViraFormFieldType.ExistingPassword,
|
|
174
|
-
ViraFormFieldType.PlainPassword,
|
|
175
|
-
].includes(field.type)
|
|
176
|
-
? ViraInputType.Password
|
|
177
|
-
: field.type === ViraFormFieldType.Email
|
|
178
|
-
? ViraInputType.Email
|
|
179
|
-
: ViraInputType.Default,
|
|
180
|
-
})}
|
|
181
|
-
${field.testId ? testId(field.testId) : nothing}
|
|
182
|
-
${listen(ViraInput.events.valueChange, (event) => {
|
|
183
|
-
dispatch(
|
|
184
|
-
new events.valueChange({
|
|
185
|
-
key,
|
|
186
|
-
...field,
|
|
187
|
-
value: event.detail,
|
|
188
|
-
}),
|
|
189
|
-
);
|
|
190
|
-
})}
|
|
191
|
-
></${ViraInput}>
|
|
192
|
-
`;
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
return html`
|
|
198
|
-
<form ${listen('submit', (event) => event.preventDefault())}>
|
|
199
|
-
${formFieldTemplates}
|
|
200
|
-
<slot></slot>
|
|
201
|
-
</form>
|
|
202
|
-
`;
|
|
203
|
-
},
|
|
204
|
-
});
|