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.
Files changed (96) hide show
  1. package/components/avatar/index.js +2 -1
  2. package/components/badge/index.js +2 -1
  3. package/components/bottom-app-bar/index.d.ts +2 -2
  4. package/components/bottom-app-bar/index.js +4 -3
  5. package/components/button/button-base.d.ts +2 -2
  6. package/components/button/button-base.js +15 -14
  7. package/components/button/index.js +2 -1
  8. package/components/button-icon/index.js +2 -1
  9. package/components/card/index.d.ts +1 -1
  10. package/components/card/index.js +5 -2
  11. package/components/checkbox/index.js +7 -10
  12. package/components/checkbox/style.js +1 -1
  13. package/components/chip/index.js +2 -1
  14. package/components/circular-progress/index.js +3 -3
  15. package/components/collapse/collapse-item-style.js +1 -1
  16. package/components/collapse/collapse-item.d.ts +2 -1
  17. package/components/collapse/collapse-item.js +23 -20
  18. package/components/collapse/collapse.d.ts +6 -6
  19. package/components/collapse/collapse.js +57 -34
  20. package/components/dialog/index.d.ts +3 -2
  21. package/components/dialog/index.js +27 -23
  22. package/components/divider/index.js +2 -1
  23. package/components/dropdown/index.d.ts +4 -5
  24. package/components/dropdown/index.js +56 -51
  25. package/components/fab/index.d.ts +1 -0
  26. package/components/fab/index.js +10 -5
  27. package/components/icon/index.js +2 -1
  28. package/components/layout/helper.d.ts +5 -6
  29. package/components/layout/helper.js +42 -48
  30. package/components/layout/layout-item-base.js +1 -2
  31. package/components/layout/layout-item.js +3 -3
  32. package/components/layout/layout-main.js +2 -1
  33. package/components/layout/layout.js +2 -1
  34. package/components/linear-progress/index.js +3 -3
  35. package/components/list/list-item.js +3 -2
  36. package/components/list/list-subheader.js +2 -1
  37. package/components/list/list.js +2 -1
  38. package/components/menu/menu-item.d.ts +1 -0
  39. package/components/menu/menu-item.js +45 -28
  40. package/components/menu/menu.d.ts +4 -1
  41. package/components/menu/menu.js +82 -56
  42. package/components/navigation-bar/navigation-bar-item-style.js +1 -1
  43. package/components/navigation-bar/navigation-bar-item.d.ts +6 -2
  44. package/components/navigation-bar/navigation-bar-item.js +26 -10
  45. package/components/navigation-bar/navigation-bar.d.ts +6 -6
  46. package/components/navigation-bar/navigation-bar.js +49 -42
  47. package/components/navigation-drawer/index.d.ts +5 -1
  48. package/components/navigation-drawer/index.js +62 -41
  49. package/components/navigation-rail/navigation-rail-item-style.js +1 -1
  50. package/components/navigation-rail/navigation-rail-item.d.ts +6 -2
  51. package/components/navigation-rail/navigation-rail-item.js +20 -8
  52. package/components/navigation-rail/navigation-rail.d.ts +4 -5
  53. package/components/navigation-rail/navigation-rail.js +51 -44
  54. package/components/radio/radio-group.d.ts +6 -4
  55. package/components/radio/radio-group.js +61 -48
  56. package/components/radio/radio-style.js +1 -1
  57. package/components/radio/radio.d.ts +3 -2
  58. package/components/radio/radio.js +24 -17
  59. package/components/range-slider/index.js +7 -9
  60. package/components/ripple/index.js +2 -1
  61. package/components/segmented-button/segmented-button-group.d.ts +6 -3
  62. package/components/segmented-button/segmented-button-group.js +84 -69
  63. package/components/segmented-button/segmented-button.d.ts +2 -2
  64. package/components/segmented-button/segmented-button.js +5 -4
  65. package/components/select/index.d.ts +2 -2
  66. package/components/select/index.js +26 -24
  67. package/components/slider/index.js +7 -9
  68. package/components/slider/slider-base-style.js +1 -1
  69. package/components/slider/slider-base.js +1 -5
  70. package/components/snackbar/index.js +2 -1
  71. package/components/switch/index.js +6 -9
  72. package/components/switch/style.js +1 -1
  73. package/components/tabs/tab-panel.js +2 -1
  74. package/components/tabs/tab-style.js +1 -1
  75. package/components/tabs/tab.js +10 -5
  76. package/components/tabs/tabs-style.js +1 -1
  77. package/components/tabs/tabs.d.ts +6 -5
  78. package/components/tabs/tabs.js +52 -38
  79. package/components/text-field/index.d.ts +2 -2
  80. package/components/text-field/index.js +32 -54
  81. package/components/text-field/style.js +1 -1
  82. package/components/tooltip/index.d.ts +5 -5
  83. package/components/tooltip/index.js +30 -25
  84. package/components/top-app-bar/top-app-bar-title-style.js +1 -1
  85. package/components/top-app-bar/top-app-bar-title.js +16 -12
  86. package/components/top-app-bar/top-app-bar.d.ts +2 -2
  87. package/components/top-app-bar/top-app-bar.js +6 -4
  88. package/custom-elements.json +3776 -3481
  89. package/functions/getTheme.js +3 -3
  90. package/functions/snackbar.js +1 -2
  91. package/functions/utils/colorScheme.js +2 -2
  92. package/html-data.zh-cn.json +727 -727
  93. package/mdui.esm.js +8 -8
  94. package/mdui.global.js +8 -8
  95. package/package.json +7 -7
  96. 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
- export let SegmentedButtonGroup = class SegmentedButtonGroup extends LitElement {
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
- // 是否已完成初始 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) {
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
- 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();
@@ -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 = 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
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.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 };
@@ -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
- 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 };
@@ -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, WarningKind } from 'lit';
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
- export let Select = class Select extends FocusableMixin(LitElement) {
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
- 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`
@@ -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 };
@@ -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
- export let Slider = class Slider extends SliderBase {
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 && ((_a = formResets.get(form)) === null || _a === void 0 ? void 0 : _a.has(this))) {
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))}:host([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))}:host([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)}:host([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)}:host([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))}:host([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))}:host([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)}:host([invalid]) .tickmark{background-color:rgba(var(--mdui-color-error),.38)}.tickmark.active{background-color:rgba(var(--mdui-color-on-primary),.38)}:host([invalid]) .tickmark.active{background-color:rgba(var(--mdui-color-on-error),.38)}:host([disabled]) .tickmark{background-color:rgba(var(--mdui-color-on-surface),.38)}`;
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
- property({
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
- export let Snackbar = class Snackbar extends LitElement {
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 };