mdui 2.0.1 → 2.0.3
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/LICENSE +21 -21
- package/components/avatar/index.d.ts +4 -2
- package/components/avatar/index.js +4 -2
- package/components/badge/index.d.ts +4 -2
- package/components/badge/index.js +4 -2
- package/components/bottom-app-bar/index.d.ts +9 -3
- package/components/bottom-app-bar/index.js +9 -9
- package/components/button/button-base.d.ts +5 -5
- package/components/button/button-base.js +22 -19
- package/components/button/index.d.ts +6 -1
- package/components/button/index.js +2 -1
- package/components/button-icon/index.d.ts +7 -1
- package/components/button-icon/index.js +3 -3
- package/components/card/index.d.ts +8 -4
- package/components/card/index.js +7 -3
- package/components/checkbox/index.d.ts +10 -3
- package/components/checkbox/index.js +13 -16
- package/components/checkbox/style.js +1 -1
- package/components/chip/index.d.ts +8 -1
- package/components/chip/index.js +5 -5
- package/components/circular-progress/index.d.ts +4 -2
- package/components/circular-progress/index.js +5 -4
- package/components/collapse/collapse-item-style.js +1 -1
- package/components/collapse/collapse-item.d.ts +15 -3
- package/components/collapse/collapse-item.js +26 -23
- package/components/collapse/collapse.d.ts +16 -8
- package/components/collapse/collapse.js +61 -38
- package/components/dialog/index.d.ts +12 -4
- package/components/dialog/index.js +36 -36
- package/components/divider/index.d.ts +4 -2
- package/components/divider/index.js +4 -2
- package/components/dropdown/index.d.ts +13 -7
- package/components/dropdown/index.js +70 -63
- package/components/fab/index.d.ts +7 -1
- package/components/fab/index.js +10 -5
- package/components/icon/index.d.ts +4 -2
- package/components/icon/index.js +4 -2
- package/components/layout/helper.d.ts +5 -6
- package/components/layout/helper.js +42 -48
- package/components/layout/layout-item-base.d.ts +3 -2
- package/components/layout/layout-item-base.js +3 -4
- package/components/layout/layout-item.d.ts +4 -3
- package/components/layout/layout-item.js +3 -3
- package/components/layout/layout-main.d.ts +4 -2
- package/components/layout/layout-main.js +4 -2
- package/components/layout/layout.d.ts +4 -2
- package/components/layout/layout.js +4 -2
- package/components/linear-progress/index.d.ts +4 -2
- package/components/linear-progress/index.js +5 -4
- package/components/list/list-item-style.js +1 -1
- package/components/list/list-item.d.ts +7 -3
- package/components/list/list-item.js +5 -3
- package/components/list/list-subheader.d.ts +4 -2
- package/components/list/list-subheader.js +4 -2
- package/components/list/list.d.ts +4 -2
- package/components/list/list.js +4 -2
- package/components/menu/menu-item.d.ts +12 -3
- package/components/menu/menu-item.js +53 -40
- package/components/menu/menu.d.ts +9 -3
- package/components/menu/menu.js +85 -59
- package/components/navigation-bar/navigation-bar-item-style.js +1 -1
- package/components/navigation-bar/navigation-bar-item.d.ts +13 -5
- package/components/navigation-bar/navigation-bar-item.js +28 -11
- package/components/navigation-bar/navigation-bar.d.ts +14 -7
- package/components/navigation-bar/navigation-bar.js +58 -49
- package/components/navigation-drawer/index.d.ts +13 -2
- package/components/navigation-drawer/index.js +69 -49
- package/components/navigation-drawer/style.js +1 -1
- package/components/navigation-rail/navigation-rail-item-style.js +1 -1
- package/components/navigation-rail/navigation-rail-item.d.ts +13 -5
- package/components/navigation-rail/navigation-rail-item.js +22 -9
- package/components/navigation-rail/navigation-rail.d.ts +8 -6
- package/components/navigation-rail/navigation-rail.js +55 -46
- package/components/radio/radio-group.d.ts +13 -6
- package/components/radio/radio-group.js +69 -59
- package/components/radio/radio-style.js +1 -1
- package/components/radio/radio.d.ts +11 -5
- package/components/radio/radio.js +26 -19
- package/components/range-slider/index.d.ts +9 -3
- package/components/range-slider/index.js +13 -11
- package/components/ripple/index.d.ts +4 -2
- package/components/ripple/index.js +4 -2
- package/components/ripple/ripple-mixin.d.ts +1 -1
- package/components/ripple/ripple-mixin.js +0 -1
- package/components/segmented-button/segmented-button-group-style.js +1 -1
- package/components/segmented-button/segmented-button-group.d.ts +12 -5
- package/components/segmented-button/segmented-button-group.js +92 -77
- package/components/segmented-button/segmented-button.d.ts +8 -3
- package/components/segmented-button/segmented-button.js +5 -4
- package/components/select/index.d.ts +13 -5
- package/components/select/index.js +30 -28
- package/components/slider/index.d.ts +8 -1
- package/components/slider/index.js +11 -18
- package/components/slider/slider-base-style.js +1 -1
- package/components/slider/slider-base.d.ts +7 -3
- package/components/slider/slider-base.js +28 -13
- package/components/snackbar/index.d.ts +9 -2
- package/components/snackbar/index.js +11 -10
- package/components/switch/index.d.ts +10 -3
- package/components/switch/index.js +12 -15
- package/components/switch/style.js +1 -1
- package/components/tabs/tab-panel.d.ts +4 -2
- package/components/tabs/tab-panel.js +4 -2
- package/components/tabs/tab-style.js +1 -1
- package/components/tabs/tab.d.ts +7 -3
- package/components/tabs/tab.js +12 -6
- package/components/tabs/tabs-style.js +1 -1
- package/components/tabs/tabs.d.ts +11 -7
- package/components/tabs/tabs.js +57 -40
- package/components/text-field/index.d.ts +13 -5
- package/components/text-field/index.js +43 -65
- package/components/text-field/style.js +1 -1
- package/components/tooltip/index.d.ts +14 -7
- package/components/tooltip/index.js +45 -38
- package/components/top-app-bar/top-app-bar-title-style.js +1 -1
- package/components/top-app-bar/top-app-bar-title.d.ts +4 -2
- package/components/top-app-bar/top-app-bar-title.js +18 -13
- package/components/top-app-bar/top-app-bar.d.ts +9 -3
- package/components/top-app-bar/top-app-bar.js +11 -10
- package/custom-elements.json +904 -546
- package/functions/getTheme.js +3 -3
- package/functions/snackbar.js +1 -2
- package/functions/utils/colorScheme.js +2 -2
- package/mdui.esm.js +8 -8
- package/mdui.global.js +8 -8
- package/package.json +8 -7
- package/web-types.zh-cn.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html
|
|
2
|
+
import { html } from 'lit';
|
|
3
3
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { map } from 'lit/directives/map.js';
|
|
@@ -9,11 +9,13 @@ 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 { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
13
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
12
14
|
import { FormController, formResets } from '@mdui/shared/controllers/form.js';
|
|
13
15
|
import { defaultValue } from '@mdui/shared/decorators/default-value.js';
|
|
14
16
|
import { watch } from '@mdui/shared/decorators/watch.js';
|
|
17
|
+
import { arraysEqualIgnoreOrder } from '@mdui/shared/helpers/array.js';
|
|
15
18
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
16
|
-
import { emit } from '@mdui/shared/helpers/event.js';
|
|
17
19
|
import { componentStyle } from '@mdui/shared/lit-styles/component-style.js';
|
|
18
20
|
import { segmentedButtonGroupStyle } from './segmented-button-group-style.js';
|
|
19
21
|
/**
|
|
@@ -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 MduiElement {
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
else {
|
|
138
|
-
this.hasSetDefaultValue = true;
|
|
138
|
+
const value = this.isMultiple ? values : values[0] || '';
|
|
139
|
+
this.setValue(value);
|
|
140
|
+
if (!this.isInitial) {
|
|
141
|
+
this.emit('change');
|
|
139
142
|
}
|
|
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();
|
|
@@ -190,7 +200,7 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
190
200
|
checkValidity() {
|
|
191
201
|
const valid = this.inputRef.value.checkValidity();
|
|
192
202
|
if (!valid) {
|
|
193
|
-
emit(
|
|
203
|
+
this.emit('invalid', {
|
|
194
204
|
bubbles: false,
|
|
195
205
|
cancelable: true,
|
|
196
206
|
composed: false,
|
|
@@ -206,13 +216,13 @@ export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement
|
|
|
206
216
|
reportValidity() {
|
|
207
217
|
this.invalid = !this.inputRef.value.reportValidity();
|
|
208
218
|
if (this.invalid) {
|
|
209
|
-
const
|
|
219
|
+
const eventProceeded = this.emit('invalid', {
|
|
210
220
|
bubbles: false,
|
|
211
221
|
cancelable: true,
|
|
212
222
|
composed: false,
|
|
213
223
|
});
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
if (!eventProceeded) {
|
|
225
|
+
// 调用了 preventDefault() 时,隐藏默认的表单错误提示
|
|
216
226
|
this.inputRef.value.blur();
|
|
217
227
|
this.inputRef.value.focus();
|
|
218
228
|
}
|
|
@@ -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,26 +252,28 @@ 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
|
-
if (item.disabled) {
|
|
276
|
+
if (!item || item.disabled) {
|
|
281
277
|
return;
|
|
282
278
|
}
|
|
283
279
|
if (this.isSelectable && item.value) {
|
|
@@ -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 };
|
|
@@ -30,7 +30,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
30
30
|
* @csspart label - 文本内容
|
|
31
31
|
* @csspart loading - 加载中状态的 `<mdui-circular-progress>` 元素
|
|
32
32
|
*/
|
|
33
|
-
export declare class SegmentedButton extends ButtonBase {
|
|
33
|
+
export declare class SegmentedButton extends ButtonBase<SegmentedButtonEventMap> {
|
|
34
34
|
static styles: CSSResultGroup;
|
|
35
35
|
/**
|
|
36
36
|
* 左侧的 Material Icons 图标名。也可以通过 `slot="icon"` 设置
|
|
@@ -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;
|
|
@@ -66,6 +66,11 @@ export declare class SegmentedButton extends ButtonBase {
|
|
|
66
66
|
private renderEndIcon;
|
|
67
67
|
private renderInner;
|
|
68
68
|
}
|
|
69
|
+
export interface SegmentedButtonEventMap {
|
|
70
|
+
focus: FocusEvent;
|
|
71
|
+
blur: FocusEvent;
|
|
72
|
+
invalid: CustomEvent<void>;
|
|
73
|
+
}
|
|
69
74
|
declare global {
|
|
70
75
|
interface HTMLElementTagNameMap {
|
|
71
76
|
'mdui-segmented-button': SegmentedButton;
|
|
@@ -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 };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
2
3
|
import '../chip.js';
|
|
3
4
|
import '../dropdown.js';
|
|
4
5
|
import '../menu.js';
|
|
5
6
|
import '../text-field.js';
|
|
6
7
|
import type { FormControl } from '@mdui/jq/shared/form.js';
|
|
7
|
-
import type { CSSResultGroup, TemplateResult
|
|
8
|
-
declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@mdui/shared/mixins/focusable.js").FocusableMixinInterface> & typeof
|
|
8
|
+
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
9
|
+
declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@mdui/shared/mixins/focusable.js").FocusableMixinInterface> & typeof MduiElement;
|
|
9
10
|
/**
|
|
10
11
|
* @summary 选择框组件。需与 `<mdui-menu-item>` 组件配合使用
|
|
11
12
|
*
|
|
@@ -35,8 +36,7 @@ declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@
|
|
|
35
36
|
* @csspart text-field - 文本框,即 [`<mdui-text-field>`](/docs/2/components/text-field) 元素
|
|
36
37
|
* @csspart menu - 下拉菜单,即 [`<mdui-menu>`](/docs/2/components/menu) 元素
|
|
37
38
|
*/
|
|
38
|
-
export declare class Select extends Select_base implements FormControl {
|
|
39
|
-
static enabledWarnings: WarningKind[];
|
|
39
|
+
export declare class Select extends Select_base<SelectEventMap> implements FormControl {
|
|
40
40
|
static styles: CSSResultGroup;
|
|
41
41
|
/**
|
|
42
42
|
* 下拉框形状。可选值为:
|
|
@@ -147,6 +147,7 @@ export declare class Select extends Select_base implements FormControl {
|
|
|
147
147
|
private readonly hiddenInputRef;
|
|
148
148
|
private readonly formController;
|
|
149
149
|
private readonly hasSlotController;
|
|
150
|
+
private readonly definedController;
|
|
150
151
|
/**
|
|
151
152
|
* 表单验证状态对象
|
|
152
153
|
*/
|
|
@@ -192,6 +193,13 @@ export declare class Select extends Select_base implements FormControl {
|
|
|
192
193
|
*/
|
|
193
194
|
private onTextFieldKeyDown;
|
|
194
195
|
}
|
|
196
|
+
export interface SelectEventMap {
|
|
197
|
+
focus: FocusEvent;
|
|
198
|
+
blur: FocusEvent;
|
|
199
|
+
change: CustomEvent<void>;
|
|
200
|
+
invalid: CustomEvent<void>;
|
|
201
|
+
clear: CustomEvent<void>;
|
|
202
|
+
}
|
|
195
203
|
declare global {
|
|
196
204
|
interface HTMLElementTagNameMap {
|
|
197
205
|
'mdui-select': Select;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html,
|
|
3
|
-
import { customElement, property, queryAssignedElements, } from 'lit/decorators.js';
|
|
2
|
+
import { html, nothing } from 'lit';
|
|
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 { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
10
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
9
11
|
import { FormController, formResets } from '@mdui/shared/controllers/form.js';
|
|
10
12
|
import { HasSlotController } from '@mdui/shared/controllers/has-slot.js';
|
|
11
13
|
import { defaultValue } from '@mdui/shared/decorators/default-value.js';
|
|
12
14
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
13
|
-
import { emit } from '@mdui/shared/helpers/event.js';
|
|
14
15
|
import { observeResize } from '@mdui/shared/helpers/observeResize.js';
|
|
15
16
|
import { componentStyle } from '@mdui/shared/lit-styles/component-style.js';
|
|
16
17
|
import { FocusableMixin } from '@mdui/shared/mixins/focusable.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(MduiElement) {
|
|
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`
|
|
@@ -159,7 +164,7 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
159
164
|
checkValidity() {
|
|
160
165
|
const valid = this.hiddenInputRef.value.checkValidity();
|
|
161
166
|
if (!valid) {
|
|
162
|
-
emit(
|
|
167
|
+
this.emit('invalid', {
|
|
163
168
|
bubbles: false,
|
|
164
169
|
cancelable: true,
|
|
165
170
|
composed: false,
|
|
@@ -175,7 +180,7 @@ export let Select = class Select extends FocusableMixin(LitElement) {
|
|
|
175
180
|
reportValidity() {
|
|
176
181
|
this.invalid = !this.hiddenInputRef.value.reportValidity();
|
|
177
182
|
if (this.invalid) {
|
|
178
|
-
emit(
|
|
183
|
+
this.emit('invalid', {
|
|
179
184
|
bubbles: false,
|
|
180
185
|
cancelable: true,
|
|
181
186
|
composed: false,
|
|
@@ -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 };
|
|
@@ -21,7 +21,7 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
21
21
|
* @csspart label 提示文本
|
|
22
22
|
* @csspart tickmark - 刻度标记
|
|
23
23
|
*/
|
|
24
|
-
export declare class Slider extends SliderBase implements FormControl {
|
|
24
|
+
export declare class Slider extends SliderBase<SliderEventMap> implements FormControl {
|
|
25
25
|
static styles: CSSResultGroup;
|
|
26
26
|
/**
|
|
27
27
|
* 滑块的值,将于表单数据一起提交
|
|
@@ -46,6 +46,13 @@ export declare class Slider extends SliderBase implements FormControl {
|
|
|
46
46
|
private updateStyle;
|
|
47
47
|
private onInput;
|
|
48
48
|
}
|
|
49
|
+
export interface SliderEventMap {
|
|
50
|
+
focus: FocusEvent;
|
|
51
|
+
blur: FocusEvent;
|
|
52
|
+
change: CustomEvent<void>;
|
|
53
|
+
input: Event;
|
|
54
|
+
invalid: CustomEvent<void>;
|
|
55
|
+
}
|
|
49
56
|
declare global {
|
|
50
57
|
interface HTMLElementTagNameMap {
|
|
51
58
|
'mdui-slider': Slider;
|