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.
Files changed (127) hide show
  1. package/LICENSE +21 -21
  2. package/components/avatar/index.d.ts +4 -2
  3. package/components/avatar/index.js +4 -2
  4. package/components/badge/index.d.ts +4 -2
  5. package/components/badge/index.js +4 -2
  6. package/components/bottom-app-bar/index.d.ts +9 -3
  7. package/components/bottom-app-bar/index.js +9 -9
  8. package/components/button/button-base.d.ts +5 -5
  9. package/components/button/button-base.js +22 -19
  10. package/components/button/index.d.ts +6 -1
  11. package/components/button/index.js +2 -1
  12. package/components/button-icon/index.d.ts +7 -1
  13. package/components/button-icon/index.js +3 -3
  14. package/components/card/index.d.ts +8 -4
  15. package/components/card/index.js +7 -3
  16. package/components/checkbox/index.d.ts +10 -3
  17. package/components/checkbox/index.js +13 -16
  18. package/components/checkbox/style.js +1 -1
  19. package/components/chip/index.d.ts +8 -1
  20. package/components/chip/index.js +5 -5
  21. package/components/circular-progress/index.d.ts +4 -2
  22. package/components/circular-progress/index.js +5 -4
  23. package/components/collapse/collapse-item-style.js +1 -1
  24. package/components/collapse/collapse-item.d.ts +15 -3
  25. package/components/collapse/collapse-item.js +26 -23
  26. package/components/collapse/collapse.d.ts +16 -8
  27. package/components/collapse/collapse.js +61 -38
  28. package/components/dialog/index.d.ts +12 -4
  29. package/components/dialog/index.js +36 -36
  30. package/components/divider/index.d.ts +4 -2
  31. package/components/divider/index.js +4 -2
  32. package/components/dropdown/index.d.ts +13 -7
  33. package/components/dropdown/index.js +70 -63
  34. package/components/fab/index.d.ts +7 -1
  35. package/components/fab/index.js +10 -5
  36. package/components/icon/index.d.ts +4 -2
  37. package/components/icon/index.js +4 -2
  38. package/components/layout/helper.d.ts +5 -6
  39. package/components/layout/helper.js +42 -48
  40. package/components/layout/layout-item-base.d.ts +3 -2
  41. package/components/layout/layout-item-base.js +3 -4
  42. package/components/layout/layout-item.d.ts +4 -3
  43. package/components/layout/layout-item.js +3 -3
  44. package/components/layout/layout-main.d.ts +4 -2
  45. package/components/layout/layout-main.js +4 -2
  46. package/components/layout/layout.d.ts +4 -2
  47. package/components/layout/layout.js +4 -2
  48. package/components/linear-progress/index.d.ts +4 -2
  49. package/components/linear-progress/index.js +5 -4
  50. package/components/list/list-item-style.js +1 -1
  51. package/components/list/list-item.d.ts +7 -3
  52. package/components/list/list-item.js +5 -3
  53. package/components/list/list-subheader.d.ts +4 -2
  54. package/components/list/list-subheader.js +4 -2
  55. package/components/list/list.d.ts +4 -2
  56. package/components/list/list.js +4 -2
  57. package/components/menu/menu-item.d.ts +12 -3
  58. package/components/menu/menu-item.js +53 -40
  59. package/components/menu/menu.d.ts +9 -3
  60. package/components/menu/menu.js +85 -59
  61. package/components/navigation-bar/navigation-bar-item-style.js +1 -1
  62. package/components/navigation-bar/navigation-bar-item.d.ts +13 -5
  63. package/components/navigation-bar/navigation-bar-item.js +28 -11
  64. package/components/navigation-bar/navigation-bar.d.ts +14 -7
  65. package/components/navigation-bar/navigation-bar.js +58 -49
  66. package/components/navigation-drawer/index.d.ts +13 -2
  67. package/components/navigation-drawer/index.js +69 -49
  68. package/components/navigation-drawer/style.js +1 -1
  69. package/components/navigation-rail/navigation-rail-item-style.js +1 -1
  70. package/components/navigation-rail/navigation-rail-item.d.ts +13 -5
  71. package/components/navigation-rail/navigation-rail-item.js +22 -9
  72. package/components/navigation-rail/navigation-rail.d.ts +8 -6
  73. package/components/navigation-rail/navigation-rail.js +55 -46
  74. package/components/radio/radio-group.d.ts +13 -6
  75. package/components/radio/radio-group.js +69 -59
  76. package/components/radio/radio-style.js +1 -1
  77. package/components/radio/radio.d.ts +11 -5
  78. package/components/radio/radio.js +26 -19
  79. package/components/range-slider/index.d.ts +9 -3
  80. package/components/range-slider/index.js +13 -11
  81. package/components/ripple/index.d.ts +4 -2
  82. package/components/ripple/index.js +4 -2
  83. package/components/ripple/ripple-mixin.d.ts +1 -1
  84. package/components/ripple/ripple-mixin.js +0 -1
  85. package/components/segmented-button/segmented-button-group-style.js +1 -1
  86. package/components/segmented-button/segmented-button-group.d.ts +12 -5
  87. package/components/segmented-button/segmented-button-group.js +92 -77
  88. package/components/segmented-button/segmented-button.d.ts +8 -3
  89. package/components/segmented-button/segmented-button.js +5 -4
  90. package/components/select/index.d.ts +13 -5
  91. package/components/select/index.js +30 -28
  92. package/components/slider/index.d.ts +8 -1
  93. package/components/slider/index.js +11 -18
  94. package/components/slider/slider-base-style.js +1 -1
  95. package/components/slider/slider-base.d.ts +7 -3
  96. package/components/slider/slider-base.js +28 -13
  97. package/components/snackbar/index.d.ts +9 -2
  98. package/components/snackbar/index.js +11 -10
  99. package/components/switch/index.d.ts +10 -3
  100. package/components/switch/index.js +12 -15
  101. package/components/switch/style.js +1 -1
  102. package/components/tabs/tab-panel.d.ts +4 -2
  103. package/components/tabs/tab-panel.js +4 -2
  104. package/components/tabs/tab-style.js +1 -1
  105. package/components/tabs/tab.d.ts +7 -3
  106. package/components/tabs/tab.js +12 -6
  107. package/components/tabs/tabs-style.js +1 -1
  108. package/components/tabs/tabs.d.ts +11 -7
  109. package/components/tabs/tabs.js +57 -40
  110. package/components/text-field/index.d.ts +13 -5
  111. package/components/text-field/index.js +43 -65
  112. package/components/text-field/style.js +1 -1
  113. package/components/tooltip/index.d.ts +14 -7
  114. package/components/tooltip/index.js +45 -38
  115. package/components/top-app-bar/top-app-bar-title-style.js +1 -1
  116. package/components/top-app-bar/top-app-bar-title.d.ts +4 -2
  117. package/components/top-app-bar/top-app-bar-title.js +18 -13
  118. package/components/top-app-bar/top-app-bar.d.ts +9 -3
  119. package/components/top-app-bar/top-app-bar.js +11 -10
  120. package/custom-elements.json +904 -546
  121. package/functions/getTheme.js +3 -3
  122. package/functions/snackbar.js +1 -2
  123. package/functions/utils/colorScheme.js +2 -2
  124. package/mdui.esm.js +8 -8
  125. package/mdui.global.js +8 -8
  126. package/package.json +8 -7
  127. package/web-types.zh-cn.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { __decorate } from "tslib";
