mdui 2.0.0 → 2.0.2
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/components/avatar/index.js +2 -1
- package/components/badge/index.js +2 -1
- package/components/bottom-app-bar/index.d.ts +2 -2
- package/components/bottom-app-bar/index.js +4 -3
- package/components/button/button-base.d.ts +2 -2
- package/components/button/button-base.js +15 -14
- package/components/button/index.js +2 -1
- package/components/button-icon/index.js +2 -1
- package/components/card/index.d.ts +1 -1
- package/components/card/index.js +5 -2
- package/components/checkbox/index.js +7 -10
- package/components/checkbox/style.js +1 -1
- package/components/chip/index.js +2 -1
- package/components/circular-progress/index.js +3 -3
- package/components/collapse/collapse-item-style.js +1 -1
- package/components/collapse/collapse-item.d.ts +2 -1
- package/components/collapse/collapse-item.js +23 -20
- package/components/collapse/collapse.d.ts +6 -6
- package/components/collapse/collapse.js +57 -34
- package/components/dialog/index.d.ts +3 -2
- package/components/dialog/index.js +27 -23
- package/components/divider/index.js +2 -1
- package/components/dropdown/index.d.ts +4 -5
- package/components/dropdown/index.js +56 -51
- package/components/fab/index.d.ts +1 -0
- package/components/fab/index.js +10 -5
- package/components/icon/index.js +2 -1
- package/components/layout/helper.d.ts +5 -6
- package/components/layout/helper.js +42 -48
- package/components/layout/layout-item-base.js +1 -2
- package/components/layout/layout-item.js +3 -3
- package/components/layout/layout-main.js +2 -1
- package/components/layout/layout.js +2 -1
- package/components/linear-progress/index.js +3 -3
- package/components/list/list-item.js +3 -2
- package/components/list/list-subheader.js +2 -1
- package/components/list/list.js +2 -1
- package/components/menu/menu-item.d.ts +1 -0
- package/components/menu/menu-item.js +45 -28
- package/components/menu/menu.d.ts +4 -1
- package/components/menu/menu.js +82 -56
- package/components/navigation-bar/navigation-bar-item-style.js +1 -1
- package/components/navigation-bar/navigation-bar-item.d.ts +6 -2
- package/components/navigation-bar/navigation-bar-item.js +26 -10
- package/components/navigation-bar/navigation-bar.d.ts +6 -6
- package/components/navigation-bar/navigation-bar.js +49 -42
- package/components/navigation-drawer/index.d.ts +5 -1
- package/components/navigation-drawer/index.js +62 -41
- package/components/navigation-rail/navigation-rail-item-style.js +1 -1
- package/components/navigation-rail/navigation-rail-item.d.ts +6 -2
- package/components/navigation-rail/navigation-rail-item.js +20 -8
- package/components/navigation-rail/navigation-rail.d.ts +4 -5
- package/components/navigation-rail/navigation-rail.js +51 -44
- package/components/radio/radio-group.d.ts +6 -4
- package/components/radio/radio-group.js +61 -48
- package/components/radio/radio-style.js +1 -1
- package/components/radio/radio.d.ts +3 -2
- package/components/radio/radio.js +24 -17
- package/components/range-slider/index.js +7 -9
- package/components/ripple/index.js +2 -1
- package/components/segmented-button/segmented-button-group.d.ts +6 -3
- package/components/segmented-button/segmented-button-group.js +84 -69
- package/components/segmented-button/segmented-button.d.ts +2 -2
- package/components/segmented-button/segmented-button.js +5 -4
- package/components/select/index.d.ts +2 -2
- package/components/select/index.js +26 -24
- package/components/slider/index.js +7 -9
- package/components/slider/slider-base-style.js +1 -1
- package/components/slider/slider-base.js +1 -5
- package/components/snackbar/index.js +2 -1
- package/components/switch/index.js +6 -9
- package/components/switch/style.js +1 -1
- package/components/tabs/tab-panel.js +2 -1
- package/components/tabs/tab-style.js +1 -1
- package/components/tabs/tab.js +10 -5
- package/components/tabs/tabs-style.js +1 -1
- package/components/tabs/tabs.d.ts +6 -5
- package/components/tabs/tabs.js +52 -38
- package/components/text-field/index.d.ts +2 -2
- package/components/text-field/index.js +32 -54
- package/components/text-field/style.js +1 -1
- package/components/tooltip/index.d.ts +5 -5
- package/components/tooltip/index.js +30 -25
- package/components/top-app-bar/top-app-bar-title-style.js +1 -1
- package/components/top-app-bar/top-app-bar-title.js +16 -12
- package/components/top-app-bar/top-app-bar.d.ts +2 -2
- package/components/top-app-bar/top-app-bar.js +6 -4
- package/custom-elements.json +3776 -3481
- package/functions/getTheme.js +3 -3
- package/functions/snackbar.js +1 -2
- package/functions/utils/colorScheme.js +2 -2
- package/html-data.zh-cn.json +727 -727
- package/mdui.esm.js +8 -8
- package/mdui.global.js +8 -8
- package/package.json +7 -7
- package/web-types.zh-cn.json +1265 -1265
|
@@ -9,9 +9,11 @@ import { $ } from '@mdui/jq/$.js';
|
|
|
9
9
|
import '@mdui/jq/methods/find.js';
|
|
10
10
|
import '@mdui/jq/methods/get.js';
|
|
11
11
|
import { isString } from '@mdui/jq/shared/helper.js';
|
|
12
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
12
13
|
import { FormController, formResets } from '@mdui/shared/controllers/form.js';
|
|
13
14
|
import { defaultValue } from '@mdui/shared/decorators/default-value.js';
|
|
14
15
|
import { watch } from '@mdui/shared/decorators/watch.js';
|
|
16
|
+
import { arraysEqualIgnoreOrder } from '@mdui/shared/helpers/array.js';
|
|
15
17
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
16
18
|
import { emit } from '@mdui/shared/helpers/event.js';
|
|
17
19
|
import { componentStyle } from '@mdui/shared/lit-styles/component-style.js';
|
|
@@ -34,7 +36,7 @@ import { segmentedButtonGroupStyle } from './segmented-button-group-style.js';
|
|
|
34
36
|
*
|
|
35
37
|
* @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
36
38
|
*/
|
|
37
|
-
|
|
39
|
+
let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement {
|
|
38
40
|
constructor() {
|
|
39
41
|
super(...arguments);
|
|
40
42
|
/**
|
|
@@ -72,10 +74,13 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
72
74
|
* 是否验证未通过
|
|
73
75
|
*/
|
|
74
76
|
this.invalid = false;
|
|
75
|
-
//
|
|
76
|
-
this.
|
|
77
|
+
// 是否为初始状态,初始状态不触发 change 事件
|
|
78
|
+
this.isInitial = true;
|
|
77
79
|
this.inputRef = createRef();
|
|
78
80
|
this.formController = new FormController(this);
|
|
81
|
+
this.definedController = new DefinedController(this, {
|
|
82
|
+
relatedElements: ['mdui-segmented-button'],
|
|
83
|
+
});
|
|
79
84
|
}
|
|
80
85
|
/**
|
|
81
86
|
* 表单验证状态对象
|
|
@@ -89,7 +94,7 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
89
94
|
get validationMessage() {
|
|
90
95
|
return this.inputRef.value.validationMessage;
|
|
91
96
|
}
|
|
92
|
-
//
|
|
97
|
+
// 为了使 <mdui-segmented-button> 可以不是该组件的直接子元素,这里不用 @queryAssignedElements()
|
|
93
98
|
get items() {
|
|
94
99
|
return $(this)
|
|
95
100
|
.find('mdui-segmented-button')
|
|
@@ -113,39 +118,35 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
113
118
|
get isSelectable() {
|
|
114
119
|
return this.isSingle || this.isMultiple;
|
|
115
120
|
}
|
|
116
|
-
onSelectsChange() {
|
|
117
|
-
if (!this.isSelectable
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
this.onValueChange();
|
|
121
|
+
async onSelectsChange() {
|
|
122
|
+
if (!this.isSelectable) {
|
|
123
|
+
// 不可选中,清空选中值
|
|
124
|
+
this.setSelectedKeys([]);
|
|
121
125
|
}
|
|
122
|
-
if (this.isSingle
|
|
123
|
-
|
|
124
|
-
this.
|
|
125
|
-
this.onValueChange();
|
|
126
|
+
else if (this.isSingle) {
|
|
127
|
+
// 单选,只保留第一个选中的值
|
|
128
|
+
this.setSelectedKeys(this.selectedKeys.slice(0, 1));
|
|
126
129
|
}
|
|
130
|
+
await this.onSelectedKeysChange();
|
|
127
131
|
}
|
|
128
|
-
onSelectedKeysChange() {
|
|
132
|
+
async onSelectedKeysChange() {
|
|
133
|
+
await this.definedController.whenDefined();
|
|
129
134
|
// 根据 selectedKeys 读取出对应 segmented-button 的 value
|
|
130
135
|
const values = this.itemsEnabled
|
|
131
136
|
.filter((item) => this.selectedKeys.includes(item.key))
|
|
132
137
|
.map((item) => item.value);
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
const value = this.isMultiple ? values : values[0] || '';
|
|
139
|
+
this.setValue(value);
|
|
140
|
+
if (!this.isInitial) {
|
|
135
141
|
emit(this, 'change');
|
|
136
142
|
}
|
|
137
|
-
else {
|
|
138
|
-
this.hasSetDefaultValue = true;
|
|
139
|
-
}
|
|
140
143
|
}
|
|
141
144
|
async onValueChange() {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
await this.updateComplete;
|
|
145
|
-
}
|
|
145
|
+
this.isInitial = !this.hasUpdated;
|
|
146
|
+
await this.definedController.whenDefined();
|
|
146
147
|
// 根据 value 找出对应的 segmented-button,并把这些元素的 key 赋值给 selectedKeys
|
|
147
148
|
if (!this.isSelectable) {
|
|
148
|
-
this.
|
|
149
|
+
this.updateItems();
|
|
149
150
|
return;
|
|
150
151
|
}
|
|
151
152
|
const values = (this.isSingle
|
|
@@ -155,24 +156,33 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
155
156
|
? [this.value]
|
|
156
157
|
: this.value).filter((i) => i);
|
|
157
158
|
if (!values.length) {
|
|
158
|
-
this.
|
|
159
|
+
this.setSelectedKeys([]);
|
|
159
160
|
}
|
|
160
161
|
else if (this.isSingle) {
|
|
161
162
|
const firstItem = this.itemsEnabled.find((item) => item.value === values[0]);
|
|
162
|
-
this.
|
|
163
|
+
this.setSelectedKeys(firstItem ? [firstItem.key] : []);
|
|
163
164
|
}
|
|
164
165
|
else if (this.isMultiple) {
|
|
165
|
-
this.
|
|
166
|
+
this.setSelectedKeys(this.itemsEnabled
|
|
166
167
|
.filter((item) => values.includes(item.value))
|
|
167
|
-
.map((item) => item.key);
|
|
168
|
+
.map((item) => item.key));
|
|
169
|
+
}
|
|
170
|
+
this.updateItems();
|
|
171
|
+
// reset 引起的值变更,不执行验证;直接修改值引起的变更,需要进行验证
|
|
172
|
+
if (!this.isInitial) {
|
|
173
|
+
const form = this.formController.getForm();
|
|
174
|
+
if (form && formResets.get(form)?.has(this)) {
|
|
175
|
+
this.invalid = false;
|
|
176
|
+
formResets.get(form).delete(this);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.invalid = !this.inputRef.value.checkValidity();
|
|
180
|
+
}
|
|
168
181
|
}
|
|
169
|
-
this.updateSelected(hasUpdated);
|
|
170
|
-
}
|
|
171
|
-
onInvalidChange() {
|
|
172
|
-
this.itemsEnabled.forEach((item) => (item.invalid = this.invalid));
|
|
173
182
|
}
|
|
174
|
-
|
|
175
|
-
this.
|
|
183
|
+
async onInvalidChange() {
|
|
184
|
+
await this.definedController.whenDefined();
|
|
185
|
+
this.updateItems();
|
|
176
186
|
}
|
|
177
187
|
connectedCallback() {
|
|
178
188
|
super.connectedCallback();
|
|
@@ -231,22 +241,6 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
231
241
|
render() {
|
|
232
242
|
return html `${when(this.isSelectable && this.isSingle, () => html `<input ${ref(this.inputRef)} type="radio" name="${ifDefined(this.name)}" value="1" .disabled="${this.disabled}" .required="${this.required}" .checked="${!!this.value}" tabindex="-1" @keydown="${this.onInputKeyDown}">`)}${when(this.isSelectable && this.isMultiple, () => html `<select ${ref(this.inputRef)} name="${ifDefined(this.name)}" .disabled="${this.disabled}" .required="${this.required}" multiple="multiple" tabindex="-1" @keydown="${this.onInputKeyDown}">${map(this.value, (value) => html `<option selected="selected" value="${value}"></option>`)}</select>`)}<slot @slotchange="${this.onSlotChange}" @click="${this.onClick}"></slot>`;
|
|
233
243
|
}
|
|
234
|
-
async updateSelected(hasUpdated) {
|
|
235
|
-
var _a;
|
|
236
|
-
this.items.forEach((item) => (item.selected = this.selectedKeys.includes(item.key)));
|
|
237
|
-
if (hasUpdated) {
|
|
238
|
-
await this.updateComplete;
|
|
239
|
-
// reset 引起的值变更,不执行验证;直接修改值引起的变更,需要进行验证
|
|
240
|
-
const form = this.formController.getForm();
|
|
241
|
-
if (form && ((_a = formResets.get(form)) === null || _a === void 0 ? void 0 : _a.has(this))) {
|
|
242
|
-
this.invalid = false;
|
|
243
|
-
formResets.get(form).delete(this);
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
this.invalid = !this.inputRef.value.checkValidity();
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
244
|
// 切换一个元素的选中状态
|
|
251
245
|
selectOne(item) {
|
|
252
246
|
if (this.isMultiple) {
|
|
@@ -258,23 +252,25 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
258
252
|
else {
|
|
259
253
|
selectedKeys.push(item.key);
|
|
260
254
|
}
|
|
261
|
-
this.selectedKeys
|
|
255
|
+
this.setSelectedKeys(selectedKeys);
|
|
262
256
|
}
|
|
263
257
|
if (this.isSingle) {
|
|
264
258
|
if (this.selectedKeys.includes(item.key)) {
|
|
265
|
-
this.
|
|
259
|
+
this.setSelectedKeys([]);
|
|
266
260
|
}
|
|
267
261
|
else {
|
|
268
|
-
this.
|
|
262
|
+
this.setSelectedKeys([item.key]);
|
|
269
263
|
}
|
|
270
264
|
}
|
|
271
|
-
this.
|
|
265
|
+
this.isInitial = false;
|
|
266
|
+
this.updateItems();
|
|
272
267
|
}
|
|
273
|
-
onClick(event) {
|
|
268
|
+
async onClick(event) {
|
|
274
269
|
// event.button 为 0 时,为鼠标左键点击。忽略鼠标中间和右键
|
|
275
270
|
if (event.button) {
|
|
276
271
|
return;
|
|
277
272
|
}
|
|
273
|
+
await this.definedController.whenDefined();
|
|
278
274
|
const target = event.target;
|
|
279
275
|
const item = target.closest('mdui-segmented-button');
|
|
280
276
|
if (item.disabled) {
|
|
@@ -286,12 +282,14 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
286
282
|
}
|
|
287
283
|
/**
|
|
288
284
|
* 在隐藏的 `<input>` 或 `<select>` 上按下按键时,切换选中状态
|
|
285
|
+
* 通常为验证不通过时,默认聚焦到 `<input>` 或 `<select>` 上,此时按下按键,切换第一个元素的选中状态
|
|
289
286
|
*/
|
|
290
|
-
onInputKeyDown(event) {
|
|
287
|
+
async onInputKeyDown(event) {
|
|
291
288
|
if (!['Enter', ' '].includes(event.key)) {
|
|
292
289
|
return;
|
|
293
290
|
}
|
|
294
291
|
event.preventDefault();
|
|
292
|
+
await this.definedController.whenDefined();
|
|
295
293
|
if (this.isSingle) {
|
|
296
294
|
const input = event.target;
|
|
297
295
|
input.checked = !input.checked;
|
|
@@ -303,11 +301,33 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
303
301
|
this.itemsEnabled[0].focus();
|
|
304
302
|
}
|
|
305
303
|
}
|
|
306
|
-
onSlotChange() {
|
|
304
|
+
async onSlotChange() {
|
|
305
|
+
await this.definedController.whenDefined();
|
|
306
|
+
this.updateItems(true);
|
|
307
|
+
}
|
|
308
|
+
setSelectedKeys(selectedKeys) {
|
|
309
|
+
if (!arraysEqualIgnoreOrder(this.selectedKeys, selectedKeys)) {
|
|
310
|
+
this.selectedKeys = selectedKeys;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
setValue(value) {
|
|
314
|
+
if (this.isSingle) {
|
|
315
|
+
this.value = value;
|
|
316
|
+
}
|
|
317
|
+
else if (!arraysEqualIgnoreOrder(this.value, value)) {
|
|
318
|
+
this.value = value;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
updateItems(slotChange = false) {
|
|
307
322
|
const items = this.items;
|
|
308
323
|
items.forEach((item, index) => {
|
|
309
|
-
item.
|
|
310
|
-
item.
|
|
324
|
+
item.invalid = this.invalid;
|
|
325
|
+
item.groupDisabled = this.disabled;
|
|
326
|
+
item.selected = this.selectedKeys.includes(item.key);
|
|
327
|
+
if (slotChange) {
|
|
328
|
+
item.classList.toggle('mdui-segmented-button-first', index === 0);
|
|
329
|
+
item.classList.toggle('mdui-segmented-button-last', index === items.length - 1);
|
|
330
|
+
}
|
|
311
331
|
});
|
|
312
332
|
}
|
|
313
333
|
};
|
|
@@ -357,14 +377,10 @@ __decorate([
|
|
|
357
377
|
state()
|
|
358
378
|
], SegmentedButtonGroup.prototype, "selectedKeys", void 0);
|
|
359
379
|
__decorate([
|
|
360
|
-
|
|
361
|
-
type: Boolean,
|
|
362
|
-
reflect: true,
|
|
363
|
-
converter: booleanConverter,
|
|
364
|
-
})
|
|
380
|
+
state()
|
|
365
381
|
], SegmentedButtonGroup.prototype, "invalid", void 0);
|
|
366
382
|
__decorate([
|
|
367
|
-
watch('selects')
|
|
383
|
+
watch('selects', true)
|
|
368
384
|
], SegmentedButtonGroup.prototype, "onSelectsChange", null);
|
|
369
385
|
__decorate([
|
|
370
386
|
watch('selectedKeys', true)
|
|
@@ -373,11 +389,10 @@ __decorate([
|
|
|
373
389
|
watch('value')
|
|
374
390
|
], SegmentedButtonGroup.prototype, "onValueChange", null);
|
|
375
391
|
__decorate([
|
|
376
|
-
watch('invalid')
|
|
377
|
-
], SegmentedButtonGroup.prototype, "onInvalidChange", null);
|
|
378
|
-
__decorate([
|
|
392
|
+
watch('invalid', true),
|
|
379
393
|
watch('disabled')
|
|
380
|
-
], SegmentedButtonGroup.prototype, "
|
|
394
|
+
], SegmentedButtonGroup.prototype, "onInvalidChange", null);
|
|
381
395
|
SegmentedButtonGroup = __decorate([
|
|
382
396
|
customElement('mdui-segmented-button-group')
|
|
383
397
|
], SegmentedButtonGroup);
|
|
398
|
+
export { SegmentedButtonGroup };
|
|
@@ -45,11 +45,11 @@ export declare class SegmentedButton extends ButtonBase {
|
|
|
45
45
|
*/
|
|
46
46
|
selectedIcon?: string;
|
|
47
47
|
/**
|
|
48
|
-
* 是否选中该分段按钮项,由 mdui-segmented-button-group 组件控制该参数
|
|
48
|
+
* 是否选中该分段按钮项,由 <mdui-segmented-button-group> 组件控制该参数
|
|
49
49
|
*/
|
|
50
50
|
protected selected: boolean;
|
|
51
51
|
/**
|
|
52
|
-
* 是否验证未通过。由 mdui-segmented-button-group 控制该参数
|
|
52
|
+
* 是否验证未通过。由 <mdui-segmented-button-group> 控制该参数
|
|
53
53
|
*/
|
|
54
54
|
protected invalid: boolean;
|
|
55
55
|
protected groupDisabled: boolean;
|
|
@@ -38,18 +38,18 @@ import { segmentedButtonStyle } from './segmented-button-style.js';
|
|
|
38
38
|
* @csspart label - 文本内容
|
|
39
39
|
* @csspart loading - 加载中状态的 `<mdui-circular-progress>` 元素
|
|
40
40
|
*/
|
|
41
|
-
|
|
41
|
+
let SegmentedButton = class SegmentedButton extends ButtonBase {
|
|
42
42
|
constructor() {
|
|
43
43
|
super(...arguments);
|
|
44
44
|
/**
|
|
45
|
-
* 是否选中该分段按钮项,由 mdui-segmented-button-group 组件控制该参数
|
|
45
|
+
* 是否选中该分段按钮项,由 <mdui-segmented-button-group> 组件控制该参数
|
|
46
46
|
*/
|
|
47
47
|
this.selected = false;
|
|
48
48
|
/**
|
|
49
|
-
* 是否验证未通过。由 mdui-segmented-button-group 控制该参数
|
|
49
|
+
* 是否验证未通过。由 <mdui-segmented-button-group> 控制该参数
|
|
50
50
|
*/
|
|
51
51
|
this.invalid = false;
|
|
52
|
-
// 父组件中是否设置了禁用。由 mdui-
|
|
52
|
+
// 父组件中是否设置了禁用。由 <mdui-segmented-button-group> 控制该参数
|
|
53
53
|
this.groupDisabled = false;
|
|
54
54
|
// 每一个 segmented-button 元素都添加一个唯一的 key
|
|
55
55
|
this.key = uniqueId();
|
|
@@ -158,3 +158,4 @@ __decorate([
|
|
|
158
158
|
SegmentedButton = __decorate([
|
|
159
159
|
customElement('mdui-segmented-button')
|
|
160
160
|
], SegmentedButton);
|
|
161
|
+
export { SegmentedButton };
|
|
@@ -4,7 +4,7 @@ import '../dropdown.js';
|
|
|
4
4
|
import '../menu.js';
|
|
5
5
|
import '../text-field.js';
|
|
6
6
|
import type { FormControl } from '@mdui/jq/shared/form.js';
|
|
7
|
-
import type { CSSResultGroup, TemplateResult
|
|
7
|
+
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
8
8
|
declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@mdui/shared/mixins/focusable.js").FocusableMixinInterface> & typeof LitElement;
|
|
9
9
|
/**
|
|
10
10
|
* @summary 选择框组件。需与 `<mdui-menu-item>` 组件配合使用
|
|
@@ -36,7 +36,6 @@ declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@
|
|
|
36
36
|
* @csspart menu - 下拉菜单,即 [`<mdui-menu>`](/docs/2/components/menu) 元素
|
|
37
37
|
*/
|
|
38
38
|
export declare class Select extends Select_base implements FormControl {
|
|
39
|
-
static enabledWarnings: WarningKind[];
|
|
40
39
|
static styles: CSSResultGroup;
|
|
41
40
|
/**
|
|
42
41
|
* 下拉框形状。可选值为:
|
|
@@ -147,6 +146,7 @@ export declare class Select extends Select_base implements FormControl {
|
|
|
147
146
|
private readonly hiddenInputRef;
|
|
148
147
|
private readonly formController;
|
|
149
148
|
private readonly hasSlotController;
|
|
149
|
+
private readonly definedController;
|
|
150
150
|
/**
|
|
151
151
|
* 表单验证状态对象
|
|
152
152
|
*/
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { html, LitElement, nothing } from 'lit';
|
|
3
|
-
import { customElement, property, queryAssignedElements, } from 'lit/decorators.js';
|
|
3
|
+
import { customElement, property, queryAssignedElements, state, } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { map } from 'lit/directives/map.js';
|
|
6
6
|
import { createRef, ref } from 'lit/directives/ref.js';
|
|
7
7
|
import { when } from 'lit/directives/when.js';
|
|
8
8
|
import { isString } from '@mdui/jq/shared/helper.js';
|
|
9
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
9
10
|
import { FormController, formResets } from '@mdui/shared/controllers/form.js';
|
|
10
11
|
import { HasSlotController } from '@mdui/shared/controllers/has-slot.js';
|
|
11
12
|
import { defaultValue } from '@mdui/shared/decorators/default-value.js';
|
|
@@ -48,7 +49,7 @@ import { style } from './style.js';
|
|
|
48
49
|
* @csspart text-field - 文本框,即 [`<mdui-text-field>`](/docs/2/components/text-field) 元素
|
|
49
50
|
* @csspart menu - 下拉菜单,即 [`<mdui-menu>`](/docs/2/components/menu) 元素
|
|
50
51
|
*/
|
|
51
|
-
|
|
52
|
+
let Select = class Select extends FocusableMixin(LitElement) {
|
|
52
53
|
constructor() {
|
|
53
54
|
super(...arguments);
|
|
54
55
|
/**
|
|
@@ -116,6 +117,9 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
116
117
|
this.hiddenInputRef = createRef();
|
|
117
118
|
this.formController = new FormController(this);
|
|
118
119
|
this.hasSlotController = new HasSlotController(this, 'icon', 'end-icon', 'error-icon', 'prefix', 'suffix', 'clear-button', 'clear-icon', 'helper');
|
|
120
|
+
this.definedController = new DefinedController(this, {
|
|
121
|
+
relatedElements: ['mdui-menu-item'],
|
|
122
|
+
});
|
|
119
123
|
}
|
|
120
124
|
/**
|
|
121
125
|
* 表单验证状态对象
|
|
@@ -144,14 +148,15 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
144
148
|
: []
|
|
145
149
|
: this.value;
|
|
146
150
|
this.defaultValue = this.multiple ? [] : '';
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
// 首次渲染时,slot 中的 mdui-menu-item 还未渲染完成,无法读取到其中的文本值
|
|
152
|
+
// 所以需要在首次更新后,再次重新渲染,此时 mdui-menu-item 已渲染完成,可以读取到文本值
|
|
153
|
+
this.definedController.whenDefined().then(() => {
|
|
154
|
+
this.requestUpdate();
|
|
149
155
|
});
|
|
150
156
|
}
|
|
151
157
|
disconnectedCallback() {
|
|
152
|
-
var _a;
|
|
153
158
|
super.disconnectedCallback();
|
|
154
|
-
|
|
159
|
+
this.observeResize?.unobserve();
|
|
155
160
|
}
|
|
156
161
|
/**
|
|
157
162
|
* 检查表单字段是否验证通过。若未通过则返回 `false`,并触发 `invalid` 事件;若验证通过,则返回 `true`
|
|
@@ -195,12 +200,9 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
195
200
|
}
|
|
196
201
|
firstUpdated(changedProperties) {
|
|
197
202
|
super.firstUpdated(changedProperties);
|
|
198
|
-
|
|
199
|
-
// 所以需要在首次更新后,再次重新渲染,此时 mdui-menu-item 已渲染完成,可以读取到文本值
|
|
200
|
-
this.requestUpdate();
|
|
203
|
+
this.observeResize = observeResize(this.textFieldRef.value, () => this.resizeMenu());
|
|
201
204
|
}
|
|
202
205
|
render() {
|
|
203
|
-
var _a;
|
|
204
206
|
const hasSelection = this.multiple ? !!this.value.length : !!this.value;
|
|
205
207
|
return html `${this.multiple
|
|
206
208
|
? html `<select ${ref(this.hiddenInputRef)} class="hidden-input" name="${ifDefined(this.name)}" value="${ifDefined(this.value)}" .required="${this.required}" .disabled="${this.disabled}" multiple="multiple" tabindex="-1">${map(this.value, (value) => html `<option selected="selected" value="${value}"></option>`)}</select>`
|
|
@@ -212,7 +214,7 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
212
214
|
? this.value.length
|
|
213
215
|
? ' '
|
|
214
216
|
: ''
|
|
215
|
-
: this.getMenuItemLabelByValue(this.value)}" .label="${this.label}" .placeholder="${this.placeholder}" .helper="${this.helper}" .error="${
|
|
217
|
+
: this.getMenuItemLabelByValue(this.value)}" .label="${this.label}" .placeholder="${this.placeholder}" .helper="${this.helper}" .error="${this.hiddenInputRef.value?.validationMessage}" .clearable="${this.clearable}" .clearIcon="${this.clearIcon}" .endAligned="${this.endAligned}" .prefix="${this.prefix}" .suffix="${this.suffix}" .icon="${this.icon}" .endIcon="${this.endIcon}" .errorIcon="${this.errorIcon}" .form="${this.form}" .disabled="${this.disabled}" .required="${this.required}" .invalidStyle="${this.invalid}" @clear="${this.onClear}" @change="${(e) => e.stopPropagation()}" @keydown="${this.onTextFieldKeyDown}">${map([
|
|
216
218
|
'icon',
|
|
217
219
|
'end-icon',
|
|
218
220
|
'error-icon',
|
|
@@ -226,11 +228,10 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
226
228
|
: nothing)} ${when(this.multiple && this.value.length, () => html `<div slot="input" class="chips">${map(this.value, (valueItem) => html `<mdui-chip class="chip" variant="input" deletable tabindex="-1" @delete="${() => this.onDeleteOneValue(valueItem)}">${this.getMenuItemLabelByValue(valueItem)}</mdui-chip>`)}</div>`)}</mdui-text-field><mdui-menu ${ref(this.menuRef)} part="menu" .selects="${this.multiple ? 'multiple' : 'single'}" .value="${this.value}" @change="${this.onValueChange}"><slot></slot></mdui-menu></mdui-dropdown>`;
|
|
227
229
|
}
|
|
228
230
|
getMenuItemLabelByValue(valueItem) {
|
|
229
|
-
var _a;
|
|
230
231
|
if (!this.menuItems.length) {
|
|
231
232
|
return valueItem;
|
|
232
233
|
}
|
|
233
|
-
return (
|
|
234
|
+
return (this.menuItems.find((item) => item.value === valueItem)?.textContent ||
|
|
234
235
|
valueItem);
|
|
235
236
|
}
|
|
236
237
|
resizeMenu() {
|
|
@@ -243,17 +244,23 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
243
244
|
onDropdownClose() {
|
|
244
245
|
// @ts-ignore
|
|
245
246
|
this.textFieldRef.value.focusedStyle = false;
|
|
247
|
+
// 如果焦点在 <mdui-select> 组件内的元素上,则焦点回到 <mdui-select> 上
|
|
248
|
+
if (this.contains(document.activeElement) ||
|
|
249
|
+
this.contains(document.activeElement?.assignedSlot ?? null)) {
|
|
250
|
+
setTimeout(() => {
|
|
251
|
+
this.focus();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
246
254
|
}
|
|
247
255
|
async onValueChange(e) {
|
|
248
|
-
var _a, _b;
|
|
249
256
|
const menu = e.target;
|
|
250
257
|
this.value = this.multiple
|
|
251
|
-
? menu.value.map((v) => v
|
|
252
|
-
:
|
|
258
|
+
? menu.value.map((v) => v ?? '')
|
|
259
|
+
: menu.value ?? '';
|
|
253
260
|
await this.updateComplete;
|
|
254
261
|
// reset 引起的值变更,不执行验证;直接修改值引起的变更,需要进行验证
|
|
255
262
|
const form = this.formController.getForm();
|
|
256
|
-
if (form &&
|
|
263
|
+
if (form && formResets.get(form)?.has(this)) {
|
|
257
264
|
this.invalid = false;
|
|
258
265
|
formResets.get(form).delete(this);
|
|
259
266
|
}
|
|
@@ -284,8 +291,6 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
284
291
|
}
|
|
285
292
|
}
|
|
286
293
|
};
|
|
287
|
-
// firstUpdated 中调用了 requestUpdate,会产生控制台警告,所以这里关闭 change-in-update 警告
|
|
288
|
-
Select.enabledWarnings = ['migration'];
|
|
289
294
|
Select.styles = [componentStyle, style];
|
|
290
295
|
__decorate([
|
|
291
296
|
property({ reflect: true })
|
|
@@ -376,11 +381,7 @@ __decorate([
|
|
|
376
381
|
})
|
|
377
382
|
], Select.prototype, "required", void 0);
|
|
378
383
|
__decorate([
|
|
379
|
-
|
|
380
|
-
type: Boolean,
|
|
381
|
-
reflect: true,
|
|
382
|
-
converter: booleanConverter,
|
|
383
|
-
})
|
|
384
|
+
state()
|
|
384
385
|
], Select.prototype, "invalid", void 0);
|
|
385
386
|
__decorate([
|
|
386
387
|
queryAssignedElements({ flatten: true, selector: 'mdui-menu-item' })
|
|
@@ -388,3 +389,4 @@ __decorate([
|
|
|
388
389
|
Select = __decorate([
|
|
389
390
|
customElement('mdui-select')
|
|
390
391
|
], Select);
|
|
392
|
+
export { Select };
|
|
@@ -10,7 +10,6 @@ import { when } from 'lit/directives/when.js';
|
|
|
10
10
|
import { FormController, formResets } from '@mdui/shared/controllers/form.js';
|
|
11
11
|
import { defaultValue } from '@mdui/shared/decorators/default-value.js';
|
|
12
12
|
import { watch } from '@mdui/shared/decorators/watch.js';
|
|
13
|
-
import { emit } from '@mdui/shared/helpers/event.js';
|
|
14
13
|
import { SliderBase } from './slider-base.js';
|
|
15
14
|
import { style } from './style.js';
|
|
16
15
|
/**
|
|
@@ -32,7 +31,7 @@ import { style } from './style.js';
|
|
|
32
31
|
* @csspart label 提示文本
|
|
33
32
|
* @csspart tickmark - 刻度标记
|
|
34
33
|
*/
|
|
35
|
-
|
|
34
|
+
let Slider = class Slider extends SliderBase {
|
|
36
35
|
constructor() {
|
|
37
36
|
super(...arguments);
|
|
38
37
|
/**
|
|
@@ -51,10 +50,9 @@ export let Slider = class Slider extends SliderBase {
|
|
|
51
50
|
return this.rippleRef.value;
|
|
52
51
|
}
|
|
53
52
|
onValueChange() {
|
|
54
|
-
var _a;
|
|
55
53
|
// reset 引起的值变更,不执行验证;直接修改值引起的变更,需要进行验证
|
|
56
54
|
const form = this.formController.getForm();
|
|
57
|
-
if (form &&
|
|
55
|
+
if (form && formResets.get(form)?.has(this)) {
|
|
58
56
|
this.invalid = false;
|
|
59
57
|
formResets.get(form).delete(this);
|
|
60
58
|
}
|
|
@@ -73,6 +71,9 @@ export let Slider = class Slider extends SliderBase {
|
|
|
73
71
|
if (this.value > this.max) {
|
|
74
72
|
this.value = this.max;
|
|
75
73
|
}
|
|
74
|
+
}
|
|
75
|
+
firstUpdated(changedProperties) {
|
|
76
|
+
super.firstUpdated(changedProperties);
|
|
76
77
|
const onTouchStart = () => {
|
|
77
78
|
if (!this.disabled) {
|
|
78
79
|
this.labelVisible = true;
|
|
@@ -87,9 +88,6 @@ export let Slider = class Slider extends SliderBase {
|
|
|
87
88
|
this.addEventListener('mousedown', onTouchStart);
|
|
88
89
|
this.addEventListener('touchend', onTouchEnd);
|
|
89
90
|
this.addEventListener('mouseup', onTouchEnd);
|
|
90
|
-
}
|
|
91
|
-
firstUpdated(changedProperties) {
|
|
92
|
-
super.firstUpdated(changedProperties);
|
|
93
91
|
this.updateStyle();
|
|
94
92
|
}
|
|
95
93
|
/**
|
|
@@ -97,7 +95,7 @@ export let Slider = class Slider extends SliderBase {
|
|
|
97
95
|
* <input class="invalid" /> 用于提供 html5 自带的表单错误提示
|
|
98
96
|
*/
|
|
99
97
|
render() {
|
|
100
|
-
return html `<label><input ${ref(this.inputRef)} type="range" step="${this.step}" min="${this.min}" max="${this.max}" ?disabled="${this.disabled}" .value="${live(this.value.toString())}" @input="${this.onInput}" @change="${this.onChange}"><div part="track-inactive" class="track-inactive"></div><div ${ref(this.trackActiveRef)} part="track-active" class="track-active"></div><div ${ref(this.handleRef)} part="handle" class="handle"><div class="elevation"></div><mdui-ripple ${ref(this.rippleRef)} .noRipple="${this.noRipple}"></mdui-ripple>${this.renderLabel(this.value)}</div>${when(this.tickmarks, () => map(this.getCandidateValues(), (value) => html `<div part="tickmark" class="tickmark ${classMap({ active: value < this.value })}" style="${styleMap({
|
|
98
|
+
return html `<label class="${classMap({ invalid: this.invalid })}"><input ${ref(this.inputRef)} type="range" step="${this.step}" min="${this.min}" max="${this.max}" ?disabled="${this.disabled}" .value="${live(this.value.toString())}" @input="${this.onInput}" @change="${this.onChange}"><div part="track-inactive" class="track-inactive"></div><div ${ref(this.trackActiveRef)} part="track-active" class="track-active"></div><div ${ref(this.handleRef)} part="handle" class="handle"><div class="elevation"></div><mdui-ripple ${ref(this.rippleRef)} .noRipple="${this.noRipple}"></mdui-ripple>${this.renderLabel(this.value)}</div>${when(this.tickmarks, () => map(this.getCandidateValues(), (value) => html `<div part="tickmark" class="tickmark ${classMap({ active: value < this.value })}" style="${styleMap({
|
|
101
99
|
left: `${((value - this.min) / this.max) * 100}%`,
|
|
102
100
|
display: value === this.value ? 'none' : 'block',
|
|
103
101
|
})}"></div>`))}</label>`;
|
|
@@ -109,7 +107,6 @@ export let Slider = class Slider extends SliderBase {
|
|
|
109
107
|
}
|
|
110
108
|
onInput() {
|
|
111
109
|
this.value = parseFloat(this.inputRef.value.value);
|
|
112
|
-
emit(this, 'input');
|
|
113
110
|
this.updateStyle();
|
|
114
111
|
}
|
|
115
112
|
};
|
|
@@ -126,3 +123,4 @@ __decorate([
|
|
|
126
123
|
Slider = __decorate([
|
|
127
124
|
customElement('mdui-slider')
|
|
128
125
|
], Slider);
|
|
126
|
+
export { Slider };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const sliderBaseStyle = css `:host{position:relative;display:block;width:100%;-webkit-tap-highlight-color:transparent;height:2.5rem;padding:0 1.25rem}label{position:relative;display:block;width:100%;height:100%}input[type=range]{position:absolute;inset:0;z-index:4;height:100%;cursor:pointer;opacity:0;-webkit-appearance:none;appearance:none;margin:0 -1.25rem;padding:0 .75rem}:host([disabled]) input[type=range]{cursor:not-allowed}.track-active,.track-inactive{position:absolute;top:50%;height:.25rem;margin-top:-.125rem}.track-inactive{left:-.125rem;right:-.125rem;border-radius:var(--mdui-shape-corner-full);background-color:rgb(var(--mdui-color-surface-container-highest))}
|
|
2
|
+
export const sliderBaseStyle = css `:host{position:relative;display:block;width:100%;-webkit-tap-highlight-color:transparent;height:2.5rem;padding:0 1.25rem}label{position:relative;display:block;width:100%;height:100%}input[type=range]{position:absolute;inset:0;z-index:4;height:100%;cursor:pointer;opacity:0;-webkit-appearance:none;appearance:none;width:calc(100% + 20rem * 2 / 16);margin:0 -1.25rem;padding:0 .75rem}:host([disabled]) input[type=range]{cursor:not-allowed}.track-active,.track-inactive{position:absolute;top:50%;height:.25rem;margin-top:-.125rem}.track-inactive{left:-.125rem;right:-.125rem;border-radius:var(--mdui-shape-corner-full);background-color:rgb(var(--mdui-color-surface-container-highest))}.invalid .track-inactive{background-color:rgba(var(--mdui-color-error),.12)}:host([disabled]) .track-inactive{background-color:rgba(var(--mdui-color-on-surface),.12)}.track-active{background-color:rgb(var(--mdui-color-primary))}.invalid .track-active{background-color:rgb(var(--mdui-color-error))}:host([disabled]) .track-active{background-color:rgba(var(--mdui-color-on-surface),.38)}.handle{position:absolute;top:50%;transform:translate(-50%);cursor:pointer;z-index:2;width:2.5rem;height:2.5rem;margin-top:-1.25rem;--mdui-comp-ripple-state-layer-color:var(--mdui-color-primary)}.invalid .handle{--mdui-comp-ripple-state-layer-color:var(--mdui-color-error)}.handle .elevation,.handle::before{position:absolute;display:block;content:' ';left:.625rem;top:.625rem;width:1.25rem;height:1.25rem;border-radius:var(--mdui-shape-corner-full)}.handle .elevation{background-color:rgb(var(--mdui-color-primary));box-shadow:var(--mdui-elevation-level1)}.invalid .handle .elevation{background-color:rgb(var(--mdui-color-error))}:host([disabled]) .handle .elevation{background-color:rgba(var(--mdui-color-on-surface),.38);box-shadow:var(--mdui-elevation-level0)}.handle::before{background-color:rgb(var(--mdui-color-background))}.handle mdui-ripple{border-radius:var(--mdui-shape-corner-full)}.label{position:absolute;left:50%;transform:translateX(-50%) scale(0);transform-origin:center bottom;display:flex;align-items:center;justify-content:center;cursor:default;white-space:nowrap;-webkit-user-select:none;user-select:none;pointer-events:none;transition:transform var(--mdui-motion-duration-short2) var(--mdui-motion-easing-standard);bottom:2.5rem;min-width:1.75rem;height:1.75rem;padding:.375rem .5rem;border-radius:var(--mdui-shape-corner-full);color:rgb(var(--mdui-color-on-primary));font-size:var(--mdui-typescale-label-medium-size);font-weight:var(--mdui-typescale-label-medium-weight);letter-spacing:var(--mdui-typescale-label-medium-tracking);line-height:var(--mdui-typescale-label-medium-line-height);background-color:rgb(var(--mdui-color-primary))}.invalid .label{color:rgb(var(--mdui-color-on-error));background-color:rgb(var(--mdui-color-error))}.label::after{content:' ';position:absolute;z-index:-1;transform:rotate(45deg);width:.875rem;height:.875rem;bottom:-.125rem;background-color:rgb(var(--mdui-color-primary))}.invalid .label::after{background-color:rgb(var(--mdui-color-error))}.label-visible{transform:translateX(-50%) scale(1);transition:transform var(--mdui-motion-duration-short4) var(--mdui-motion-easing-standard)}.tickmark{position:absolute;top:50%;transform:translate(-50%);width:.125rem;height:.125rem;margin-top:-.0625rem;border-radius:var(--mdui-shape-corner-full);background-color:rgba(var(--mdui-color-on-surface-variant),.38)}.invalid .tickmark{background-color:rgba(var(--mdui-color-error),.38)}.tickmark.active{background-color:rgba(var(--mdui-color-on-primary),.38)}.invalid .tickmark.active{background-color:rgba(var(--mdui-color-on-error),.38)}:host([disabled]) .tickmark{background-color:rgba(var(--mdui-color-on-surface),.38)}`;
|
|
@@ -182,11 +182,7 @@ __decorate([
|
|
|
182
182
|
property({ reflect: true })
|
|
183
183
|
], SliderBase.prototype, "name", void 0);
|
|
184
184
|
__decorate([
|
|
185
|
-
|
|
186
|
-
type: Boolean,
|
|
187
|
-
reflect: true,
|
|
188
|
-
converter: booleanConverter,
|
|
189
|
-
})
|
|
185
|
+
state()
|
|
190
186
|
], SliderBase.prototype, "invalid", void 0);
|
|
191
187
|
__decorate([
|
|
192
188
|
state()
|
|
@@ -41,7 +41,7 @@ import { style } from './style.js';
|
|
|
41
41
|
* @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
42
42
|
* @cssprop --z-index - 组件的 CSS 的 `z-index` 值
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
let Snackbar = class Snackbar extends LitElement {
|
|
45
45
|
constructor() {
|
|
46
46
|
super();
|
|
47
47
|
/**
|
|
@@ -283,3 +283,4 @@ __decorate([
|
|
|
283
283
|
Snackbar = __decorate([
|
|
284
284
|
customElement('mdui-snackbar')
|
|
285
285
|
], Snackbar);
|
|
286
|
+
export { Snackbar };
|