vira 25.7.2 → 25.8.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/index.d.ts +8 -3
- package/dist/elements/index.js +8 -3
- package/dist/elements/pop-up/pop-up-helpers.d.ts +30 -0
- package/dist/elements/pop-up/pop-up-helpers.js +58 -0
- package/dist/elements/pop-up/pop-up-menu-item.d.ts +24 -0
- package/dist/elements/pop-up/pop-up-menu-item.js +1 -0
- package/dist/elements/pop-up/vira-menu-item.element.d.ts +15 -0
- package/dist/elements/{dropdown/vira-dropdown-item.element.js → pop-up/vira-menu-item.element.js} +9 -22
- package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +37 -0
- package/dist/elements/pop-up/vira-menu-trigger.element.js +107 -0
- package/dist/elements/pop-up/vira-menu.element.d.ts +36 -0
- package/dist/elements/pop-up/vira-menu.element.js +129 -0
- package/dist/elements/pop-up/vira-pop-up-menu.element.d.ts +10 -0
- package/dist/elements/pop-up/vira-pop-up-menu.element.js +48 -0
- package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +44 -0
- package/dist/elements/pop-up/vira-pop-up-trigger.element.js +235 -0
- package/dist/elements/vira-bold-text.element.js +3 -2
- package/dist/elements/{dropdown/vira-dropdown.element.d.ts → vira-dropdown.element.d.ts} +12 -9
- package/dist/elements/vira-dropdown.element.js +185 -0
- package/dist/styles/focus.d.ts +0 -1
- package/dist/util/pop-up-manager.d.ts +1 -1
- package/dist/util/pop-up-manager.js +20 -9
- package/package.json +11 -10
- package/dist/elements/dropdown/dropdown-helpers.d.ts +0 -45
- package/dist/elements/dropdown/dropdown-helpers.js +0 -78
- package/dist/elements/dropdown/vira-dropdown-item.element.d.ts +0 -27
- package/dist/elements/dropdown/vira-dropdown-options.element.d.ts +0 -29
- package/dist/elements/dropdown/vira-dropdown-options.element.js +0 -116
- package/dist/elements/dropdown/vira-dropdown.element.js +0 -324
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { joinWithFinalConjunction } from '@augment-vir/common';
|
|
2
|
-
/**
|
|
3
|
-
* Filters an array of {@link ViraDropdownOption} based on the given selection.
|
|
4
|
-
*
|
|
5
|
-
* @category Internal
|
|
6
|
-
*/
|
|
7
|
-
export function filterToSelectedOptions({ selected, options, isMultiSelect, }) {
|
|
8
|
-
if (selected.length && options.length) {
|
|
9
|
-
const selectedOptions = options.filter((option) => selected.includes(option.id));
|
|
10
|
-
if (selectedOptions.length > 1 && !isMultiSelect) {
|
|
11
|
-
console.error(`vira-dropdown has multiple selections but \`isMultiSelect\` is not \`true\`. Truncating to the first selection.`);
|
|
12
|
-
return selectedOptions.slice(0, 1);
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return selectedOptions;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Verifies that all options have unique ids.
|
|
24
|
-
*
|
|
25
|
-
* @category Internal
|
|
26
|
-
*/
|
|
27
|
-
export function assertUniqueIdProps(options) {
|
|
28
|
-
const usedIds = new Set();
|
|
29
|
-
const duplicateIds = [];
|
|
30
|
-
options.forEach((option) => {
|
|
31
|
-
if (usedIds.has(option.id)) {
|
|
32
|
-
duplicateIds.push(option.id);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
usedIds.add(option.id);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
if (duplicateIds.length) {
|
|
39
|
-
throw new Error(`Duplicate option ids were given to ViraDropdown: ${joinWithFinalConjunction(duplicateIds)}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Creates a new array of selections based on the current selection and new selection id. This
|
|
44
|
-
* behaves differently when multi select is enabled, hence this function.
|
|
45
|
-
*
|
|
46
|
-
* @category Internal
|
|
47
|
-
*/
|
|
48
|
-
export function createNewSelection(
|
|
49
|
-
/** The id of the option that should be newly selected. */
|
|
50
|
-
id, currentSelection, isMultiSelect) {
|
|
51
|
-
if (isMultiSelect) {
|
|
52
|
-
return currentSelection.includes(id)
|
|
53
|
-
? currentSelection.filter((entry) => entry !== id)
|
|
54
|
-
: [
|
|
55
|
-
...currentSelection,
|
|
56
|
-
id,
|
|
57
|
-
];
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return [id];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Handles toggles pop up state for `ViraDropdown`.
|
|
65
|
-
*
|
|
66
|
-
* @category Internal
|
|
67
|
-
*/
|
|
68
|
-
export function triggerPopUpState({ open, emitEvent }, { updateState, popUpManager, dispatch, host, }) {
|
|
69
|
-
if (open) {
|
|
70
|
-
updateState({ showPopUpResult: popUpManager.showPopUp(host) });
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
popUpManager.removePopUp();
|
|
74
|
-
}
|
|
75
|
-
if (emitEvent) {
|
|
76
|
-
dispatch(open);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
-
import { type HTMLTemplateResult } from 'element-vir';
|
|
3
|
-
/**
|
|
4
|
-
* An individual option for ViraDropdown.
|
|
5
|
-
*
|
|
6
|
-
* @category Dropdown
|
|
7
|
-
*/
|
|
8
|
-
export type ViraDropdownOption = {
|
|
9
|
-
/** Each `id` must be unique across all options. */
|
|
10
|
-
id: PropertyKey;
|
|
11
|
-
label: string;
|
|
12
|
-
} & PartialWithUndefined<{
|
|
13
|
-
disabled: boolean;
|
|
14
|
-
hoverText: string;
|
|
15
|
-
/** An optional custom template for this option. */
|
|
16
|
-
template: HTMLTemplateResult;
|
|
17
|
-
}>;
|
|
18
|
-
/**
|
|
19
|
-
* An element for an individual item in the ViraDropdown menu.
|
|
20
|
-
*
|
|
21
|
-
* @category Dropdown
|
|
22
|
-
* @category Elements
|
|
23
|
-
*/
|
|
24
|
-
export declare const ViraDropdownItem: import("element-vir").DeclarativeElementDefinition<"vira-dropdown-item", {
|
|
25
|
-
label: string;
|
|
26
|
-
selected: boolean;
|
|
27
|
-
}, {}, {}, "vira-dropdown-item-selected", "vira-dropdown-item-", readonly []>;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type NavController } from 'device-navigation';
|
|
2
|
-
import { type ViraDropdownOption } from './vira-dropdown-item.element.js';
|
|
3
|
-
/**
|
|
4
|
-
* Test ids for {@link ViraDropdownOptions}.
|
|
5
|
-
*
|
|
6
|
-
* @category Internal
|
|
7
|
-
*/
|
|
8
|
-
export declare const viraDropdownOptionsTestIds: {
|
|
9
|
-
option: string;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* The dropdown menu portion of `ViraDropdown`.
|
|
13
|
-
*
|
|
14
|
-
* @category Dropdown
|
|
15
|
-
* @category Elements
|
|
16
|
-
*/
|
|
17
|
-
export declare const ViraDropdownOptions: import("element-vir").DeclarativeElementDefinition<"vira-dropdown-options", Readonly<{
|
|
18
|
-
navController: NavController;
|
|
19
|
-
/** All dropdown options to show to the user. */
|
|
20
|
-
options: ReadonlyArray<Readonly<ViraDropdownOption>>;
|
|
21
|
-
/**
|
|
22
|
-
* The currently selected dropdown options. Note that this must be a reference subset of the
|
|
23
|
-
* options input. Meaning, entries in this array must be the exact same objects (by
|
|
24
|
-
* reference) as entries in the `options` input array for them to be marked as selected.
|
|
25
|
-
*/
|
|
26
|
-
selectedOptions: ReadonlyArray<Readonly<ViraDropdownOption>>;
|
|
27
|
-
}>, {}, {
|
|
28
|
-
selectionChange: import("element-vir").DefineEvent<Readonly<ViraDropdownOption>>;
|
|
29
|
-
}, "vira-dropdown-options-", "vira-dropdown-options-", readonly []>;
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { nav, navAttribute, NavValue } from 'device-navigation';
|
|
2
|
-
import { classMap, css, defineElementEvent, html, ifDefined, listen, testId } from 'element-vir';
|
|
3
|
-
import { viraBorders } from '../../styles/border.js';
|
|
4
|
-
import { viraFormCssVars } from '../../styles/form-themes.js';
|
|
5
|
-
import { viraDisabledStyles } from '../../styles/index.js';
|
|
6
|
-
import { viraShadows } from '../../styles/shadows.js';
|
|
7
|
-
import { defineViraElement } from '../define-vira-element.js';
|
|
8
|
-
import { ViraDropdownItem } from './vira-dropdown-item.element.js';
|
|
9
|
-
/**
|
|
10
|
-
* Test ids for {@link ViraDropdownOptions}.
|
|
11
|
-
*
|
|
12
|
-
* @category Internal
|
|
13
|
-
*/
|
|
14
|
-
export const viraDropdownOptionsTestIds = {
|
|
15
|
-
option: 'dropdown-option',
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* The dropdown menu portion of `ViraDropdown`.
|
|
19
|
-
*
|
|
20
|
-
* @category Dropdown
|
|
21
|
-
* @category Elements
|
|
22
|
-
*/
|
|
23
|
-
export const ViraDropdownOptions = defineViraElement()({
|
|
24
|
-
tagName: 'vira-dropdown-options',
|
|
25
|
-
events: {
|
|
26
|
-
selectionChange: defineElementEvent(),
|
|
27
|
-
},
|
|
28
|
-
styles: css `
|
|
29
|
-
:host {
|
|
30
|
-
display: flex;
|
|
31
|
-
flex-direction: column;
|
|
32
|
-
|
|
33
|
-
pointer-events: auto;
|
|
34
|
-
width: 100%;
|
|
35
|
-
max-height: 100%;
|
|
36
|
-
overflow-y: auto;
|
|
37
|
-
z-index: 99;
|
|
38
|
-
border-radius: ${viraBorders['vira-form-input-radius'].value};
|
|
39
|
-
border-top-left-radius: 0;
|
|
40
|
-
border-top-right-radius: 0;
|
|
41
|
-
background-color: ${viraFormCssVars['vira-form-background-color'].value};
|
|
42
|
-
border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
|
|
43
|
-
color: ${viraFormCssVars['vira-form-foreground-color'].value};
|
|
44
|
-
${viraShadows.menuShadow}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.dropdown-item {
|
|
48
|
-
background-color: white;
|
|
49
|
-
outline: none;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
${navAttribute.css({
|
|
53
|
-
baseSelector: '.dropdown-item:not(.disabled):not(.selected)',
|
|
54
|
-
navValue: NavValue.Focused,
|
|
55
|
-
})} {
|
|
56
|
-
background-color: ${viraFormCssVars['vira-form-selection-hover-background-color']
|
|
57
|
-
.value};
|
|
58
|
-
outline: none;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
${ViraDropdownItem} {
|
|
62
|
-
pointer-events: none;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.dropdown-item.disabled {
|
|
66
|
-
${viraDisabledStyles};
|
|
67
|
-
pointer-events: auto;
|
|
68
|
-
}
|
|
69
|
-
`,
|
|
70
|
-
render({ inputs, dispatch, events }) {
|
|
71
|
-
const optionTemplates = inputs.options.map((option) => {
|
|
72
|
-
const selected = inputs.selectedOptions.includes(option);
|
|
73
|
-
const innerTemplate = option.template ||
|
|
74
|
-
html `
|
|
75
|
-
<${ViraDropdownItem.assign({
|
|
76
|
-
label: option.label,
|
|
77
|
-
selected,
|
|
78
|
-
})}></${ViraDropdownItem}>
|
|
79
|
-
`;
|
|
80
|
-
return html `
|
|
81
|
-
<div
|
|
82
|
-
class="dropdown-item ${classMap({
|
|
83
|
-
disabled: !!option.disabled,
|
|
84
|
-
selected,
|
|
85
|
-
})}"
|
|
86
|
-
${testId(viraDropdownOptionsTestIds.option)}
|
|
87
|
-
title=${ifDefined(option.hoverText || undefined)}
|
|
88
|
-
role="option"
|
|
89
|
-
${nav(inputs.navController, { disabled: option.disabled || selected })}
|
|
90
|
-
${listen('mousedown', (event) => {
|
|
91
|
-
/**
|
|
92
|
-
* Prevent this mousedown event from propagating to the window, which would
|
|
93
|
-
* then trigger the dropdown to close.
|
|
94
|
-
*/
|
|
95
|
-
event.stopPropagation();
|
|
96
|
-
})}
|
|
97
|
-
${listen('mouseup', (event) => {
|
|
98
|
-
/**
|
|
99
|
-
* Prevent this event from propagating to the window, which would then
|
|
100
|
-
* trigger the dropdown to close.
|
|
101
|
-
*/
|
|
102
|
-
event.stopPropagation();
|
|
103
|
-
if (!option.disabled) {
|
|
104
|
-
dispatch(new events.selectionChange(option));
|
|
105
|
-
}
|
|
106
|
-
})}
|
|
107
|
-
>
|
|
108
|
-
${innerTemplate}
|
|
109
|
-
</div>
|
|
110
|
-
`;
|
|
111
|
-
});
|
|
112
|
-
return html `
|
|
113
|
-
<slot>${optionTemplates}</slot>
|
|
114
|
-
`;
|
|
115
|
-
},
|
|
116
|
-
});
|
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
import { assert } from '@augment-vir/assert';
|
|
2
|
-
import { NavController } from 'device-navigation';
|
|
3
|
-
import { classMap, css, defineElementEvent, html, ifDefined, listen, nothing, renderIf, testId, } from 'element-vir';
|
|
4
|
-
import { ChevronUp24Icon } from '../../icons/index.js';
|
|
5
|
-
import { viraBorders } from '../../styles/border.js';
|
|
6
|
-
import { createFocusStyles, viraFocusCssVars } from '../../styles/focus.js';
|
|
7
|
-
import { viraFormCssVars } from '../../styles/form-themes.js';
|
|
8
|
-
import { noNativeFormStyles, noUserSelect, viraAnimationDurations, viraDisabledStyles, } from '../../styles/index.js';
|
|
9
|
-
import { viraShadows } from '../../styles/shadows.js';
|
|
10
|
-
import { HidePopUpEvent, NavSelectEvent, PopUpManager, } from '../../util/pop-up-manager.js';
|
|
11
|
-
import { defineViraElement } from '../define-vira-element.js';
|
|
12
|
-
import { ViraIcon } from '../vira-icon.element.js';
|
|
13
|
-
import { assertUniqueIdProps, createNewSelection, filterToSelectedOptions, triggerPopUpState, } from './dropdown-helpers.js';
|
|
14
|
-
import { ViraDropdownOptions } from './vira-dropdown-options.element.js';
|
|
15
|
-
/**
|
|
16
|
-
* Test ids for {@link ViraDropdown}.
|
|
17
|
-
*
|
|
18
|
-
* @category Internal
|
|
19
|
-
*/
|
|
20
|
-
export const viraDropdownTestIds = {
|
|
21
|
-
trigger: 'dropdown-trigger',
|
|
22
|
-
icon: 'dropdown-icon',
|
|
23
|
-
prefix: 'dropdown-prefix',
|
|
24
|
-
options: 'dropdown-options',
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* The main dropdown element that should be use directly.
|
|
28
|
-
*
|
|
29
|
-
* @category Dropdown
|
|
30
|
-
* @category Elements
|
|
31
|
-
* @see https://electrovir.github.io/element-vir/vira/book/elements/dropdown/vira-dropdown
|
|
32
|
-
*/
|
|
33
|
-
export const ViraDropdown = defineViraElement()({
|
|
34
|
-
tagName: 'vira-dropdown',
|
|
35
|
-
state({ host }) {
|
|
36
|
-
return {
|
|
37
|
-
/** `undefined` means the pop up is not currently showing. */
|
|
38
|
-
showPopUpResult: undefined,
|
|
39
|
-
popUpManager: new PopUpManager(new NavController(host)),
|
|
40
|
-
};
|
|
41
|
-
},
|
|
42
|
-
hostClasses: {
|
|
43
|
-
'vira-dropdown-disabled': ({ inputs }) => !!inputs.isDisabled,
|
|
44
|
-
},
|
|
45
|
-
styles: ({ hostClasses }) => css `
|
|
46
|
-
:host {
|
|
47
|
-
display: inline-flex;
|
|
48
|
-
vertical-align: middle;
|
|
49
|
-
width: 256px;
|
|
50
|
-
${viraFocusCssVars['vira-focus-outline-color'].name}: ${viraFormCssVars['vira-form-focus-color'].value};
|
|
51
|
-
position: relative;
|
|
52
|
-
max-width: 100%;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.dropdown-wrapper {
|
|
56
|
-
${noNativeFormStyles};
|
|
57
|
-
max-width: 100%;
|
|
58
|
-
align-self: stretch;
|
|
59
|
-
flex-grow: 1;
|
|
60
|
-
position: relative;
|
|
61
|
-
border-radius: ${viraBorders['vira-form-input-radius'].value};
|
|
62
|
-
transition: border-radius
|
|
63
|
-
${viraAnimationDurations['vira-interaction-animation-duration'].value};
|
|
64
|
-
outline: none;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
${createFocusStyles({
|
|
68
|
-
selector: '.dropdown-wrapper:focus',
|
|
69
|
-
elementBorderSize: 1,
|
|
70
|
-
})}
|
|
71
|
-
|
|
72
|
-
.selection-display {
|
|
73
|
-
overflow: hidden;
|
|
74
|
-
text-overflow: ellipsis;
|
|
75
|
-
white-space: nowrap;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.trigger-icon {
|
|
79
|
-
transform: rotate(180deg);
|
|
80
|
-
transition: ${viraAnimationDurations['vira-interaction-animation-duration'].value}
|
|
81
|
-
linear transform;
|
|
82
|
-
align-self: flex-start;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.trigger-icon-wrapper {
|
|
86
|
-
flex-grow: 1;
|
|
87
|
-
display: flex;
|
|
88
|
-
justify-content: flex-end;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.dropdown-wrapper.open .trigger-icon {
|
|
92
|
-
transform: rotate(0);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.dropdown-wrapper.open:not(.open-upwards) {
|
|
96
|
-
border-bottom-left-radius: 0;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.open-upwards.dropdown-wrapper.open {
|
|
100
|
-
border-top-left-radius: 0;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.dropdown-trigger {
|
|
104
|
-
border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
|
|
105
|
-
height: 100%;
|
|
106
|
-
width: 100%;
|
|
107
|
-
transition: inherit;
|
|
108
|
-
box-sizing: border-box;
|
|
109
|
-
display: flex;
|
|
110
|
-
gap: 8px;
|
|
111
|
-
text-align: left;
|
|
112
|
-
align-items: center;
|
|
113
|
-
padding: 3px;
|
|
114
|
-
padding-left: 10px;
|
|
115
|
-
${noUserSelect};
|
|
116
|
-
border-radius: inherit;
|
|
117
|
-
background-color: ${viraFormCssVars['vira-form-background-color'].value};
|
|
118
|
-
color: ${viraFormCssVars['vira-form-foreground-color'].value};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.open-upwards ${ViraDropdownOptions} {
|
|
122
|
-
border-bottom-left-radius: 0;
|
|
123
|
-
border-bottom-right-radius: 0;
|
|
124
|
-
${viraShadows.menuShadowReversed}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
${hostClasses['vira-dropdown-disabled'].selector} {
|
|
128
|
-
${viraDisabledStyles}
|
|
129
|
-
pointer-events: auto;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
${hostClasses['vira-dropdown-disabled'].selector} .dropdown-wrapper {
|
|
133
|
-
pointer-events: none;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.pop-up-positioner {
|
|
137
|
-
position: absolute;
|
|
138
|
-
pointer-events: none;
|
|
139
|
-
display: flex;
|
|
140
|
-
flex-direction: column;
|
|
141
|
-
|
|
142
|
-
/* highest possible z-index */
|
|
143
|
-
z-index: 2147483647;
|
|
144
|
-
/* space for the caret icon */
|
|
145
|
-
right: 28px;
|
|
146
|
-
/* minus the border width */
|
|
147
|
-
top: calc(100% - 1px);
|
|
148
|
-
left: 0;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.using-placeholder {
|
|
152
|
-
opacity: 0.4;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.open-upwards .pop-up-positioner {
|
|
156
|
-
flex-direction: column-reverse;
|
|
157
|
-
/* minus the border width */
|
|
158
|
-
bottom: calc(100% - 1px);
|
|
159
|
-
}
|
|
160
|
-
`,
|
|
161
|
-
events: {
|
|
162
|
-
selectedChange: defineElementEvent(),
|
|
163
|
-
openChange: defineElementEvent(),
|
|
164
|
-
},
|
|
165
|
-
cleanup({ state, updateState }) {
|
|
166
|
-
updateState({ showPopUpResult: undefined });
|
|
167
|
-
state.popUpManager.destroy();
|
|
168
|
-
},
|
|
169
|
-
init({ state, updateState, host, inputs, dispatch, events }) {
|
|
170
|
-
state.popUpManager.listen(HidePopUpEvent, () => {
|
|
171
|
-
updateState({ showPopUpResult: undefined });
|
|
172
|
-
if (!inputs.isDisabled) {
|
|
173
|
-
const dropdownWrapper = host.shadowRoot.querySelector('.dropdown-wrapper');
|
|
174
|
-
assert.instanceOf(dropdownWrapper, HTMLButtonElement, 'failed to find dropdown wrapper child');
|
|
175
|
-
dropdownWrapper.focus();
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
state.popUpManager.listen(NavSelectEvent, (event) => {
|
|
179
|
-
const optionIndex = event.detail.x;
|
|
180
|
-
const option = inputs.options[optionIndex];
|
|
181
|
-
if (!option) {
|
|
182
|
-
throw new Error(`Found no dropdown option at index '${optionIndex}'`);
|
|
183
|
-
}
|
|
184
|
-
/** Only close upon option selection if the dropdown is not multi select. */
|
|
185
|
-
if (!inputs.isMultiSelect) {
|
|
186
|
-
triggerPopUpState({ emitEvent: true, open: false }, {
|
|
187
|
-
dispatch: (openState) => {
|
|
188
|
-
dispatch(new events.openChange(openState));
|
|
189
|
-
},
|
|
190
|
-
host,
|
|
191
|
-
popUpManager: state.popUpManager,
|
|
192
|
-
updateState,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
dispatch(new events.selectedChange(createNewSelection(option.id, inputs.selected, !!inputs.isMultiSelect)));
|
|
196
|
-
});
|
|
197
|
-
},
|
|
198
|
-
render({ dispatch, events, state, inputs, updateState, host }) {
|
|
199
|
-
assertUniqueIdProps(inputs.options);
|
|
200
|
-
function triggerPopUp(param) {
|
|
201
|
-
triggerPopUpState(param, {
|
|
202
|
-
dispatch: (openState) => {
|
|
203
|
-
dispatch(new events.openChange(openState));
|
|
204
|
-
},
|
|
205
|
-
host,
|
|
206
|
-
popUpManager: state.popUpManager,
|
|
207
|
-
updateState,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
if (inputs.isDisabled) {
|
|
211
|
-
triggerPopUp({ open: false, emitEvent: false });
|
|
212
|
-
}
|
|
213
|
-
else if (inputs.z_debug_forceOpenState != undefined) {
|
|
214
|
-
if (!inputs.z_debug_forceOpenState && state.showPopUpResult) {
|
|
215
|
-
triggerPopUp({ emitEvent: false, open: false });
|
|
216
|
-
}
|
|
217
|
-
else if (inputs.z_debug_forceOpenState && !state.showPopUpResult) {
|
|
218
|
-
triggerPopUp({ emitEvent: false, open: true });
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
const selectedOptions = filterToSelectedOptions(inputs);
|
|
222
|
-
const leadingIconTemplate = inputs.icon
|
|
223
|
-
? html `
|
|
224
|
-
<${ViraIcon.assign({
|
|
225
|
-
icon: inputs.icon,
|
|
226
|
-
})}
|
|
227
|
-
${testId(viraDropdownTestIds.icon)}
|
|
228
|
-
></${ViraIcon}>
|
|
229
|
-
`
|
|
230
|
-
: nothing;
|
|
231
|
-
const positionerStyles = state.showPopUpResult
|
|
232
|
-
? state.showPopUpResult.popDown
|
|
233
|
-
? /** Dropdown going down position. */
|
|
234
|
-
css `
|
|
235
|
-
bottom: -${state.showPopUpResult.positions.diff.bottom}px;
|
|
236
|
-
`
|
|
237
|
-
: /** Dropdown going up position. */
|
|
238
|
-
css `
|
|
239
|
-
top: -${state.showPopUpResult.positions.diff.top}px;
|
|
240
|
-
`
|
|
241
|
-
: undefined;
|
|
242
|
-
function respondToClick() {
|
|
243
|
-
triggerPopUp({ emitEvent: true, open: !state.showPopUpResult });
|
|
244
|
-
}
|
|
245
|
-
const shouldUsePlaceholder = !selectedOptions.length;
|
|
246
|
-
const prefixTemplate = inputs.selectionPrefix && !shouldUsePlaceholder
|
|
247
|
-
? html `
|
|
248
|
-
<span class="selected-label-prefix" ${testId(viraDropdownTestIds.prefix)}>
|
|
249
|
-
${inputs.selectionPrefix}
|
|
250
|
-
</span>
|
|
251
|
-
`
|
|
252
|
-
: nothing;
|
|
253
|
-
const selectionDisplay = shouldUsePlaceholder
|
|
254
|
-
? inputs.placeholder || ''
|
|
255
|
-
: selectedOptions.map((item) => item.label).join(', ');
|
|
256
|
-
return html `
|
|
257
|
-
<button
|
|
258
|
-
?disabled=${!!inputs.isDisabled}
|
|
259
|
-
class="dropdown-wrapper ${classMap({
|
|
260
|
-
open: !!state.showPopUpResult,
|
|
261
|
-
'open-upwards': !state.showPopUpResult?.popDown,
|
|
262
|
-
})}"
|
|
263
|
-
${testId(viraDropdownTestIds.trigger)}
|
|
264
|
-
role="listbox"
|
|
265
|
-
aria-expanded=${!!state.showPopUpResult}
|
|
266
|
-
${listen('keydown', (event) => {
|
|
267
|
-
if (!state.showPopUpResult && event.code.startsWith('Arrow')) {
|
|
268
|
-
triggerPopUp({ emitEvent: true, open: true });
|
|
269
|
-
}
|
|
270
|
-
})}
|
|
271
|
-
${listen('click', (event) => {
|
|
272
|
-
/** Detail is 0 if it was a keyboard key (like Enter) that triggered this click. */
|
|
273
|
-
if (event.detail === 0) {
|
|
274
|
-
respondToClick();
|
|
275
|
-
}
|
|
276
|
-
})}
|
|
277
|
-
${listen('mousedown', (event) => {
|
|
278
|
-
/** Ignore any clicks that aren't the main button. */
|
|
279
|
-
if (event.button === 0) {
|
|
280
|
-
respondToClick();
|
|
281
|
-
}
|
|
282
|
-
})}
|
|
283
|
-
>
|
|
284
|
-
<div class="dropdown-trigger">
|
|
285
|
-
${leadingIconTemplate}
|
|
286
|
-
<span
|
|
287
|
-
class="selection-display ${classMap({
|
|
288
|
-
'using-placeholder': shouldUsePlaceholder,
|
|
289
|
-
})}"
|
|
290
|
-
title=${ifDefined(shouldUsePlaceholder ? selectionDisplay : undefined)}
|
|
291
|
-
>
|
|
292
|
-
${prefixTemplate} ${selectionDisplay}
|
|
293
|
-
</span>
|
|
294
|
-
<span class="trigger-icon-wrapper">
|
|
295
|
-
<${ViraIcon.assign({ icon: ChevronUp24Icon })}
|
|
296
|
-
class="trigger-icon"
|
|
297
|
-
></${ViraIcon}>
|
|
298
|
-
</span>
|
|
299
|
-
</div>
|
|
300
|
-
<div class="pop-up-positioner" style=${positionerStyles}>
|
|
301
|
-
${renderIf(!!state.showPopUpResult, html `
|
|
302
|
-
<${ViraDropdownOptions.assign({
|
|
303
|
-
options: inputs.options,
|
|
304
|
-
selectedOptions,
|
|
305
|
-
navController: state.popUpManager.navController,
|
|
306
|
-
})}
|
|
307
|
-
${listen(ViraDropdownOptions.events.selectionChange, (event) => {
|
|
308
|
-
/**
|
|
309
|
-
* Only close upon option selection if the dropdown is not multi
|
|
310
|
-
* select.
|
|
311
|
-
*/
|
|
312
|
-
if (!inputs.isMultiSelect) {
|
|
313
|
-
triggerPopUp({ emitEvent: true, open: false });
|
|
314
|
-
}
|
|
315
|
-
dispatch(new events.selectedChange(createNewSelection(event.detail.id, inputs.selected, !!inputs.isMultiSelect)));
|
|
316
|
-
})}
|
|
317
|
-
${testId(viraDropdownTestIds.options)}
|
|
318
|
-
></${ViraDropdownOptions}>
|
|
319
|
-
`)}
|
|
320
|
-
</div>
|
|
321
|
-
</button>
|
|
322
|
-
`;
|
|
323
|
-
},
|
|
324
|
-
});
|