2
- import { html, LitElement } from 'lit';
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
- export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement {
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
- // 是否已完成初始 value 的设置。首次设置初始值时,不触发 change 事件
76
- this.hasSetDefaultValue = false;
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 && this.selectedKeys.length) {
118
- this.selectedKeys = [];
119
- this.onSelectedKeysChange();
120
- this.onValueChange();
121
+ async onSelectsChange() {
122
+ if (!this.isSelectable) {
123
+ // 不可选中,清空选中值
124
+ this.setSelectedKeys([]);
121
125
  }
122
- if (this.isSingle && this.selectedKeys.length > 1) {
123
- this.selectedKeys = this.selectedKeys.slice(0, 1);
124
- this.onSelectedKeysChange();
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
- this.value = this.isMultiple ? values : values[0] || '';
134
- if (this.hasSetDefaultValue) {
135
- emit(this, 'change');
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
- const hasUpdated = this.hasUpdated;
143
- if (!hasUpdated) {
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.updateSelected(hasUpdated);
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.selectedKeys = [];
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.selectedKeys = firstItem ? [firstItem.key] : [];
163
+ this.setSelectedKeys(firstItem ? [firstItem.key] : []);
163
164
  }
164
165
  else if (this.isMultiple) {
165
- this.selectedKeys = this.itemsEnabled
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
- onDisabledChange() {
175
- this.items.forEach((item) => (item.groupDisabled = this.disabled));
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(this, 'invalid', {
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 requestInvalid = emit(this, 'invalid', {
219
+ const eventProceeded = this.emit('invalid', {
210
220
  bubbles: false,
211
221
  cancelable: true,
212
222
  composed: false,
213
223
  });
214
- // 调用了 preventDefault() 时,隐藏默认的表单错误提示
215
- if (requestInvalid.defaultPrevented) {
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 = selectedKeys;
255
+ this.setSelectedKeys(selectedKeys);
262
256
  }
263
257
  if (this.isSingle) {
264
258
  if (this.selectedKeys.includes(item.key)) {
265
- this.selectedKeys = [];
259
+ this.setSelectedKeys([]);
266
260
  }
267
261
  else {
268
- this.selectedKeys = [item.key];
262
+ this.setSelectedKeys([item.key]);
269
263
  }
270
264
  }
271
- this.updateSelected(this.hasUpdated);
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.classList.toggle('mdui-segmented-button-first', index === 0);
310
- item.classList.toggle('mdui-segmented-button-last', index === items.length - 1);
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
- property({
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, "onDisabledChange", null);
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
- export let SegmentedButton = class SegmentedButton extends ButtonBase {
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-radio-group 控制该参数
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 { LitElement, PropertyValues } from 'lit';
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, WarningKind } from 'lit';
8
- declare const Select_base: import("@open-wc/dedupe-mixin").Constructor<import("@mdui/shared/mixins/focusable.js").FocusableMixinInterface> & typeof LitElement;
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, LitElement, nothing } from 'lit';
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
- export let Select = class Select extends FocusableMixin(LitElement) {
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
- this.updateComplete.then(() => {
148
- this.observeResize = observeResize(this.textFieldRef.value, () => this.resizeMenu());
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
- (_a = this.observeResize) === null || _a === void 0 ? void 0 : _a.unobserve();
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(this, 'invalid', {
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(this, 'invalid', {
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
- // 首次渲染时,slot 中的 mdui-menu-item 还未渲染完成,无法读取到其中的文本值
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="${(_a = this.hiddenInputRef.value) === null || _a === void 0 ? void 0 : _a.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([
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 (((_a = this.menuItems.find((item) => item.value === valueItem)) === null || _a === void 0 ? void 0 : _a.textContent) ||
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 !== null && v !== void 0 ? v : '')
252
- : (_a = menu.value) !== null && _a !== void 0 ? _a : '';
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 && ((_b = formResets.get(form)) === null || _b === void 0 ? void 0 : _b.has(this))) {
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
- property({
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;