vira 32.4.0 → 33.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/directives/index.d.ts +2 -0
- package/dist/directives/index.js +2 -0
- package/dist/directives/popover.directive.d.ts +29 -0
- package/dist/directives/popover.directive.js +45 -0
- package/dist/directives/tooltip.directive.d.ts +60 -0
- package/dist/directives/tooltip.directive.js +99 -0
- package/dist/elements/color/vira-color-picker.element.d.ts +1 -1
- package/dist/elements/color/vira-color-picker.element.js +17 -15
- package/dist/elements/index.d.ts +5 -5
- package/dist/elements/index.js +5 -5
- package/dist/elements/{pop-up → popover}/vira-menu-item.element.d.ts +4 -4
- package/dist/elements/{pop-up → popover}/vira-menu-item.element.js +12 -3
- package/dist/elements/popover/vira-menu-trigger.element.d.ts +56 -0
- package/dist/elements/{pop-up → popover}/vira-menu-trigger.element.js +19 -30
- package/dist/elements/popover/vira-menu.element.d.ts +35 -0
- package/dist/elements/popover/vira-menu.element.js +262 -0
- package/dist/elements/popover/vira-popover-trigger.element.d.ts +50 -0
- package/dist/elements/popover/vira-popover-trigger.element.js +307 -0
- package/dist/elements/popover/vira-tooltip.element.d.ts +10 -0
- package/dist/elements/popover/vira-tooltip.element.js +176 -0
- package/dist/elements/vira-drawer.element.js +1 -1
- package/dist/elements/vira-dropdown.element.d.ts +40 -13
- package/dist/elements/vira-dropdown.element.js +375 -69
- package/dist/elements/vira-form.element.js +10 -16
- package/dist/elements/vira-json-form.element.js +40 -36
- package/dist/elements/vira-modal.element.js +1 -1
- package/dist/elements/vira-tabs.element.d.ts +3 -9
- package/dist/elements/vira-tabs.element.js +5 -6
- package/dist/elements/vira-theme-switcher.element.js +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/util/anchored-popover.d.ts +40 -0
- package/dist/util/anchored-popover.js +70 -0
- package/dist/util/fuzzy-match.d.ts +16 -0
- package/dist/util/fuzzy-match.js +24 -0
- package/dist/util/index.d.ts +5 -3
- package/dist/util/index.js +5 -3
- package/dist/util/{pop-up-helpers.d.ts → menu-helpers.d.ts} +8 -19
- package/dist/util/{pop-up-helpers.js → menu-helpers.js} +12 -19
- package/dist/util/popover-manager.d.ts +123 -0
- package/dist/util/popover-manager.js +414 -0
- package/dist/util/vira-dropdown-option.d.ts +30 -0
- package/dist/util/vira-dropdown-option.js +8 -0
- package/dist/util/vira-form-fields.d.ts +2 -2
- package/dist/util/vira-theme-client.d.ts +1 -1
- package/dist/util/vira-theme-client.js +3 -3
- package/package.json +2 -1
- package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +0 -45
- package/dist/elements/pop-up/vira-menu.element.d.ts +0 -36
- package/dist/elements/pop-up/vira-menu.element.js +0 -88
- package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +0 -109
- package/dist/elements/pop-up/vira-pop-up-trigger.element.js +0 -408
- package/dist/elements/vira-select.element.d.ts +0 -44
- package/dist/elements/vira-select.element.js +0 -418
- package/dist/util/pop-up-manager.d.ts +0 -200
- package/dist/util/pop-up-manager.js +0 -258
- package/dist/util/vira-select-option.d.ts +0 -31
- package/dist/util/vira-select-option.js +0 -8
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
-
import { type AttributeValues, type HtmlInterpolation } from 'element-vir';
|
|
3
|
-
import { type ViraIconSvg } from '../icons/index.js';
|
|
4
|
-
import { type ViraSelectOption, type ViraSelectOptionGroup } from '../util/vira-select-option.js';
|
|
5
|
-
/**
|
|
6
|
-
* Similar to {@link ViraDropdown} but is, instead, simply a wrapper for `<select>` and nothing more.
|
|
7
|
-
*
|
|
8
|
-
* @category Dropdown
|
|
9
|
-
* @category Elements
|
|
10
|
-
* @see https://electrovir.github.io/vira/book/elements/vira-select
|
|
11
|
-
*/
|
|
12
|
-
export declare const ViraSelect: import("element-vir").DeclarativeElementDefinition<"vira-select", {
|
|
13
|
-
options: ReadonlyArray<Readonly<ViraSelectOption> | Readonly<ViraSelectOptionGroup>>;
|
|
14
|
-
/** The currently selected option value. */
|
|
15
|
-
value: undefined | string;
|
|
16
|
-
} & PartialWithUndefined<{
|
|
17
|
-
icon: Readonly<ViraIconSvg>;
|
|
18
|
-
placeholder: string;
|
|
19
|
-
label: string | HtmlInterpolation;
|
|
20
|
-
/** If set to `true`, only minimal styles are applied. */
|
|
21
|
-
rawSelect: boolean;
|
|
22
|
-
disabled: boolean;
|
|
23
|
-
/**
|
|
24
|
-
* When `true`, the currently selected option's label is rendered as plain text with no
|
|
25
|
-
* wrapper, border, or focus styles.
|
|
26
|
-
*/
|
|
27
|
-
isReadonly: boolean;
|
|
28
|
-
attributePassthrough: Readonly<PartialWithUndefined<{
|
|
29
|
-
label: AttributeValues;
|
|
30
|
-
select: AttributeValues;
|
|
31
|
-
option: AttributeValues;
|
|
32
|
-
}>>;
|
|
33
|
-
hasError: boolean;
|
|
34
|
-
}>, {
|
|
35
|
-
/**
|
|
36
|
-
* Used to couple the label and select together. This is not applied if no label is
|
|
37
|
-
* provided.
|
|
38
|
-
*/
|
|
39
|
-
randomId: string;
|
|
40
|
-
/** Removes event listeners registered during init. */
|
|
41
|
-
cleanupListeners: undefined | (() => void);
|
|
42
|
-
}, {
|
|
43
|
-
valueChange: import("element-vir").DefineElementEvent<string>;
|
|
44
|
-
}, "vira-select-disabled" | "vira-select-error" | "vira-select-has-label" | "vira-select-not-raw" | "vira-select-readonly", "vira-select-padding-horizontal" | "vira-select-padding-vertical" | "vira-select-icon-padding", readonly [], readonly []>;
|
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
import { assertWrap, check } from '@augment-vir/assert';
|
|
2
|
-
import { randomString } from '@augment-vir/common';
|
|
3
|
-
import { extractEventTarget } from '@augment-vir/web';
|
|
4
|
-
import { attributes, classMap, css, defineElementEvent, html, ifDefined, listen, nothing, } from 'element-vir';
|
|
5
|
-
import { listenTo } from 'typed-event-target';
|
|
6
|
-
import { ChevronUp16Icon } from '../icons/index.js';
|
|
7
|
-
import { viraDisabledStyles } from '../styles/disabled.js';
|
|
8
|
-
import { createFocusStyles } from '../styles/focus.js';
|
|
9
|
-
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
10
|
-
import { viraAnimationDurations } from '../styles/index.js';
|
|
11
|
-
import { noNativeFormStyles } from '../styles/native-styles.js';
|
|
12
|
-
import { defineViraElement } from '../util/define-vira-element.js';
|
|
13
|
-
import { isViraSelectOptionGroup, } from '../util/vira-select-option.js';
|
|
14
|
-
import { ViraIcon } from './vira-icon.element.js';
|
|
15
|
-
function renderSelectOption(option, value) {
|
|
16
|
-
return html `
|
|
17
|
-
<option
|
|
18
|
-
?selected=${option.value === value}
|
|
19
|
-
aria-label=${option.label}
|
|
20
|
-
?disabled=${option.disabled}
|
|
21
|
-
value=${option.value}
|
|
22
|
-
>
|
|
23
|
-
${option.label}
|
|
24
|
-
</option>
|
|
25
|
-
`;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Similar to {@link ViraDropdown} but is, instead, simply a wrapper for `<select>` and nothing more.
|
|
29
|
-
*
|
|
30
|
-
* @category Dropdown
|
|
31
|
-
* @category Elements
|
|
32
|
-
* @see https://electrovir.github.io/vira/book/elements/vira-select
|
|
33
|
-
*/
|
|
34
|
-
export const ViraSelect = defineViraElement()({
|
|
35
|
-
tagName: 'vira-select',
|
|
36
|
-
state() {
|
|
37
|
-
return {
|
|
38
|
-
/**
|
|
39
|
-
* Used to couple the label and select together. This is not applied if no label is
|
|
40
|
-
* provided.
|
|
41
|
-
*/
|
|
42
|
-
randomId: randomString(32),
|
|
43
|
-
/** Removes event listeners registered during init. */
|
|
44
|
-
cleanupListeners: undefined,
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
events: {
|
|
48
|
-
valueChange: defineElementEvent(),
|
|
49
|
-
},
|
|
50
|
-
cssVars: {
|
|
51
|
-
'vira-select-padding-horizontal': '10px',
|
|
52
|
-
'vira-select-padding-vertical': '3px',
|
|
53
|
-
'vira-select-icon-padding': '40px',
|
|
54
|
-
},
|
|
55
|
-
hostClasses: {
|
|
56
|
-
'vira-select-disabled'({ inputs }) {
|
|
57
|
-
return !!inputs.disabled;
|
|
58
|
-
},
|
|
59
|
-
'vira-select-error'({ inputs }) {
|
|
60
|
-
return !!inputs.hasError;
|
|
61
|
-
},
|
|
62
|
-
'vira-select-has-label'({ inputs }) {
|
|
63
|
-
return !!inputs.label;
|
|
64
|
-
},
|
|
65
|
-
'vira-select-not-raw'({ inputs }) {
|
|
66
|
-
return !inputs.rawSelect;
|
|
67
|
-
},
|
|
68
|
-
'vira-select-readonly'({ inputs }) {
|
|
69
|
-
return !!inputs.isReadonly;
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
styles({ hostClasses, cssVars }) {
|
|
73
|
-
return css `
|
|
74
|
-
:host {
|
|
75
|
-
position: relative;
|
|
76
|
-
display: inline-flex;
|
|
77
|
-
width: 223px;
|
|
78
|
-
height: 28px;
|
|
79
|
-
box-sizing: border-box;
|
|
80
|
-
color: ${viraFormCssVars['vira-form-foreground-color'].value};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
${hostClasses['vira-select-has-label'].selector} {
|
|
84
|
-
height: auto;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/*
|
|
88
|
-
Readonly renders plain text with no select chrome, so the input height would leave
|
|
89
|
-
the text sitting above the middle of an over-tall box. That mis-aligns it against a
|
|
90
|
-
sibling label and makes readonly select rows taller than readonly text rows.
|
|
91
|
-
*/
|
|
92
|
-
${hostClasses['vira-select-readonly'].selector} {
|
|
93
|
-
height: auto;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.select-wrapper {
|
|
97
|
-
${noNativeFormStyles};
|
|
98
|
-
height: inherit;
|
|
99
|
-
max-width: 100%;
|
|
100
|
-
flex-grow: 1;
|
|
101
|
-
display: inline-flex;
|
|
102
|
-
box-sizing: border-box;
|
|
103
|
-
align-items: center;
|
|
104
|
-
position: relative;
|
|
105
|
-
cursor: pointer;
|
|
106
|
-
|
|
107
|
-
& select {
|
|
108
|
-
appearance: none;
|
|
109
|
-
-webkit-appearance: none;
|
|
110
|
-
-moz-appearance: none;
|
|
111
|
-
color: inherit;
|
|
112
|
-
font: inherit;
|
|
113
|
-
outline: none;
|
|
114
|
-
width: 100%;
|
|
115
|
-
border: none;
|
|
116
|
-
background: none;
|
|
117
|
-
border-radius: inherit;
|
|
118
|
-
cursor: pointer;
|
|
119
|
-
height: 100%;
|
|
120
|
-
box-sizing: border-box;
|
|
121
|
-
/* Prevent the left pixel of text getting cut off. */
|
|
122
|
-
padding-left: 0.5px;
|
|
123
|
-
padding-right: 24px;
|
|
124
|
-
overflow: hidden;
|
|
125
|
-
text-overflow: ellipsis;
|
|
126
|
-
|
|
127
|
-
&.placeholder {
|
|
128
|
-
color: ${viraFormCssVars['vira-form-placeholder-color'].value};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
&.with-icon {
|
|
132
|
-
padding-left: ${cssVars['vira-select-icon-padding'].value};
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
& ${ViraIcon} {
|
|
137
|
-
position: absolute;
|
|
138
|
-
pointer-events: none;
|
|
139
|
-
|
|
140
|
-
&.trigger-icon {
|
|
141
|
-
transform: rotate(180deg);
|
|
142
|
-
right: 3px;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
&.input-icon {
|
|
146
|
-
left: 10px;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.trigger-icon {
|
|
152
|
-
width: 20px;
|
|
153
|
-
aspect-ratio: 1;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
${hostClasses['vira-select-not-raw'].selector} {
|
|
157
|
-
.select-wrapper {
|
|
158
|
-
border-radius: ${viraFormCssVars['vira-form-radius'].value};
|
|
159
|
-
color: ${viraFormCssVars['vira-form-foreground-color'].value};
|
|
160
|
-
background-color: ${viraFormCssVars['vira-form-background-color'].value};
|
|
161
|
-
/*
|
|
162
|
-
Border colors are actually applied via the .wrapper-border class. However, we must
|
|
163
|
-
apply a border here still so that it takes up space.
|
|
164
|
-
*/
|
|
165
|
-
border: 1px solid transparent;
|
|
166
|
-
cursor: pointer;
|
|
167
|
-
|
|
168
|
-
& select {
|
|
169
|
-
padding: ${cssVars['vira-select-padding-vertical'].value} 27px
|
|
170
|
-
${cssVars['vira-select-padding-vertical'].value}
|
|
171
|
-
${cssVars['vira-select-padding-horizontal'].value};
|
|
172
|
-
|
|
173
|
-
&:focus:focus-visible:not([aria-disabled='true']) ~ .focus-border {
|
|
174
|
-
${createFocusStyles({
|
|
175
|
-
elementBorderSize: '1px',
|
|
176
|
-
noNesting: true,
|
|
177
|
-
})}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
& .border-style {
|
|
182
|
-
position: absolute;
|
|
183
|
-
top: 0;
|
|
184
|
-
left: 0;
|
|
185
|
-
width: 100%;
|
|
186
|
-
height: 100%;
|
|
187
|
-
border-radius: ${viraFormCssVars['vira-form-radius'].value};
|
|
188
|
-
z-index: 0;
|
|
189
|
-
pointer-events: none;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
& .wrapper-border {
|
|
193
|
-
top: -1px;
|
|
194
|
-
left: -1px;
|
|
195
|
-
border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
|
|
196
|
-
transition: border
|
|
197
|
-
${viraAnimationDurations['vira-interaction-animation-duration'].value};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
label {
|
|
203
|
-
display: flex;
|
|
204
|
-
flex-direction: column;
|
|
205
|
-
justify-content: flex-start;
|
|
206
|
-
gap: 2px;
|
|
207
|
-
width: 100%;
|
|
208
|
-
max-width: 100%;
|
|
209
|
-
|
|
210
|
-
& .select-label {
|
|
211
|
-
font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
|
|
212
|
-
text-align: left;
|
|
213
|
-
flex-shrink: 0;
|
|
214
|
-
flex-wrap: wrap;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
& .select-wrapper {
|
|
218
|
-
height: 32px;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.readonly-value {
|
|
223
|
-
overflow-wrap: anywhere;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
${hostClasses['vira-select-disabled'].selector} {
|
|
227
|
-
cursor: not-allowed;
|
|
228
|
-
|
|
229
|
-
& select,
|
|
230
|
-
& .wrapper-border {
|
|
231
|
-
${viraDisabledStyles}
|
|
232
|
-
}
|
|
233
|
-
${ViraIcon} {
|
|
234
|
-
${viraDisabledStyles}
|
|
235
|
-
}
|
|
236
|
-
& * {
|
|
237
|
-
cursor: not-allowed;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
:host(
|
|
242
|
-
.${hostClasses['vira-select-not-raw'].name}.${hostClasses['vira-select-error']
|
|
243
|
-
.name}
|
|
244
|
-
)
|
|
245
|
-
.wrapper-border {
|
|
246
|
-
border-color: ${viraFormCssVars['vira-form-error-color'].value};
|
|
247
|
-
}
|
|
248
|
-
`;
|
|
249
|
-
},
|
|
250
|
-
init({ state, updateState, host }) {
|
|
251
|
-
state.cleanupListeners?.();
|
|
252
|
-
function getSelectElement() {
|
|
253
|
-
return assertWrap.instanceOf(host.shadowRoot.querySelector('select'), HTMLSelectElement);
|
|
254
|
-
}
|
|
255
|
-
const listenerRemovers = [
|
|
256
|
-
listenTo(host, 'mousedown', (event) => {
|
|
257
|
-
const selectElement = getSelectElement();
|
|
258
|
-
if (event.composedPath().includes(selectElement)) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
event.preventDefault();
|
|
262
|
-
event.stopPropagation();
|
|
263
|
-
/** `showPicker` is not in Safari. */
|
|
264
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
265
|
-
if (selectElement.showPicker) {
|
|
266
|
-
try {
|
|
267
|
-
selectElement.showPicker();
|
|
268
|
-
}
|
|
269
|
-
catch {
|
|
270
|
-
/**
|
|
271
|
-
* Chromium throws `NotAllowedError` when `showPicker` runs without
|
|
272
|
-
* transient user activation; the picker just won't open.
|
|
273
|
-
*/
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}),
|
|
277
|
-
listenTo(host, 'click', (event) => {
|
|
278
|
-
const selectElement = getSelectElement();
|
|
279
|
-
if (event.composedPath().includes(selectElement)) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
event.preventDefault();
|
|
283
|
-
event.stopPropagation();
|
|
284
|
-
/** `showPicker` is not in Safari. */
|
|
285
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
286
|
-
if (selectElement.showPicker) {
|
|
287
|
-
try {
|
|
288
|
-
selectElement.showPicker();
|
|
289
|
-
}
|
|
290
|
-
catch {
|
|
291
|
-
/**
|
|
292
|
-
* Chromium throws `NotAllowedError` when `showPicker` runs without
|
|
293
|
-
* transient user activation; the picker just won't open.
|
|
294
|
-
*/
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}),
|
|
298
|
-
];
|
|
299
|
-
updateState({
|
|
300
|
-
cleanupListeners() {
|
|
301
|
-
listenerRemovers.forEach((remover) => remover());
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
},
|
|
305
|
-
cleanup({ state, updateState }) {
|
|
306
|
-
state.cleanupListeners?.();
|
|
307
|
-
updateState({
|
|
308
|
-
cleanupListeners: undefined,
|
|
309
|
-
});
|
|
310
|
-
},
|
|
311
|
-
render({ inputs, state, dispatch, events }) {
|
|
312
|
-
const value = inputs.value || undefined;
|
|
313
|
-
if (inputs.isReadonly) {
|
|
314
|
-
const selectedOption = inputs.options
|
|
315
|
-
.flatMap((entry) => (isViraSelectOptionGroup(entry) ? [...entry.options] : [entry]))
|
|
316
|
-
.find((option) => option.value === value);
|
|
317
|
-
const readonlyValueTemplate = html `
|
|
318
|
-
<span class="readonly-value">
|
|
319
|
-
${selectedOption?.label || inputs.placeholder || ''}
|
|
320
|
-
</span>
|
|
321
|
-
`;
|
|
322
|
-
if (inputs.label) {
|
|
323
|
-
return html `
|
|
324
|
-
<label ${attributes(inputs.attributePassthrough?.label)}>
|
|
325
|
-
<span class="select-label">${inputs.label}</span>
|
|
326
|
-
${readonlyValueTemplate}
|
|
327
|
-
</label>
|
|
328
|
-
`;
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
return readonlyValueTemplate;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
const placeholderOptionTemplate = inputs.placeholder || value == undefined
|
|
335
|
-
? html `
|
|
336
|
-
<option value="" disabled ?selected=${value == undefined}>
|
|
337
|
-
${inputs.placeholder}
|
|
338
|
-
</option>
|
|
339
|
-
`
|
|
340
|
-
: nothing;
|
|
341
|
-
const selectTemplate = html `
|
|
342
|
-
<span class="select-wrapper">
|
|
343
|
-
<select
|
|
344
|
-
.value=${ifDefined(value)}
|
|
345
|
-
class=${classMap({
|
|
346
|
-
placeholder: !value && !!inputs.placeholder,
|
|
347
|
-
'with-icon': !!inputs.icon,
|
|
348
|
-
})}
|
|
349
|
-
tabindex=${inputs.disabled ? -1 : 0}
|
|
350
|
-
id=${ifDefined(inputs.label ? state.randomId : undefined)}
|
|
351
|
-
aria-label=${ifDefined((check.isString(inputs.label) && inputs.label) || undefined)}
|
|
352
|
-
aria-disabled=${ifDefined(inputs.disabled ? 'true' : undefined)}
|
|
353
|
-
${listen('input', (event) => {
|
|
354
|
-
const selectElement = extractEventTarget(event, HTMLSelectElement);
|
|
355
|
-
const newValue = selectElement.value;
|
|
356
|
-
if (selectElement.value !== value) {
|
|
357
|
-
selectElement.selectedIndex = inputs.options
|
|
358
|
-
.flatMap((entry) => {
|
|
359
|
-
return isViraSelectOptionGroup(entry)
|
|
360
|
-
? [...entry.options]
|
|
361
|
-
: [entry];
|
|
362
|
-
})
|
|
363
|
-
.findIndex((option) => option.value === value);
|
|
364
|
-
}
|
|
365
|
-
dispatch(new events.valueChange({
|
|
366
|
-
detail: newValue,
|
|
367
|
-
}));
|
|
368
|
-
})}
|
|
369
|
-
${attributes(inputs.attributePassthrough?.select)}
|
|
370
|
-
>
|
|
371
|
-
${placeholderOptionTemplate}
|
|
372
|
-
${inputs.options.map((entry) => {
|
|
373
|
-
if (isViraSelectOptionGroup(entry)) {
|
|
374
|
-
return html `
|
|
375
|
-
<optgroup label=${entry.groupName}>
|
|
376
|
-
${entry.options.map((option) => {
|
|
377
|
-
return renderSelectOption(option, value);
|
|
378
|
-
})}
|
|
379
|
-
</optgroup>
|
|
380
|
-
`;
|
|
381
|
-
}
|
|
382
|
-
return renderSelectOption(entry, value);
|
|
383
|
-
})}
|
|
384
|
-
</select>
|
|
385
|
-
<!--
|
|
386
|
-
These separate style elements are necessary so that we can select them as
|
|
387
|
-
siblings of the focused <select> element.
|
|
388
|
-
-->
|
|
389
|
-
|
|
390
|
-
<div class="border-style focus-border"></div>
|
|
391
|
-
|
|
392
|
-
<div class="border-style wrapper-border"></div>
|
|
393
|
-
|
|
394
|
-
<${ViraIcon.assign({
|
|
395
|
-
icon: inputs.icon,
|
|
396
|
-
})}
|
|
397
|
-
class="input-icon"
|
|
398
|
-
></${ViraIcon}>
|
|
399
|
-
<${ViraIcon.assign({
|
|
400
|
-
icon: ChevronUp16Icon,
|
|
401
|
-
})}
|
|
402
|
-
class="trigger-icon"
|
|
403
|
-
></${ViraIcon}>
|
|
404
|
-
</span>
|
|
405
|
-
`;
|
|
406
|
-
if (inputs.label) {
|
|
407
|
-
return html `
|
|
408
|
-
<label for=${state.randomId} ${attributes(inputs.attributePassthrough?.label)}>
|
|
409
|
-
<span class="select-label">${inputs.label}</span>
|
|
410
|
-
${selectTemplate}
|
|
411
|
-
</label>
|
|
412
|
-
`;
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
return selectTemplate;
|
|
416
|
-
}
|
|
417
|
-
},
|
|
418
|
-
});
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { type MaybePromise } from '@augment-vir/common';
|
|
2
|
-
import { type Coords, type NavController } from 'device-navigation';
|
|
3
|
-
import { type ExtractEventByType, type ExtractEventTypes, type ListenOptions, ListenTarget, type RemoveListenerCallback } from 'typed-event-target';
|
|
4
|
-
/**
|
|
5
|
-
* Used to prevent pop-ups from closing when a text input is active.
|
|
6
|
-
*
|
|
7
|
-
* @category Internal
|
|
8
|
-
*/
|
|
9
|
-
export declare function isInputLikeElement(element: Element): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Determines if a mouse event landed on a scrollbar rather than on element content. Scrollbar
|
|
12
|
-
* interactions fire mouse events on the scrolling element itself (or on `<html>` for the page
|
|
13
|
-
* scrollbar), so an outside-click check would otherwise treat dragging a scrollbar as a click away
|
|
14
|
-
* from the pop-up and dismiss it mid-drag.
|
|
15
|
-
*
|
|
16
|
-
* @category Internal
|
|
17
|
-
*/
|
|
18
|
-
export declare function isMouseEventOnScrollbar(event: Readonly<MouseEvent>): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* A type used for representing a rectangle's position.
|
|
21
|
-
*
|
|
22
|
-
* @category Internal
|
|
23
|
-
*/
|
|
24
|
-
export type PositionRect = {
|
|
25
|
-
top: number;
|
|
26
|
-
left: number;
|
|
27
|
-
right: number;
|
|
28
|
-
bottom: number;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* The default empty {@link PositionRect}, with all values set to 0.
|
|
32
|
-
*
|
|
33
|
-
* @category Internal
|
|
34
|
-
*/
|
|
35
|
-
export declare const emptyPositionRect: PositionRect;
|
|
36
|
-
/**
|
|
37
|
-
* Options for {@link PopUpManager}.
|
|
38
|
-
*
|
|
39
|
-
* @category PopUp
|
|
40
|
-
*/
|
|
41
|
-
export type PopUpManagerOptions = {
|
|
42
|
-
/**
|
|
43
|
-
* The minimum number of pixels for allowing the pop-up to go downwards. If the downward
|
|
44
|
-
* available space is less than this, and if the upwards available space is
|
|
45
|
-
* `verticalDiffThreshold` more than the downwards space, the pop-up will be directed upwards.
|
|
46
|
-
*
|
|
47
|
-
* Equation:
|
|
48
|
-
*
|
|
49
|
-
* const directUpwards =
|
|
50
|
-
* downwardsSpace < minDownSpace &&
|
|
51
|
-
* upwardsSpace > DownwardsSpace + verticalDiffThreshold;
|
|
52
|
-
*
|
|
53
|
-
* @default 200
|
|
54
|
-
*/
|
|
55
|
-
minDownSpace: number;
|
|
56
|
-
/**
|
|
57
|
-
* The minimum number of pixels for allowing the pop-up to go rightwards. If the rightward
|
|
58
|
-
* available space is less than this, and if the leftwards available space is
|
|
59
|
-
* `horizontalDiffThreshold` more than the rightwards space, the pop-up will be directed
|
|
60
|
-
* leftwards.
|
|
61
|
-
*
|
|
62
|
-
* Equation:
|
|
63
|
-
*
|
|
64
|
-
* const directLeftwards =
|
|
65
|
-
* rightwardsSpace < minRightSpace &&
|
|
66
|
-
* leftwardsSpace > rightwardsSpace + horizontalDiffThreshold;
|
|
67
|
-
*
|
|
68
|
-
* @default 400
|
|
69
|
-
*/
|
|
70
|
-
minRightSpace: number;
|
|
71
|
-
/**
|
|
72
|
-
* The number of pixels required for the upwards available space to be bigger than the downwards
|
|
73
|
-
* available space before directing the pop-up upwards.
|
|
74
|
-
*
|
|
75
|
-
* Equation:
|
|
76
|
-
*
|
|
77
|
-
* const directUpwards =
|
|
78
|
-
* downwardsSpace < minDownSpace &&
|
|
79
|
-
* upwardsSpace > DownwardsSpace + verticalDiffThreshold;
|
|
80
|
-
*
|
|
81
|
-
* @default 20
|
|
82
|
-
*/
|
|
83
|
-
verticalDiffThreshold: number;
|
|
84
|
-
/**
|
|
85
|
-
* The number of pixels required for the leftwards available space to be bigger than the
|
|
86
|
-
* rightwards available space before directing the pop-up leftwards.
|
|
87
|
-
*
|
|
88
|
-
* Equation:
|
|
89
|
-
*
|
|
90
|
-
* const directLeftwards =
|
|
91
|
-
* rightwardsSpace < minRightSpace &&
|
|
92
|
-
* leftwardsSpace > rightwardsSpace + horizontalDiffThreshold;
|
|
93
|
-
*
|
|
94
|
-
* @default 100
|
|
95
|
-
*/
|
|
96
|
-
horizontalDiffThreshold: number;
|
|
97
|
-
/**
|
|
98
|
-
* Supports navigation of the pop up via the `device-navigation` package.
|
|
99
|
-
*
|
|
100
|
-
* @default true
|
|
101
|
-
*/
|
|
102
|
-
supportNavigation: boolean;
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Output type from `PopUpManager.showPopUp`
|
|
106
|
-
*
|
|
107
|
-
* @category PopUp
|
|
108
|
-
*/
|
|
109
|
-
export type ShowPopUpResult = {
|
|
110
|
-
/**
|
|
111
|
-
* Indicates if the "pop up" should pop in the downwards direction or not. If not, it should pop
|
|
112
|
-
* in the upwards direction. This is determined by how much space is available on either side of
|
|
113
|
-
* the root element.
|
|
114
|
-
*/
|
|
115
|
-
popDown: boolean;
|
|
116
|
-
/**
|
|
117
|
-
* Indicates if the "pop up" should pop in the rightwards direction or not. If not, it should
|
|
118
|
-
* pop in the leftwards direction. This is determined by how much space is available on either
|
|
119
|
-
* side of the root element.
|
|
120
|
-
*/
|
|
121
|
-
popRight: boolean;
|
|
122
|
-
positions: Record<'root' | 'container' | 'diff', PositionRect>;
|
|
123
|
-
};
|
|
124
|
-
declare const HidePopUpEvent_base: (new (eventInitDict?: EventInit) => Event & import("typed-event-target").TypedEvent<"hide-pop-up">) & Pick<{
|
|
125
|
-
new (type: string, eventInitDict?: EventInit): Event;
|
|
126
|
-
prototype: Event;
|
|
127
|
-
readonly NONE: 0;
|
|
128
|
-
readonly CAPTURING_PHASE: 1;
|
|
129
|
-
readonly AT_TARGET: 2;
|
|
130
|
-
readonly BUBBLING_PHASE: 3;
|
|
131
|
-
}, "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE" | "prototype"> & Pick<import("typed-event-target").TypedEvent<"hide-pop-up">, "type">;
|
|
132
|
-
/**
|
|
133
|
-
* An event fired from {@link PopUpManager} when the pop up should be hidden.
|
|
134
|
-
*
|
|
135
|
-
* @category PopUp
|
|
136
|
-
*/
|
|
137
|
-
export declare class HidePopUpEvent extends HidePopUpEvent_base {
|
|
138
|
-
}
|
|
139
|
-
declare const NavSelectEvent_base: (new (eventInitDict: {
|
|
140
|
-
bubbles?: boolean;
|
|
141
|
-
cancelable?: boolean;
|
|
142
|
-
composed?: boolean;
|
|
143
|
-
detail: Coords;
|
|
144
|
-
}) => import("typed-event-target").TypedCustomEvent<Coords, "nav-select">) & Pick<{
|
|
145
|
-
new (type: string, eventInitDict?: EventInit): Event;
|
|
146
|
-
prototype: Event;
|
|
147
|
-
readonly NONE: 0;
|
|
148
|
-
readonly CAPTURING_PHASE: 1;
|
|
149
|
-
readonly AT_TARGET: 2;
|
|
150
|
-
readonly BUBBLING_PHASE: 3;
|
|
151
|
-
}, "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE" | "prototype"> & Pick<import("typed-event-target").TypedCustomEvent<Coords, "nav-select">, "type">;
|
|
152
|
-
/**
|
|
153
|
-
* An event fired from {@link PopUpManager} when an individual item in the pop up has been selected
|
|
154
|
-
* by the user.
|
|
155
|
-
*
|
|
156
|
-
* @category PopUp
|
|
157
|
-
*/
|
|
158
|
-
export declare class NavSelectEvent extends NavSelectEvent_base {
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* All events that can be emitted by {@link PopUpManager}.
|
|
162
|
-
*
|
|
163
|
-
* @category Internal
|
|
164
|
-
*/
|
|
165
|
-
export type PopUpManagerEvents = HidePopUpEvent | NavSelectEvent;
|
|
166
|
-
/**
|
|
167
|
-
* A "pop up" manager for items that pop up from the HTML page, like dropdowns or menus.
|
|
168
|
-
*
|
|
169
|
-
* @category PopUp
|
|
170
|
-
*/
|
|
171
|
-
export declare class PopUpManager {
|
|
172
|
-
readonly navController: NavController;
|
|
173
|
-
protected listenTarget: ListenTarget<PopUpManagerEvents>;
|
|
174
|
-
options: PopUpManagerOptions;
|
|
175
|
-
/** Callbacks that remove the global listeners attached while a pop up is shown. */
|
|
176
|
-
protected cleanupCallbacks: (() => void)[];
|
|
177
|
-
protected lastRootElement: HTMLElement | undefined;
|
|
178
|
-
constructor(navController: NavController, options?: Partial<PopUpManagerOptions> | undefined);
|
|
179
|
-
/**
|
|
180
|
-
* Attaches the global listeners (page activation, navigation, mousedown, and keydown) that
|
|
181
|
-
* control the currently shown pop up.
|
|
182
|
-
*/
|
|
183
|
-
protected attachGlobalListeners(): void;
|
|
184
|
-
/** Listen to events emitted from a {@link PopUpManager} instance. */
|
|
185
|
-
listen<const EventDefinition extends Readonly<{
|
|
186
|
-
type: ExtractEventTypes<PopUpManagerEvents>;
|
|
187
|
-
}>>(event: EventDefinition, listener: (event: ExtractEventByType<PopUpManagerEvents, EventDefinition['type']>) => MaybePromise<void>, options?: ListenOptions | undefined): RemoveListenerCallback;
|
|
188
|
-
/** Trigger removal or hiding of the pop up. */
|
|
189
|
-
removePopUp(): void;
|
|
190
|
-
/** Trigger showing the pop up. */
|
|
191
|
-
showPopUp(rootElement: HTMLElement, options?: Partial<PopUpManagerOptions> | undefined): ShowPopUpResult;
|
|
192
|
-
/**
|
|
193
|
-
* Cleanup and destroy the {@link PopUpManager} instance. This:
|
|
194
|
-
*
|
|
195
|
-
* - Removes the existing pop up
|
|
196
|
-
* - Cleans up all internal and external listeners
|
|
197
|
-
*/
|
|
198
|
-
destroy(): void;
|
|
199
|
-
}
|
|
200
|
-
export {};
|