vira 28.19.6 → 28.20.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/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 +16 -0
- package/{src/elements/vira-collapsible-wrapper.element.ts → dist/elements/vira-collapsible-wrapper.element.js} +26 -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
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import {joinWithFinalConjunction, type PartialWithUndefined} from '@augment-vir/common';
|
|
2
|
-
import {
|
|
3
|
-
type PopUpManager,
|
|
4
|
-
type PopUpManagerOptions,
|
|
5
|
-
type ShowPopUpResult,
|
|
6
|
-
} from '../../util/pop-up-manager.js';
|
|
7
|
-
import {type MenuItem} from './pop-up-menu-item.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Verifies that all items have unique ids.
|
|
11
|
-
*
|
|
12
|
-
* @category Internal
|
|
13
|
-
*/
|
|
14
|
-
export function assertUniqueIdProps(items: ReadonlyArray<Readonly<{id: PropertyKey}>>) {
|
|
15
|
-
const usedIds = new Set<PropertyKey>();
|
|
16
|
-
const duplicateIds: PropertyKey[] = [];
|
|
17
|
-
items.forEach((option) => {
|
|
18
|
-
if (usedIds.has(option.id)) {
|
|
19
|
-
duplicateIds.push(option.id);
|
|
20
|
-
} else {
|
|
21
|
-
usedIds.add(option.id);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
if (duplicateIds.length) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`Duplicate option ids were given: ${joinWithFinalConjunction(duplicateIds)}`,
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Creates a new array of selections based on the current selection and new selection id. This
|
|
34
|
-
* behaves differently when multi select is enabled, hence this function.
|
|
35
|
-
*
|
|
36
|
-
* @category Internal
|
|
37
|
-
*/
|
|
38
|
-
export function updateSelectedItems(
|
|
39
|
-
/** The item that should be newly toggled. */
|
|
40
|
-
newItem: Readonly<MenuItem>,
|
|
41
|
-
currentSelection: ReadonlyArray<PropertyKey> = [],
|
|
42
|
-
isMultiSelect: boolean = false,
|
|
43
|
-
): PropertyKey[] {
|
|
44
|
-
if (isMultiSelect) {
|
|
45
|
-
return currentSelection.includes(newItem.id)
|
|
46
|
-
? currentSelection.filter((entry) => entry !== newItem.id)
|
|
47
|
-
: [
|
|
48
|
-
...currentSelection,
|
|
49
|
-
newItem.id,
|
|
50
|
-
];
|
|
51
|
-
} else {
|
|
52
|
-
/** In single select, only the toggled item is allowed. */
|
|
53
|
-
return [newItem.id];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Handles toggling pop up state for `ViraDropdown`.
|
|
59
|
-
*
|
|
60
|
-
* @category Internal
|
|
61
|
-
*/
|
|
62
|
-
export function triggerPopUpState({
|
|
63
|
-
open,
|
|
64
|
-
callback,
|
|
65
|
-
popUpManager,
|
|
66
|
-
host,
|
|
67
|
-
options,
|
|
68
|
-
}: Readonly<
|
|
69
|
-
{
|
|
70
|
-
open: boolean;
|
|
71
|
-
popUpManager: PopUpManager;
|
|
72
|
-
host: HTMLElement;
|
|
73
|
-
} & PartialWithUndefined<{
|
|
74
|
-
callback?: ((showPopUpResult: ShowPopUpResult | undefined) => void) | undefined;
|
|
75
|
-
options?: Partial<PopUpManagerOptions> | undefined;
|
|
76
|
-
}>
|
|
77
|
-
>) {
|
|
78
|
-
if (open) {
|
|
79
|
-
const showPopUpResult = popUpManager.showPopUp(host, options);
|
|
80
|
-
callback?.(showPopUpResult);
|
|
81
|
-
} else {
|
|
82
|
-
popUpManager.removePopUp();
|
|
83
|
-
callback?.(undefined);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import {type PartialWithUndefined} from '@augment-vir/common';
|
|
2
|
-
import {type NavController} from 'device-navigation';
|
|
3
|
-
import {classMap, css, defineElementEvent, html, listen, nothing, testId} from 'element-vir';
|
|
4
|
-
import {type PopUpManager, type ShowPopUpResult} from '../../util/pop-up-manager.js';
|
|
5
|
-
import {defineViraElement} from '../define-vira-element.js';
|
|
6
|
-
import {updateSelectedItems} from './pop-up-helpers.js';
|
|
7
|
-
import {type MenuItem} from './pop-up-menu-item.js';
|
|
8
|
-
import {ViraMenu} from './vira-menu.element.js';
|
|
9
|
-
import {
|
|
10
|
-
PopUpMenuDirection,
|
|
11
|
-
ViraPopUpMenu,
|
|
12
|
-
type PopUpMenuCornerStyle,
|
|
13
|
-
} from './vira-pop-up-menu.element.js';
|
|
14
|
-
import {
|
|
15
|
-
HorizontalAnchor,
|
|
16
|
-
ViraPopUpTrigger,
|
|
17
|
-
type PopUpOffset,
|
|
18
|
-
type PopUpTriggerPosition,
|
|
19
|
-
} from './vira-pop-up-trigger.element.js';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Test ids for {@link ViraMenuTrigger}.
|
|
23
|
-
*
|
|
24
|
-
* @category Internal
|
|
25
|
-
*/
|
|
26
|
-
export const viraMenuTriggerTestIds = {
|
|
27
|
-
menu: 'menu-trigger-menu',
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* A more specific wrapper of `ViraPopUpTrigger` that always opens a menu.
|
|
32
|
-
*
|
|
33
|
-
* @category PopUp
|
|
34
|
-
* @category Elements
|
|
35
|
-
*/
|
|
36
|
-
export const ViraMenuTrigger = defineViraElement<
|
|
37
|
-
{
|
|
38
|
-
items: ReadonlyArray<Readonly<MenuItem>>;
|
|
39
|
-
} & PartialWithUndefined<
|
|
40
|
-
{
|
|
41
|
-
/** The selected item ids from the given `items` object. */
|
|
42
|
-
selected: ReadonlyArray<PropertyKey>;
|
|
43
|
-
isDisabled: boolean;
|
|
44
|
-
isMultiSelect: boolean;
|
|
45
|
-
z_debug_forceOpenState: boolean;
|
|
46
|
-
popUpOffset: PopUpOffset;
|
|
47
|
-
/** Hide menu item check mark icons. */
|
|
48
|
-
hideCheckIcons: boolean;
|
|
49
|
-
menuCornerStyle: PopUpMenuCornerStyle;
|
|
50
|
-
} & PopUpTriggerPosition
|
|
51
|
-
>
|
|
52
|
-
>()({
|
|
53
|
-
tagName: 'vira-menu-trigger',
|
|
54
|
-
styles: css`
|
|
55
|
-
:host {
|
|
56
|
-
display: inline-flex;
|
|
57
|
-
box-sizing: border-box;
|
|
58
|
-
vertical-align: middle;
|
|
59
|
-
max-width: 100%;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
${ViraPopUpTrigger} {
|
|
63
|
-
width: 100%;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.full-width-menu {
|
|
67
|
-
width: 100%;
|
|
68
|
-
}
|
|
69
|
-
`,
|
|
70
|
-
events: {
|
|
71
|
-
itemActivate: defineElementEvent<PropertyKey[]>(),
|
|
72
|
-
openChange: defineElementEvent<ShowPopUpResult | undefined>(),
|
|
73
|
-
},
|
|
74
|
-
state() {
|
|
75
|
-
return {
|
|
76
|
-
navController: undefined as undefined | NavController,
|
|
77
|
-
popUpManager: undefined as undefined | PopUpManager,
|
|
78
|
-
/** `undefined` means the pop up is not currently showing. */
|
|
79
|
-
showPopUpResult: undefined as ShowPopUpResult | undefined,
|
|
80
|
-
};
|
|
81
|
-
},
|
|
82
|
-
render({inputs, state, updateState, dispatch, events}) {
|
|
83
|
-
return html`
|
|
84
|
-
<${ViraPopUpTrigger.assign({
|
|
85
|
-
...inputs,
|
|
86
|
-
keepOpenAfterInteraction: true,
|
|
87
|
-
popUpOffset: inputs.popUpOffset,
|
|
88
|
-
horizontalAnchor: inputs.horizontalAnchor || HorizontalAnchor.Left,
|
|
89
|
-
})}
|
|
90
|
-
class=${classMap({
|
|
91
|
-
open: !!state.showPopUpResult,
|
|
92
|
-
})}
|
|
93
|
-
${listen(ViraPopUpTrigger.events.init, (event) => {
|
|
94
|
-
updateState({
|
|
95
|
-
navController: event.detail.navController,
|
|
96
|
-
popUpManager: event.detail.popUpManager,
|
|
97
|
-
});
|
|
98
|
-
})}
|
|
99
|
-
${listen(ViraPopUpTrigger.events.openChange, (event) => {
|
|
100
|
-
if (!!state.showPopUpResult !== !!event.detail) {
|
|
101
|
-
dispatch(new events.openChange(event.detail));
|
|
102
|
-
}
|
|
103
|
-
updateState({
|
|
104
|
-
showPopUpResult: event.detail,
|
|
105
|
-
});
|
|
106
|
-
})}
|
|
107
|
-
${listen(ViraPopUpTrigger.events.navSelect, (event) => {
|
|
108
|
-
const itemIndex = event.detail.x;
|
|
109
|
-
const item = inputs.items[itemIndex];
|
|
110
|
-
if (!item) {
|
|
111
|
-
throw new Error(`Found no dropdown option at index '${itemIndex}'`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
dispatch(
|
|
115
|
-
new events.itemActivate(
|
|
116
|
-
updateSelectedItems(item, inputs.selected, inputs.isMultiSelect),
|
|
117
|
-
),
|
|
118
|
-
);
|
|
119
|
-
if (!inputs.isMultiSelect) {
|
|
120
|
-
/**
|
|
121
|
-
* Defer pop up removal to prevent race conditions with element-internal
|
|
122
|
-
* click handlers.
|
|
123
|
-
*/
|
|
124
|
-
globalThis.setTimeout(() => state.popUpManager?.removePopUp());
|
|
125
|
-
}
|
|
126
|
-
})}
|
|
127
|
-
>
|
|
128
|
-
<slot slot=${ViraPopUpTrigger.slotNames.trigger}></slot>
|
|
129
|
-
${state.navController && state.showPopUpResult
|
|
130
|
-
? html`
|
|
131
|
-
<${ViraPopUpMenu.assign({
|
|
132
|
-
direction: state.showPopUpResult.popDown
|
|
133
|
-
? PopUpMenuDirection.Downwards
|
|
134
|
-
: PopUpMenuDirection.Upwards,
|
|
135
|
-
cornerStyle: inputs.menuCornerStyle,
|
|
136
|
-
})}
|
|
137
|
-
slot=${ViraPopUpTrigger.slotNames.popUp}
|
|
138
|
-
class=${classMap({
|
|
139
|
-
'full-width-menu':
|
|
140
|
-
inputs.horizontalAnchor === HorizontalAnchor.Both,
|
|
141
|
-
})}
|
|
142
|
-
>
|
|
143
|
-
<${ViraMenu.assign({
|
|
144
|
-
items: inputs.items,
|
|
145
|
-
selected: inputs.selected,
|
|
146
|
-
navController: state.navController,
|
|
147
|
-
isMultiSelect: !!inputs.isMultiSelect,
|
|
148
|
-
hideCheckIcons: inputs.hideCheckIcons,
|
|
149
|
-
})}
|
|
150
|
-
${testId(viraMenuTriggerTestIds.menu)}
|
|
151
|
-
></${ViraMenu}>
|
|
152
|
-
</${ViraPopUpMenu}>
|
|
153
|
-
`
|
|
154
|
-
: nothing}
|
|
155
|
-
</${ViraPopUpTrigger}>
|
|
156
|
-
`;
|
|
157
|
-
},
|
|
158
|
-
});
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import {check, checkWrap} from '@augment-vir/assert';
|
|
2
|
-
import {type PartialWithUndefined} from '@augment-vir/common';
|
|
3
|
-
import {extractEventTarget} from '@augment-vir/web';
|
|
4
|
-
import {type AttributeValues} from 'element-vir';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Inputs shared between the multiple input elements.
|
|
8
|
-
*
|
|
9
|
-
* @category Internal
|
|
10
|
-
*/
|
|
11
|
-
export type SharedTextInputElementInputs = {
|
|
12
|
-
value: string;
|
|
13
|
-
} & PartialWithUndefined<{
|
|
14
|
-
/** Shown when no other text is present. Input restrictions do not apply to this property. */
|
|
15
|
-
placeholder: string;
|
|
16
|
-
/** Set to true to trigger disabled styles and to block all user input. */
|
|
17
|
-
disabled: boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Only letters in the given string or matches to the given RegExp will be allowed.
|
|
20
|
-
* blockedInputs takes precedence over this input.
|
|
21
|
-
*
|
|
22
|
-
* For example: if allowedInputs is set to "abcd" and blockedInputs is set to "d", only "a",
|
|
23
|
-
* "b", or "c" letters will be allowed.
|
|
24
|
-
*/
|
|
25
|
-
allowedInputs: string | RegExp;
|
|
26
|
-
/** Any letters in the given string or matches to the given RegExp will be blocked. */
|
|
27
|
-
blockedInputs: string | RegExp;
|
|
28
|
-
/** Disable all browser helps like spellchecking, autocomplete, etc. */
|
|
29
|
-
disableBrowserHelps: boolean;
|
|
30
|
-
/** Set this to true to make the whole element size to only fit the input text. */
|
|
31
|
-
fitText: boolean;
|
|
32
|
-
/** A set of attributes that will be applied to the inner native text element. */
|
|
33
|
-
attributePassthrough: AttributeValues;
|
|
34
|
-
}>;
|
|
35
|
-
|
|
36
|
-
function doesMatch({input, matcher}: {input: string; matcher: string | RegExp}): boolean {
|
|
37
|
-
if (!input || !matcher) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
if (input.length > 1) {
|
|
41
|
-
return input.split('').every((singleInput) => doesMatch({input: singleInput, matcher}));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (matcher instanceof RegExp) {
|
|
45
|
-
return !!input.match(matcher);
|
|
46
|
-
} else {
|
|
47
|
-
return matcher.includes(input);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Inputs used to check if the current input element value is allowed.
|
|
53
|
-
*
|
|
54
|
-
* @category Internal
|
|
55
|
-
*/
|
|
56
|
-
export type IsAllowedInputs = {
|
|
57
|
-
value: string;
|
|
58
|
-
allowed: string | RegExp | undefined;
|
|
59
|
-
blocked: string | RegExp | undefined;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
function isAllowed({value, allowed, blocked}: IsAllowedInputs) {
|
|
63
|
-
const isAllowedCharacter = allowed
|
|
64
|
-
? doesMatch({
|
|
65
|
-
input: value,
|
|
66
|
-
matcher: allowed,
|
|
67
|
-
})
|
|
68
|
-
: true;
|
|
69
|
-
const isBlockedCharacter = blocked
|
|
70
|
-
? doesMatch({
|
|
71
|
-
input: value,
|
|
72
|
-
matcher: blocked,
|
|
73
|
-
})
|
|
74
|
-
: false;
|
|
75
|
-
|
|
76
|
-
return isAllowedCharacter && !isBlockedCharacter;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Filters out blocked text from an input element's value.
|
|
81
|
-
*
|
|
82
|
-
* @category Internal
|
|
83
|
-
*/
|
|
84
|
-
export function filterTextInputValue(inputs: IsAllowedInputs): {
|
|
85
|
-
filtered: string;
|
|
86
|
-
blocked: string;
|
|
87
|
-
} {
|
|
88
|
-
if (!inputs.value) {
|
|
89
|
-
return {filtered: inputs.value, blocked: ''};
|
|
90
|
-
}
|
|
91
|
-
const {filtered, blocked} = inputs.value.split('').reduce(
|
|
92
|
-
(accum, letter) => {
|
|
93
|
-
const allowed = isAllowed({...inputs, value: letter});
|
|
94
|
-
|
|
95
|
-
if (allowed) {
|
|
96
|
-
accum.filtered.push(letter);
|
|
97
|
-
} else {
|
|
98
|
-
accum.blocked.push(letter);
|
|
99
|
-
}
|
|
100
|
-
return accum;
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
filtered: [] as string[],
|
|
104
|
-
blocked: [] as string[],
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
filtered: filtered.join(''),
|
|
110
|
-
blocked: blocked.join(''),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* A function to be called when an input element's value changes.
|
|
116
|
-
*
|
|
117
|
-
* @category Internal
|
|
118
|
-
*/
|
|
119
|
-
export function textInputListener({
|
|
120
|
-
inputs,
|
|
121
|
-
previousValue,
|
|
122
|
-
event,
|
|
123
|
-
inputBlockedCallback,
|
|
124
|
-
newValueCallback,
|
|
125
|
-
}: {
|
|
126
|
-
inputs: SharedTextInputElementInputs;
|
|
127
|
-
/** The value of the input element before this listener fired. */
|
|
128
|
-
previousValue: string;
|
|
129
|
-
event: Event;
|
|
130
|
-
inputBlockedCallback: (blockedInput: string) => void;
|
|
131
|
-
newValueCallback: (newValue: string) => void;
|
|
132
|
-
}) {
|
|
133
|
-
const inputElement = extractEventTarget(event, HTMLInputElement);
|
|
134
|
-
/**
|
|
135
|
-
* This is usually a single character, but can be a bunch of characters in some circumstances.
|
|
136
|
-
* For example, when a bunch of characters are pasted, this will be the entire pasted contents.
|
|
137
|
-
*
|
|
138
|
-
* When a password manager auto fills the password, at least for Safari + iCloud Keychain, it'll
|
|
139
|
-
* fire a `CustomEvent` (rather than the typical `InputEvent`) and `event.data` won't be
|
|
140
|
-
* populated.
|
|
141
|
-
*/
|
|
142
|
-
const changedText: string =
|
|
143
|
-
(check.hasKey(event, 'data') && checkWrap.isString(event.data)) || '';
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* When changedText is falsy, that means an operation other than inserting characters happened.
|
|
147
|
-
* Such as: deleting, cutting the text, etc.
|
|
148
|
-
*/
|
|
149
|
-
if (changedText) {
|
|
150
|
-
const {blocked} = filterTextInputValue({
|
|
151
|
-
value: changedText,
|
|
152
|
-
allowed: inputs.allowedInputs,
|
|
153
|
-
blocked: inputs.blockedInputs,
|
|
154
|
-
});
|
|
155
|
-
if (blocked.length) {
|
|
156
|
-
inputBlockedCallback(blocked);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const finalValue = filterTextInputValue({
|
|
161
|
-
value: inputElement.value,
|
|
162
|
-
allowed: inputs.allowedInputs,
|
|
163
|
-
blocked: inputs.blockedInputs,
|
|
164
|
-
}).filtered;
|
|
165
|
-
|
|
166
|
-
if (inputElement.value !== finalValue) {
|
|
167
|
-
// this prevents blocked inputs by simply overwriting them
|
|
168
|
-
inputElement.value = finalValue;
|
|
169
|
-
}
|
|
170
|
-
if (previousValue !== finalValue) {
|
|
171
|
-
newValueCallback(finalValue);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import {css, html, onDomCreated} from 'element-vir';
|
|
2
|
-
import {type RequireExactlyOne} from 'type-fest';
|
|
3
|
-
import {listenTo} from 'typed-event-target';
|
|
4
|
-
import {defineViraElement} from './define-vira-element.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* An element switches between two slots based on their overflow.
|
|
8
|
-
*
|
|
9
|
-
* @category Elements
|
|
10
|
-
* @see https://electrovir.github.io/vira/book/elements/vira-overflow-switch
|
|
11
|
-
*/
|
|
12
|
-
export const ViraOverflowSwitch = defineViraElement<
|
|
13
|
-
Readonly<
|
|
14
|
-
RequireExactlyOne<{
|
|
15
|
-
automaticallySwitch: boolean;
|
|
16
|
-
useSmall: boolean;
|
|
17
|
-
}>
|
|
18
|
-
>
|
|
19
|
-
>()({
|
|
20
|
-
tagName: 'vira-overflow-switch',
|
|
21
|
-
slotNames: [
|
|
22
|
-
/** The child to render, if it fits. */
|
|
23
|
-
'large',
|
|
24
|
-
/** The child to render if the large one does not fit. */
|
|
25
|
-
'small',
|
|
26
|
-
],
|
|
27
|
-
state() {
|
|
28
|
-
return {
|
|
29
|
-
isOverflowing: false,
|
|
30
|
-
resizeObserver: undefined as undefined | ResizeObserver,
|
|
31
|
-
/** Called on cleanup to clear all listeners. */
|
|
32
|
-
cleanup: undefined as undefined | (() => void),
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
hostClasses: {
|
|
36
|
-
'vira-overflow-switch-show-small': ({state, inputs}) =>
|
|
37
|
-
state.isOverflowing || !!inputs.useSmall,
|
|
38
|
-
},
|
|
39
|
-
styles: ({hostClasses}) => css`
|
|
40
|
-
:host {
|
|
41
|
-
display: inline-block;
|
|
42
|
-
max-width: 100%;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.large,
|
|
46
|
-
.small {
|
|
47
|
-
display: inline-block;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.small {
|
|
51
|
-
display: none;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* When the large content overflows, hide it but keep it in layout so we can measure it.
|
|
56
|
-
* The small content is then shown instead.
|
|
57
|
-
*/
|
|
58
|
-
${hostClasses['vira-overflow-switch-show-small'].selector} .large {
|
|
59
|
-
visibility: hidden;
|
|
60
|
-
position: absolute;
|
|
61
|
-
top: 0;
|
|
62
|
-
left: 0;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
${hostClasses['vira-overflow-switch-show-small'].selector} .small {
|
|
66
|
-
display: inline-block;
|
|
67
|
-
}
|
|
68
|
-
`,
|
|
69
|
-
cleanup({state, updateState}) {
|
|
70
|
-
state.cleanup?.();
|
|
71
|
-
updateState({
|
|
72
|
-
cleanup: undefined,
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
|
-
render({slotNames, updateState, inputs, host, state}) {
|
|
76
|
-
return html`
|
|
77
|
-
<div
|
|
78
|
-
class="large"
|
|
79
|
-
${onDomCreated((largeElement) => {
|
|
80
|
-
if (!inputs.automaticallySwitch) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const overflowParams: Parameters<typeof updateOverflowing>[0] = {
|
|
85
|
-
elementToTest: largeElement,
|
|
86
|
-
host,
|
|
87
|
-
updateState,
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
91
|
-
updateOverflowing(overflowParams);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
resizeObserver.observe(host);
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Also observe the large slot wrapper itself in case its own layout changes
|
|
98
|
-
* without host resizing.
|
|
99
|
-
*/
|
|
100
|
-
resizeObserver.observe(largeElement);
|
|
101
|
-
|
|
102
|
-
const removeSlotChangeListener = listenTo(largeElement, 'slotchange', () => {
|
|
103
|
-
updateOverflowing(overflowParams);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
/** Initial measurement: defer until after first layout. */
|
|
107
|
-
updateOverflowing(overflowParams);
|
|
108
|
-
|
|
109
|
-
state.cleanup?.();
|
|
110
|
-
updateState({
|
|
111
|
-
cleanup() {
|
|
112
|
-
resizeObserver.disconnect();
|
|
113
|
-
removeSlotChangeListener();
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
|
-
})}
|
|
117
|
-
>
|
|
118
|
-
<slot name=${slotNames.large}></slot>
|
|
119
|
-
</div>
|
|
120
|
-
<div class="small"><slot name=${slotNames.small}></slot></div>
|
|
121
|
-
`;
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
function updateOverflowing({
|
|
126
|
-
elementToTest,
|
|
127
|
-
host,
|
|
128
|
-
updateState,
|
|
129
|
-
}: {
|
|
130
|
-
host: Element;
|
|
131
|
-
updateState: (newState: Partial<{isOverflowing: boolean}>) => void;
|
|
132
|
-
elementToTest: Element;
|
|
133
|
-
}) {
|
|
134
|
-
const isOverflowing = elementToTest.scrollWidth > host.clientWidth;
|
|
135
|
-
|
|
136
|
-
updateState({isOverflowing});
|
|
137
|
-
}
|
package/src/icons/icon-svg.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {getObjectTypedKeys, stringify} from '@augment-vir/common';
|
|
2
|
-
import Color, {type ColorTypes} from 'colorjs.io';
|
|
3
|
-
import {type TemplateResult, html} from 'element-vir';
|
|
4
|
-
import {viraIconCssVars} from './icon-css-vars.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* An individual Vira icon SVG definition.
|
|
8
|
-
*
|
|
9
|
-
* @category Icon
|
|
10
|
-
*/
|
|
11
|
-
export type ViraIconSvg = {
|
|
12
|
-
name: string;
|
|
13
|
-
svgTemplate: TemplateResult;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A function used to define an individual Vira icon SVG.
|
|
18
|
-
*
|
|
19
|
-
* @category Icon
|
|
20
|
-
*/
|
|
21
|
-
export function defineIcon({
|
|
22
|
-
name,
|
|
23
|
-
svgTemplate,
|
|
24
|
-
}: {
|
|
25
|
-
name: string;
|
|
26
|
-
svgTemplate: TemplateResult;
|
|
27
|
-
}): ViraIconSvg {
|
|
28
|
-
const iconSvg: ViraIconSvg = {
|
|
29
|
-
name,
|
|
30
|
-
svgTemplate,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return iconSvg;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function getAssertedValidColor(input: ColorTypes | undefined) {
|
|
37
|
-
try {
|
|
38
|
-
if (!input) {
|
|
39
|
-
throw new Error('invalid empty color');
|
|
40
|
-
}
|
|
41
|
-
return new Color(input);
|
|
42
|
-
} catch {
|
|
43
|
-
throw new Error(`Invalid color: ${stringify(input)}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Wraps an existing icon with a specific color and outputs another icon that can be used anywhere
|
|
49
|
-
* the original icon can be used.
|
|
50
|
-
*
|
|
51
|
-
* @category Icon
|
|
52
|
-
*/
|
|
53
|
-
export function createColoredIcon(
|
|
54
|
-
icon: ViraIconSvg,
|
|
55
|
-
colors: Partial<Record<keyof typeof viraIconCssVars, string>>,
|
|
56
|
-
): ViraIconSvg {
|
|
57
|
-
const colorStyles = getObjectTypedKeys(colors)
|
|
58
|
-
.map((cssVarName) => {
|
|
59
|
-
const colorValue = colors[cssVarName];
|
|
60
|
-
const color = getAssertedValidColor(colorValue);
|
|
61
|
-
return `${viraIconCssVars[cssVarName].name}: ${color.toString()};`;
|
|
62
|
-
})
|
|
63
|
-
.join(' ');
|
|
64
|
-
|
|
65
|
-
return defineIcon({
|
|
66
|
-
name: icon.name,
|
|
67
|
-
svgTemplate: html`
|
|
68
|
-
<div style=${colorStyles}>${icon.svgTemplate}</div>
|
|
69
|
-
`,
|
|
70
|
-
});
|
|
71
|
-
}
|