@vollowx/seele 0.11.2 → 0.12.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/custom-elements.json +1 -1396
- package/package.json +1 -1
- package/src/all.js +1 -0
- package/src/base/autocomplete.js +172 -0
- package/src/base/controllers/list-controller.js +36 -16
- package/src/base/input.js +8 -8
- package/src/base/menu.js +9 -27
- package/src/base/select.js +2 -0
- package/src/m3/autocomplete/autocomplete-styles.css.js +2 -0
- package/src/m3/autocomplete/autocomplete.js +35 -0
- package/src/m3/list/list-item-styles.css.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vollowx/seele",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Standard Extensible Elements. A web components library that can be styled and extended freely, pre-providing components in Material Design 3.",
|
|
5
5
|
"author": "vollowx",
|
|
6
6
|
"license": "Apache-2.0",
|
package/src/all.js
CHANGED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
|
+
import { LitElement, html } from 'lit';
|
|
3
|
+
import { property, query, queryAssignedElements } from 'lit/decorators.js';
|
|
4
|
+
import { InternalsAttached } from './mixins/internals-attached.js';
|
|
5
|
+
import { FocusDelegated } from './mixins/focus-delegated.js';
|
|
6
|
+
const Base = FocusDelegated(InternalsAttached(LitElement));
|
|
7
|
+
/**
|
|
8
|
+
* TODO: Check if manually dispatching input/change events on input is necessary
|
|
9
|
+
*/ export class Autocomplete extends Base {
|
|
10
|
+
get $input() {
|
|
11
|
+
return this.inputSlotElements[0];
|
|
12
|
+
}
|
|
13
|
+
render() {
|
|
14
|
+
return html`
|
|
15
|
+
<slot name="input" @slotchange=${this.handleInputSlotChange}></slot>
|
|
16
|
+
${this.renderMenu()}
|
|
17
|
+
`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Example content:
|
|
21
|
+
*
|
|
22
|
+
* ```html
|
|
23
|
+
* <your-menu
|
|
24
|
+
* part="menu"
|
|
25
|
+
* id="menu"
|
|
26
|
+
* type="listbox"
|
|
27
|
+
* data-tabindex="-1"
|
|
28
|
+
* .offset=${this.offset}
|
|
29
|
+
* .align=${this.align}
|
|
30
|
+
* .alignStrategy=${this.alignStrategy}
|
|
31
|
+
* no-focus-control
|
|
32
|
+
* ?open=${this.open}
|
|
33
|
+
* @open="${() => (this.open = true)}"
|
|
34
|
+
* @close="${() => (this.open = false)}"
|
|
35
|
+
* @select=${this.handleMenuSelect}
|
|
36
|
+
* >
|
|
37
|
+
* <slot @slotchange=${this.handleItemsSlotChange}></slot>
|
|
38
|
+
* </your-menu>
|
|
39
|
+
* ```
|
|
40
|
+
*/ renderMenu() {
|
|
41
|
+
return html``;
|
|
42
|
+
}
|
|
43
|
+
handleInputSlotChange() {
|
|
44
|
+
const input = this.$input;
|
|
45
|
+
if (!input) return;
|
|
46
|
+
const $realInput = this.$input.$inputOrTextarea;
|
|
47
|
+
if ($realInput) {
|
|
48
|
+
$realInput.role = 'combobox';
|
|
49
|
+
$realInput.ariaExpanded = String(this.open);
|
|
50
|
+
$realInput.ariaHasPopup = 'listbox';
|
|
51
|
+
$realInput.ariaAutoComplete = this.mode;
|
|
52
|
+
$realInput.ariaControlsElements = [
|
|
53
|
+
this.$menu
|
|
54
|
+
];
|
|
55
|
+
input.addEventListener('input', this.handleInput.bind(this));
|
|
56
|
+
input.addEventListener('keydown', this.handleInputKeydown.bind(this));
|
|
57
|
+
input.addEventListener('click', ()=>this.open = !this.open);
|
|
58
|
+
this.$menu.attach($realInput);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
handleItemsSlotChange() {
|
|
62
|
+
// Initial filter based on current input value (if any)
|
|
63
|
+
this.filterOptions(this.$input?.value || '');
|
|
64
|
+
}
|
|
65
|
+
handleInput(event) {
|
|
66
|
+
const inputEl = this.$input.$inputOrTextarea;
|
|
67
|
+
const currentValue = inputEl.value;
|
|
68
|
+
this.open = true;
|
|
69
|
+
// Filter items based on current value
|
|
70
|
+
const firstMatch = this.filterOptions(currentValue);
|
|
71
|
+
// Inline completion logic (mode = both)
|
|
72
|
+
if (this.mode === 'both' && event.inputType !== 'deleteContentBackward') {
|
|
73
|
+
if (firstMatch && currentValue.length > 0) {
|
|
74
|
+
this.applyInlineAutoComplete(inputEl, firstMatch, currentValue);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
applyInlineAutoComplete(inputEl, item, typedValue) {
|
|
79
|
+
const suggestion = item.textContent?.trim() || '';
|
|
80
|
+
if (suggestion.toLowerCase().startsWith(typedValue.toLowerCase())) {
|
|
81
|
+
inputEl.value = suggestion;
|
|
82
|
+
inputEl.setSelectionRange(typedValue.length, suggestion.length);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
filterOptions(searchTerm) {
|
|
86
|
+
if (this.mode === 'none') return null;
|
|
87
|
+
const normalizedSearch = searchTerm.toLowerCase();
|
|
88
|
+
let firstMatch = null;
|
|
89
|
+
this.itemSlotElements.forEach((item)=>{
|
|
90
|
+
const text = (item.textContent || '').toLowerCase().trim();
|
|
91
|
+
const isMatch = text.startsWith(normalizedSearch);
|
|
92
|
+
item.hidden = !isMatch;
|
|
93
|
+
if (isMatch && !firstMatch) {
|
|
94
|
+
firstMatch = item;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return firstMatch;
|
|
98
|
+
}
|
|
99
|
+
handleInputKeydown(event) {
|
|
100
|
+
if (this.$input?.disabled) return;
|
|
101
|
+
if ([
|
|
102
|
+
'Enter',
|
|
103
|
+
'Escape',
|
|
104
|
+
'ArrowUp',
|
|
105
|
+
'ArrowDown'
|
|
106
|
+
].includes(event.key)) {
|
|
107
|
+
const eventClone = new KeyboardEvent(event.type, event);
|
|
108
|
+
eventClone.preventDefault = ()=>event.preventDefault();
|
|
109
|
+
eventClone.stopPropagation = ()=>event.stopPropagation();
|
|
110
|
+
this.$menu.$menu.dispatchEvent(eventClone);
|
|
111
|
+
if (event.key === 'Enter') this.open = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
handleMenuSelect(event) {
|
|
115
|
+
const selectedItem = event.detail.item;
|
|
116
|
+
const newValue = selectedItem.getAttribute('value') || selectedItem.textContent?.trim() || '';
|
|
117
|
+
if (this.$input) {
|
|
118
|
+
this.$input.value = newValue;
|
|
119
|
+
}
|
|
120
|
+
this.open = false;
|
|
121
|
+
}
|
|
122
|
+
updated(changed) {
|
|
123
|
+
if (changed.has('open') && this.$input) {
|
|
124
|
+
const $input = this.$input.$inputOrTextarea;
|
|
125
|
+
if ($input) {
|
|
126
|
+
$input.ariaExpanded = String(this.open);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
constructor(...args){
|
|
131
|
+
super(...args), this.open = false, this.offset = 0, this.align = 'bottom-start', this.alignStrategy = 'absolute', this.mode = 'none';
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
_ts_decorate([
|
|
135
|
+
property({
|
|
136
|
+
type: Boolean
|
|
137
|
+
})
|
|
138
|
+
], Autocomplete.prototype, "open", void 0);
|
|
139
|
+
_ts_decorate([
|
|
140
|
+
property({
|
|
141
|
+
type: Number
|
|
142
|
+
})
|
|
143
|
+
], Autocomplete.prototype, "offset", void 0);
|
|
144
|
+
_ts_decorate([
|
|
145
|
+
property({
|
|
146
|
+
reflect: true
|
|
147
|
+
})
|
|
148
|
+
], Autocomplete.prototype, "align", void 0);
|
|
149
|
+
_ts_decorate([
|
|
150
|
+
property({
|
|
151
|
+
type: String,
|
|
152
|
+
reflect: true,
|
|
153
|
+
attribute: 'align-strategy'
|
|
154
|
+
})
|
|
155
|
+
], Autocomplete.prototype, "alignStrategy", void 0);
|
|
156
|
+
_ts_decorate([
|
|
157
|
+
property()
|
|
158
|
+
], Autocomplete.prototype, "mode", void 0);
|
|
159
|
+
_ts_decorate([
|
|
160
|
+
query('[part="menu"]')
|
|
161
|
+
], Autocomplete.prototype, "$menu", void 0);
|
|
162
|
+
_ts_decorate([
|
|
163
|
+
queryAssignedElements({
|
|
164
|
+
slot: 'input',
|
|
165
|
+
flatten: true
|
|
166
|
+
})
|
|
167
|
+
], Autocomplete.prototype, "inputSlotElements", void 0);
|
|
168
|
+
_ts_decorate([
|
|
169
|
+
queryAssignedElements({
|
|
170
|
+
flatten: true
|
|
171
|
+
})
|
|
172
|
+
], Autocomplete.prototype, "itemSlotElements", void 0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { filterOptions } from '../menu.js';
|
|
2
2
|
export class ListController {
|
|
3
3
|
constructor(host, config){
|
|
4
|
-
this.
|
|
4
|
+
this._focusedItem = null;
|
|
5
5
|
this.searchString = '';
|
|
6
6
|
this.searchTimeout = null;
|
|
7
7
|
const { isItem, getPossibleItems, blurItem, focusItem, wrapNavigation } = config;
|
|
@@ -18,8 +18,8 @@ export class ListController {
|
|
|
18
18
|
return this.getPossibleItems().filter(this.isItem);
|
|
19
19
|
}
|
|
20
20
|
get currentIndex() {
|
|
21
|
-
|
|
22
|
-
return items.
|
|
21
|
+
if (!this._focusedItem) return -1;
|
|
22
|
+
return this.items.indexOf(this._focusedItem);
|
|
23
23
|
}
|
|
24
24
|
handleType(char) {
|
|
25
25
|
const searchString = this.getSearchString(char);
|
|
@@ -53,13 +53,13 @@ export class ListController {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
_focusItem(item) {
|
|
56
|
-
if (this.
|
|
56
|
+
if (this._focusedItem !== null) this._blurItem(this._focusedItem);
|
|
57
57
|
this.focusItem(item);
|
|
58
|
-
this.
|
|
58
|
+
this._focusedItem = item;
|
|
59
59
|
}
|
|
60
60
|
_blurItem(item) {
|
|
61
61
|
this.blurItem(item);
|
|
62
|
-
this.
|
|
62
|
+
this._focusedItem = null;
|
|
63
63
|
}
|
|
64
64
|
focusFirstItem() {
|
|
65
65
|
this._focusItem(this.items[0]);
|
|
@@ -68,24 +68,44 @@ export class ListController {
|
|
|
68
68
|
this._focusItem(this.items[this.items.length - 1]);
|
|
69
69
|
}
|
|
70
70
|
focusNextItem() {
|
|
71
|
-
const
|
|
71
|
+
const items = this.items;
|
|
72
|
+
const count = items.length;
|
|
72
73
|
if (count === 0) return;
|
|
73
|
-
let nextIndex = this.
|
|
74
|
+
let nextIndex = this.currentIndex + 1;
|
|
74
75
|
if (nextIndex >= count) {
|
|
75
|
-
nextIndex = this.wrapNavigation() ? count - 1
|
|
76
|
+
nextIndex = this.wrapNavigation() ? 0 : count - 1;
|
|
76
77
|
}
|
|
77
|
-
this._focusItem(
|
|
78
|
+
this._focusItem(items[nextIndex]);
|
|
78
79
|
}
|
|
79
80
|
focusPreviousItem() {
|
|
80
|
-
const
|
|
81
|
+
const items = this.items;
|
|
82
|
+
const count = items.length;
|
|
81
83
|
if (count === 0) return;
|
|
82
|
-
let prevIndex = this.
|
|
84
|
+
let prevIndex = this.currentIndex - 1;
|
|
83
85
|
if (prevIndex < 0) {
|
|
84
|
-
prevIndex = this.wrapNavigation() ?
|
|
86
|
+
prevIndex = this.wrapNavigation() ? count - 1 : 0;
|
|
85
87
|
}
|
|
86
|
-
this._focusItem(
|
|
88
|
+
this._focusItem(items[prevIndex]);
|
|
87
89
|
}
|
|
88
90
|
handleSlotChange() {
|
|
89
|
-
|
|
91
|
+
const items = this.items;
|
|
92
|
+
const index = this.currentIndex;
|
|
93
|
+
this._focusedItem = index >= 0 ? items[index] : null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function getIndexByLetter(options, filter, startIndex = 0) {
|
|
97
|
+
const orderedOptions = [
|
|
98
|
+
...options.slice(startIndex),
|
|
99
|
+
...options.slice(0, startIndex)
|
|
100
|
+
];
|
|
101
|
+
const firstMatch = filterOptions(orderedOptions, filter)[0];
|
|
102
|
+
const allSameLetter = (array)=>array.every((letter)=>letter === array[0]);
|
|
103
|
+
if (firstMatch) {
|
|
104
|
+
return options.indexOf(firstMatch);
|
|
105
|
+
} else if (allSameLetter(filter.split(''))) {
|
|
106
|
+
const matches = filterOptions(orderedOptions, filter[0]);
|
|
107
|
+
return options.indexOf(matches[0]);
|
|
108
|
+
} else {
|
|
109
|
+
return -1;
|
|
90
110
|
}
|
|
91
111
|
}
|
package/src/base/input.js
CHANGED
|
@@ -89,22 +89,22 @@ export class Input extends Base {
|
|
|
89
89
|
this.dispatchEvent(newEvent);
|
|
90
90
|
}
|
|
91
91
|
syncValidity() {
|
|
92
|
-
if (!this
|
|
93
|
-
this[internals].setValidity(this
|
|
92
|
+
if (!this.$inputOrTextarea) return;
|
|
93
|
+
this[internals].setValidity(this.$inputOrTextarea.validity, this.$inputOrTextarea.validationMessage, this.$inputOrTextarea);
|
|
94
94
|
}
|
|
95
95
|
select() {
|
|
96
|
-
this
|
|
96
|
+
this.$inputOrTextarea?.select();
|
|
97
97
|
}
|
|
98
98
|
stepUp(n) {
|
|
99
|
-
this
|
|
99
|
+
this.$inputOrTextarea?.stepUp(n);
|
|
100
100
|
this.handleInput({
|
|
101
|
-
target: this
|
|
101
|
+
target: this.$inputOrTextarea
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
stepDown(n) {
|
|
105
|
-
this
|
|
105
|
+
this.$inputOrTextarea?.stepDown(n);
|
|
106
106
|
this.handleInput({
|
|
107
|
-
target: this
|
|
107
|
+
target: this.$inputOrTextarea
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
formResetCallback() {
|
|
@@ -189,4 +189,4 @@ _ts_decorate([
|
|
|
189
189
|
], Input.prototype, "focused", void 0);
|
|
190
190
|
_ts_decorate([
|
|
191
191
|
query('[part~=input]')
|
|
192
|
-
], Input.prototype, "inputOrTextarea", void 0);
|
|
192
|
+
], Input.prototype, "$inputOrTextarea", void 0);
|
package/src/base/menu.js
CHANGED
|
@@ -16,8 +16,6 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
16
16
|
* @fires {Event} close - Fires when the menu is closed.
|
|
17
17
|
* @fires {MenuSelectEvent} select - Fires when an item is selected.
|
|
18
18
|
* @fires {MenuItemFocusEvent} item-focus - Fires when an item is focused
|
|
19
|
-
*
|
|
20
|
-
* FIXME: aria-activedescendant may not work in and out shadow DOM
|
|
21
19
|
*/ export class Menu extends Base {
|
|
22
20
|
get $items() {
|
|
23
21
|
return this.listController.items || [];
|
|
@@ -74,6 +72,9 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
74
72
|
}
|
|
75
73
|
});
|
|
76
74
|
} else {
|
|
75
|
+
if (!this.noFocusControl) {
|
|
76
|
+
this.$menu.ariaActiveDescendantElement = null;
|
|
77
|
+
}
|
|
77
78
|
this.dispatchEvent(new Event('close', {
|
|
78
79
|
bubbles: true,
|
|
79
80
|
composed: true
|
|
@@ -189,7 +190,7 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
189
190
|
super(...args), this._possibleItemTags = [], this._durations = {
|
|
190
191
|
show: 0,
|
|
191
192
|
hide: 0
|
|
192
|
-
}, this._scrollPadding = 0, this.type = 'menu', this.open = false, this.quick = false, this.offset = 0, this.align = 'bottom-start', this.alignStrategy = 'absolute', this.keepOpenBlur = false, this.keepOpenClickItem = false, this.keepOpenClickAway = false, this.
|
|
193
|
+
}, this._scrollPadding = 0, this.type = 'menu', this.open = false, this.quick = false, this.offset = 0, this.align = 'bottom-start', this.alignStrategy = 'absolute', this.keepOpenBlur = false, this.keepOpenClickItem = false, this.keepOpenClickAway = false, this.noFocusControl = false, this.tabIndex = 0, this.$lastFocused = null, this.popoverController = new PopoverController(this, {
|
|
193
194
|
popover: ()=>this.$menu,
|
|
194
195
|
trigger: ()=>this.$control,
|
|
195
196
|
positioning: {
|
|
@@ -206,14 +207,17 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
206
207
|
if (!this.keepOpenClickAway) this.open = false;
|
|
207
208
|
}
|
|
208
209
|
}), this.listController = new ListController(this, {
|
|
209
|
-
isItem: (item)=>this._possibleItemTags.includes(item.tagName.toLowerCase()) && !item.hasAttribute('disabled'),
|
|
210
|
+
isItem: (item)=>this._possibleItemTags.includes(item.tagName.toLowerCase()) && !item.hasAttribute('disabled') && !item.hidden,
|
|
210
211
|
getPossibleItems: ()=>this.slotItems,
|
|
211
212
|
blurItem: (item)=>{
|
|
213
|
+
console.log(item);
|
|
212
214
|
item.focused = false;
|
|
213
215
|
},
|
|
214
216
|
focusItem: (item)=>{
|
|
215
217
|
item.focused = true;
|
|
216
|
-
if (!this.noFocusControl)
|
|
218
|
+
if (!this.noFocusControl) {
|
|
219
|
+
this.$menu.ariaActiveDescendantElement = item;
|
|
220
|
+
}
|
|
217
221
|
scrollItemIntoView(this.$menu, item, this._scrollPadding);
|
|
218
222
|
this.dispatchEvent(new CustomEvent('item-focus', {
|
|
219
223
|
detail: {
|
|
@@ -276,12 +280,6 @@ _ts_decorate([
|
|
|
276
280
|
attribute: 'keep-open-click-away'
|
|
277
281
|
})
|
|
278
282
|
], Menu.prototype, "keepOpenClickAway", void 0);
|
|
279
|
-
_ts_decorate([
|
|
280
|
-
property({
|
|
281
|
-
type: Boolean,
|
|
282
|
-
attribute: 'no-list-control'
|
|
283
|
-
})
|
|
284
|
-
], Menu.prototype, "noListControl", void 0);
|
|
285
283
|
_ts_decorate([
|
|
286
284
|
property({
|
|
287
285
|
type: Boolean,
|
|
@@ -361,22 +359,6 @@ export function getActionFromKey(event, menuOpen) {
|
|
|
361
359
|
}
|
|
362
360
|
return undefined;
|
|
363
361
|
}
|
|
364
|
-
export function getIndexByLetter(options, filter, startIndex = 0) {
|
|
365
|
-
const orderedOptions = [
|
|
366
|
-
...options.slice(startIndex),
|
|
367
|
-
...options.slice(0, startIndex)
|
|
368
|
-
];
|
|
369
|
-
const firstMatch = filterOptions(orderedOptions, filter)[0];
|
|
370
|
-
const allSameLetter = (array)=>array.every((letter)=>letter === array[0]);
|
|
371
|
-
if (firstMatch) {
|
|
372
|
-
return options.indexOf(firstMatch);
|
|
373
|
-
} else if (allSameLetter(filter.split(''))) {
|
|
374
|
-
const matches = filterOptions(orderedOptions, filter[0]);
|
|
375
|
-
return options.indexOf(matches[0]);
|
|
376
|
-
} else {
|
|
377
|
-
return -1;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
362
|
export function getUpdatedIndex(currentIndex, maxIndex, action) {
|
|
381
363
|
const pageSize = 10;
|
|
382
364
|
switch(action){
|
package/src/base/select.js
CHANGED
|
@@ -150,6 +150,8 @@ const Base = FormAssociated(FocusDelegated(InternalsAttached(LitElement)));
|
|
|
150
150
|
*/ handleFieldKeydown(event) {
|
|
151
151
|
if (this.disabled) return;
|
|
152
152
|
const eventClone = new KeyboardEvent(event.type, event);
|
|
153
|
+
eventClone.preventDefault = ()=>event.preventDefault();
|
|
154
|
+
eventClone.stopPropagation = ()=>event.stopPropagation();
|
|
153
155
|
this.$menu.$menu.dispatchEvent(eventClone);
|
|
154
156
|
}
|
|
155
157
|
handleMenuSelect(event) {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const autocompleteStyles = css`:host{-webkit-user-select:none;user-select:none;min-width:210px;display:inline-block;position:relative}::slotted([slot=input]){cursor:pointer;outline:none;width:100%}[part=menu]{--md-menu-max-height:300px;min-width:100%}`;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { customElement } from 'lit/decorators.js';
|
|
4
|
+
import { Autocomplete } from '../../base/autocomplete.js';
|
|
5
|
+
import { autocompleteStyles } from './autocomplete-styles.css.js';
|
|
6
|
+
export class M3Autocomplete extends Autocomplete {
|
|
7
|
+
static{
|
|
8
|
+
this.styles = [
|
|
9
|
+
autocompleteStyles
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
renderMenu() {
|
|
13
|
+
return html`
|
|
14
|
+
<md-menu
|
|
15
|
+
part="menu"
|
|
16
|
+
id="menu"
|
|
17
|
+
type="listbox"
|
|
18
|
+
data-tabindex="-1"
|
|
19
|
+
.offset=${this.offset}
|
|
20
|
+
.align=${this.align}
|
|
21
|
+
.alignStrategy=${this.alignStrategy}
|
|
22
|
+
no-focus-control
|
|
23
|
+
?open=${this.open}
|
|
24
|
+
@open="${()=>this.open = true}"
|
|
25
|
+
@close="${()=>this.open = false}"
|
|
26
|
+
@select=${this.handleMenuSelect}
|
|
27
|
+
>
|
|
28
|
+
<slot @slotchange=${this.handleItemsSlotChange}></slot>
|
|
29
|
+
</md-menu>
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
M3Autocomplete = _ts_decorate([
|
|
34
|
+
customElement('md-autocomplete')
|
|
35
|
+
], M3Autocomplete);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const listItemStyles = css`:host{--md-focus-ring-shape:12px;--md-focus-ring-inward-offset:-3px;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;border-radius:4px;outline:0;display:flex}:host(:first-of-type){border-radius:12px 12px 4px 4px}:host(:last-of-type){border-radius:4px 4px 12px 12px}:host(:state(selected)){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-radius:12px}:host(:disabled){cursor:default;opacity:.3;pointer-events:none}md-item,md-item div[slot=container]{border-radius:inherit}`;
|
|
2
|
+
export const listItemStyles = css`:host{--md-focus-ring-shape:12px;--md-focus-ring-inward-offset:-3px;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;border-radius:4px;outline:0;display:flex}:host(:not([hidden]):first-of-type){border-radius:12px 12px 4px 4px}:host(:not([hidden]):last-of-type){border-radius:4px 4px 12px 12px}:host(:state(selected)){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-radius:12px}:host(:disabled){cursor:default;opacity:.3;pointer-events:none}md-item,md-item div[slot=container]{border-radius:inherit}`;
|