@motifx-community/ui 0.1.0-beta.0 → 0.1.0-beta.1

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/CHANGELOG.md +18 -0
  2. package/dist/components/dropdown/DropDown.d.ts +14 -0
  3. package/dist/components/dropdown/drop-down-props.d.ts +5 -0
  4. package/dist/components/scheduler/view/AgendaView.d.ts +1 -1
  5. package/dist/core/ui-strings.d.ts +2 -0
  6. package/dist/generated/tokens.d.ts +40 -0
  7. package/dist/index.js +133 -15
  8. package/dist/index.js.map +1 -1
  9. package/dist/locales/en.json +1 -0
  10. package/dist/locales/tr.json +1 -0
  11. package/dist/parts/data/DataItems.d.ts +5 -0
  12. package/dist/parts/data/KeyedItems.d.ts +2 -0
  13. package/dist/styles.css +87 -3
  14. package/dist/tokens/index.d.ts +40 -0
  15. package/dist/tokens/index.js +40 -0
  16. package/dist/tokens/index.js.map +1 -1
  17. package/docs/accordion.md +1 -1
  18. package/docs/actionsheet.md +1 -1
  19. package/docs/avatar.md +1 -1
  20. package/docs/badge.md +1 -1
  21. package/docs/bottomsheet.md +1 -1
  22. package/docs/breadcrumb.md +1 -1
  23. package/docs/button.md +1 -1
  24. package/docs/buttongroup.md +1 -1
  25. package/docs/calendar.md +1 -1
  26. package/docs/card.md +1 -1
  27. package/docs/checkbox.md +1 -1
  28. package/docs/chip.md +1 -1
  29. package/docs/colorbox.md +1 -1
  30. package/docs/combobox.md +1 -1
  31. package/docs/control.md +1 -1
  32. package/docs/datagrid-api.md +1 -1
  33. package/docs/datagrid-bands.md +1 -1
  34. package/docs/datagrid-drag-select.md +1 -1
  35. package/docs/datagrid-drag.md +1 -1
  36. package/docs/datagrid-editing.md +1 -1
  37. package/docs/datagrid-filtering.md +1 -1
  38. package/docs/datagrid-forms.md +1 -1
  39. package/docs/datagrid-grouping.md +1 -1
  40. package/docs/datagrid-layout.md +1 -1
  41. package/docs/datagrid-lookups.md +1 -1
  42. package/docs/datagrid-master-detail.md +1 -1
  43. package/docs/datagrid-scrolling.md +1 -1
  44. package/docs/datagrid-selection.md +1 -1
  45. package/docs/datagrid.md +1 -1
  46. package/docs/datebox.md +1 -1
  47. package/docs/drawer.md +1 -1
  48. package/docs/dropdown.md +11 -5
  49. package/docs/filterbuilder.md +1 -1
  50. package/docs/formlayout.md +1 -1
  51. package/docs/home.md +1 -1
  52. package/docs/keyboard.md +1 -1
  53. package/docs/layout.md +1 -1
  54. package/docs/listbox.md +1 -1
  55. package/docs/lookup.md +86 -2
  56. package/docs/menus.md +1 -1
  57. package/docs/numberbox.md +1 -1
  58. package/docs/pagination.md +1 -1
  59. package/docs/progress.md +1 -1
  60. package/docs/radiogroup.md +1 -1
  61. package/docs/rating.md +1 -1
  62. package/docs/scheduler-agenda.md +1 -1
  63. package/docs/scheduler-big-data.md +1 -1
  64. package/docs/scheduler-editing.md +1 -1
  65. package/docs/scheduler-form.md +1 -1
  66. package/docs/scheduler-icalendar.md +1 -1
  67. package/docs/scheduler-mobile.md +1 -1
  68. package/docs/scheduler-recurrence.md +1 -1
  69. package/docs/scheduler-resources.md +1 -1
  70. package/docs/scheduler-timeline.md +1 -1
  71. package/docs/scheduler.md +1 -1
  72. package/docs/showcase.md +1 -1
  73. package/docs/skeleton.md +1 -1
  74. package/docs/slider.md +1 -1
  75. package/docs/switch.md +1 -1
  76. package/docs/tabdocs-dock.md +1 -1
  77. package/docs/tabdocs-drag.md +1 -1
  78. package/docs/tabdocs-menus.md +1 -1
  79. package/docs/tabdocs-mobile.md +1 -1
  80. package/docs/tabdocs-tabs.md +1 -1
  81. package/docs/tabdocs-windows.md +1 -1
  82. package/docs/tabdocs-workspace.md +1 -1
  83. package/docs/tabdocs.md +1 -1
  84. package/docs/tabs.md +1 -1
  85. package/docs/tagbox.md +1 -1
  86. package/docs/textarea.md +1 -1
  87. package/docs/textbox.md +1 -1
  88. package/docs/toast.md +1 -1
  89. package/docs/tokens.md +9 -1
  90. package/docs/toolbar.md +1 -1
  91. package/docs/tooltip.md +1 -1
  92. package/docs/treeview.md +1 -1
  93. package/docs/window.md +1 -1
  94. package/llms-full.txt +181 -83
  95. package/llms.txt +1 -1
  96. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.0-beta.1] - 2026-11-04
10
+
11
+ ### DropDown and Lookup: a value on no loaded page is asked for by key
12
+
13
+ - A value whose item is on no loaded page of `dataSource` is asked for by key, in one request with the keys the
14
+ other fields and grids over the same source need at that moment. Meanwhile the field waits: `aria-busy`, a
15
+ spinner in the arrow's place (`.mx-drop-down__spinner`, `data-loading`), the list closed, never the key as its
16
+ text. A record that carries the name too gives it as `valueText`, and the field shows it at once. A key the
17
+ source does not have shows itself, muted and underlined (`data-missing`), its title says why (`notInList`);
18
+ when the request failed, opening the list asks again.
19
+ - Units `drop-down.spinner` and `drop-down.spinner-shape` and the `missing` state of `drop-down.value`, drawn in
20
+ every language. The docs: "A value on no loaded page" on the Lookup page.
21
+
22
+ ### Scheduler
23
+
24
+ - The agenda view tells the Scheduler it is shown as soon as it is configured: a view change made while focus is
25
+ in the Scheduler moves focus into the agenda, as into the other views.
26
+
9
27
  ## [0.1.0-beta.0] - 2026-10-30
10
28
 
11
29
  The first preview on npm (`npm i @motifx-community/ui@beta`). The package also carries its documentation for
@@ -12,6 +12,10 @@ type Template<T> = ((item: T, host: HTMLElement) => (() => void) | void) | null;
12
12
  * list opens below it with the keyboard or a press, and can be searched. Items are plain values,
13
13
  * `DropDownItem`s or your own objects read through `textField` / `valueField`.
14
14
  *
15
+ * From a data source, a value on no loaded page is asked for by key: meanwhile the field shows
16
+ * `valueText` when it is given, else it waits (a spinner in the arrow's place, the list closed).
17
+ * A key the source does not have shows itself, marked.
18
+ *
15
19
  * @example
16
20
  * <DropDown label="&City" items={['Ankara', 'İstanbul', 'İzmir']} x-model={() => this.form.city} />
17
21
  * <DropDown label="Country" items={() => this.countries} textField="name" valueField="code" searchEnabled />
@@ -32,6 +36,8 @@ export declare class DropDown<T = unknown, V = unknown> extends Field<V | null,
32
36
  set enabledField(value: Bind<ItemField<T>>);
33
37
  get dataSource(): data.DataSource<T, unknown> | null;
34
38
  set dataSource(value: Bind<data.DataSource<T, unknown> | null>);
39
+ get valueText(): string;
40
+ set valueText(value: Bind<string>);
35
41
  get searchDelay(): number;
36
42
  set searchDelay(value: Bind<number>);
37
43
  get placeholder(): string;
@@ -76,6 +82,10 @@ export declare class DropDown<T = unknown, V = unknown> extends Field<V | null,
76
82
  private indexOfValue;
77
83
  /** The item of `value`: among the items in memory, or the one known from a data source (asked by key when needed). */
78
84
  private itemOfValue;
85
+ /** Asks the data source for the item of `value` (`again`: after its request failed); the field shows the answer. */
86
+ private lookUp;
87
+ /** What the field shows for `value` and its text. */
88
+ private valueLook;
79
89
  private renderSource;
80
90
  private sourceChanged;
81
91
  private visibleItems;
@@ -91,6 +101,10 @@ export declare class DropDown<T = unknown, V = unknown> extends Field<V | null,
91
101
  private watchList;
92
102
  private drawList;
93
103
  private renderField;
104
+ /** The texts of the wait and of a missing key are the kit's: the field draws them again when its language changes. */
105
+ private followLanguage;
106
+ /** The spinner in the arrow's place while the value's item is asked for; made the first time it is needed. */
107
+ private addSpinner;
94
108
  private renderClear;
95
109
  }
96
110
  export {};
@@ -9,6 +9,11 @@ export interface DropDownProps<T, V> extends FieldProps<V | null> {
9
9
  items?: Bind<readonly T[]>;
10
10
  /** Items from the data layer; the search box searches it (`searchFields`). Wins over `items`. */
11
11
  dataSource?: Bind<data.DataSource<T, unknown> | null>;
12
+ /**
13
+ * The value's text while its item is asked for from `dataSource` (the record often carries it:
14
+ * `valueText={() => order.customerName}`): the field shows it at once instead of waiting.
15
+ */
16
+ valueText?: Bind<string>;
12
17
  /** Milliseconds between the last key in the search box and a data source search. Default `250`. */
13
18
  searchDelay?: Bind<number>;
14
19
  /** Default `'text'` of an object item, the item itself otherwise. */
@@ -27,7 +27,7 @@ export declare class AgendaView<T> extends Component<HTMLDivElement, Props<T>> {
27
27
  constructor(props: Props<T>);
28
28
  private get host();
29
29
  onConfigured(): void;
30
- onMounted(): void;
30
+ onConfig(): void;
31
31
  onDisposing(): void;
32
32
  /** All of the list, as the model has it now. */
33
33
  draw(): void;
@@ -9,6 +9,8 @@ export interface UiStrings {
9
9
  close: string;
10
10
  loading: string;
11
11
  noItems: string;
12
+ /** A value the list's source does not have. */
13
+ notInList: string;
12
14
  search: string;
13
15
  notifications: string;
14
16
  previousMonth: string;
@@ -6345,6 +6345,16 @@ export declare const componentTokens: {
6345
6345
  readonly type: 'color';
6346
6346
  readonly layer: 'component';
6347
6347
  };
6348
+ readonly 'drop-down.value.missing.color': {
6349
+ readonly cssVar: '--mx-drop-down-value-missing-color';
6350
+ readonly type: 'color';
6351
+ readonly layer: 'component';
6352
+ };
6353
+ readonly 'drop-down.value.missing.text-decoration': {
6354
+ readonly cssVar: '--mx-drop-down-value-missing-text-decoration';
6355
+ readonly type: 'keyword';
6356
+ readonly layer: 'component';
6357
+ };
6348
6358
  readonly 'drop-down.chevron.size': {
6349
6359
  readonly cssVar: '--mx-drop-down-chevron-size';
6350
6360
  readonly type: 'dimension';
@@ -6370,6 +6380,36 @@ export declare const componentTokens: {
6370
6380
  readonly type: 'color';
6371
6381
  readonly layer: 'component';
6372
6382
  };
6383
+ readonly 'drop-down.spinner.size': {
6384
+ readonly cssVar: '--mx-drop-down-spinner-size';
6385
+ readonly type: 'dimension';
6386
+ readonly layer: 'component';
6387
+ };
6388
+ readonly 'drop-down.spinner.border-width': {
6389
+ readonly cssVar: '--mx-drop-down-spinner-border-width';
6390
+ readonly type: 'dimension';
6391
+ readonly layer: 'component';
6392
+ };
6393
+ readonly 'drop-down.spinner.border-end-color': {
6394
+ readonly cssVar: '--mx-drop-down-spinner-border-end-color';
6395
+ readonly type: 'color';
6396
+ readonly layer: 'component';
6397
+ };
6398
+ readonly 'drop-down.spinner.radius': {
6399
+ readonly cssVar: '--mx-drop-down-spinner-radius';
6400
+ readonly type: 'dimension';
6401
+ readonly layer: 'component';
6402
+ };
6403
+ readonly 'drop-down.spinner.color': {
6404
+ readonly cssVar: '--mx-drop-down-spinner-color';
6405
+ readonly type: 'color';
6406
+ readonly layer: 'component';
6407
+ };
6408
+ readonly 'drop-down.spinner-shape.display': {
6409
+ readonly cssVar: '--mx-drop-down-spinner-shape-display';
6410
+ readonly type: 'keyword';
6411
+ readonly layer: 'component';
6412
+ };
6373
6413
  readonly 'field.width': {
6374
6414
  readonly cssVar: '--mx-field-width';
6375
6415
  readonly type: 'dimension';
package/dist/index.js CHANGED
@@ -1756,6 +1756,7 @@ var en_exports = /* @__PURE__ */ __exportAll({
1756
1756
  no: () => "No",
1757
1757
  noItems: () => noItems$1,
1758
1758
  noMatch: () => noMatch$1,
1759
+ notInList: () => notInList$1,
1759
1760
  notifications: () => notifications$1,
1760
1761
  ok: () => "OK",
1761
1762
  outOfRange: () => outOfRange$1,
@@ -2044,6 +2045,7 @@ var decrease$1 = "Decrease";
2044
2045
  var close$1 = "Close";
2045
2046
  var loading$1 = "Loading…";
2046
2047
  var noItems$1 = "No items";
2048
+ var notInList$1 = "Not found in the list";
2047
2049
  var search$1 = "Search";
2048
2050
  var notifications$1 = "Notifications";
2049
2051
  var previousMonth$1 = "Previous month";
@@ -2577,6 +2579,7 @@ var en_default = {
2577
2579
  close: close$1,
2578
2580
  loading: loading$1,
2579
2581
  noItems: noItems$1,
2582
+ notInList: notInList$1,
2580
2583
  search: search$1,
2581
2584
  notifications: notifications$1,
2582
2585
  previousMonth: previousMonth$1,
@@ -3403,6 +3406,7 @@ var tr_exports = /* @__PURE__ */ __exportAll({
3403
3406
  no: () => no,
3404
3407
  noItems: () => noItems,
3405
3408
  noMatch: () => noMatch,
3409
+ notInList: () => notInList,
3406
3410
  notifications: () => notifications,
3407
3411
  ok: () => ok,
3408
3412
  outOfRange: () => outOfRange,
@@ -3691,6 +3695,7 @@ var decrease = "Azalt";
3691
3695
  var close = "Kapat";
3692
3696
  var loading = "Yükleniyor…";
3693
3697
  var noItems = "Öğe yok";
3698
+ var notInList = "Listede bulunamadı";
3694
3699
  var notifications = "Bildirimler";
3695
3700
  var previousMonth = "Önceki ay";
3696
3701
  var nextMonth = "Sonraki ay";
@@ -4233,6 +4238,7 @@ var tr_default = {
4233
4238
  close,
4234
4239
  loading,
4235
4240
  noItems,
4241
+ notInList,
4236
4242
  search: "Ara",
4237
4243
  notifications,
4238
4244
  previousMonth,
@@ -10221,6 +10227,15 @@ var KeyedItems = class KeyedItems {
10221
10227
  }
10222
10228
  return Promise.all(waits).then(() => void 0);
10223
10229
  }
10230
+ /** Asks again for the keys whose last request failed (and for those never asked for). */
10231
+ retry(keys) {
10232
+ const list = [...keys];
10233
+ for (const key of list) {
10234
+ const ks = keyString(key);
10235
+ if (this.entries.get(ks)?.failed) this.entries.delete(ks);
10236
+ }
10237
+ return this.request(list);
10238
+ }
10224
10239
  /** Keeps what an editor chose for a key: its item, or its text. It shows at once, without a request. */
10225
10240
  remember(key, itemOrText) {
10226
10241
  if (key === null || key === void 0) return;
@@ -10541,6 +10556,18 @@ var DataItems = class {
10541
10556
  findLoaded(value, valueOf, same = Object.is) {
10542
10557
  return (this.source ? this.loaded : this.array).find((item) => same(valueOf(item), value));
10543
10558
  }
10559
+ /** What is known of the item `find` asked the data source for: still asked for, found, or not in the source. */
10560
+ known(value) {
10561
+ if (!this.source || value === null || value === void 0) return void 0;
10562
+ return KeyedItems.of(this.source, this.valueField).get(value);
10563
+ }
10564
+ /** Asks the data source again for the item of `value` after its request failed. */
10565
+ async retry(value) {
10566
+ if (!this.source || value === null || value === void 0) return void 0;
10567
+ const known = KeyedItems.of(this.source, this.valueField);
10568
+ await known.retry([value]);
10569
+ return known.get(value)?.item;
10570
+ }
10544
10571
  reload() {
10545
10572
  return this.source ? this.source.reload() : Promise.resolve();
10546
10573
  }
@@ -11021,6 +11048,7 @@ function itemOwnValue(item) {
11021
11048
  var OWN$48 = [
11022
11049
  "items",
11023
11050
  "dataSource",
11051
+ "valueText",
11024
11052
  "placeholder",
11025
11053
  "searchEnabled",
11026
11054
  "searchMode",
@@ -11044,6 +11072,10 @@ var PARTS$33 = Symbol("mx.dropdown");
11044
11072
  * list opens below it with the keyboard or a press, and can be searched. Items are plain values,
11045
11073
  * `DropDownItem`s or your own objects read through `textField` / `valueField`.
11046
11074
  *
11075
+ * From a data source, a value on no loaded page is asked for by key: meanwhile the field shows
11076
+ * `valueText` when it is given, else it waits (a spinner in the arrow's place, the list closed).
11077
+ * A key the source does not have shows itself, marked.
11078
+ *
11047
11079
  * @example
11048
11080
  * <DropDown label="&City" items={['Ankara', 'İstanbul', 'İzmir']} x-model={() => this.form.city} />
11049
11081
  * <DropDown label="Country" items={() => this.countries} textField="name" valueField="code" searchEnabled />
@@ -11072,14 +11104,11 @@ var DropDown = class extends Field {
11072
11104
  return {
11073
11105
  items: this.items,
11074
11106
  value: this.value,
11107
+ valueText: this.getProperty("valueText") ?? "",
11075
11108
  placeholder: this.getProperty("placeholder") ?? "",
11076
11109
  template: this.getProperty("fieldTemplate")
11077
11110
  };
11078
- }, ({ items, value, placeholder, template }) => {
11079
- const item = this.itemOfValue(items, value);
11080
- const text = item === void 0 ? value == null ? "" : String(value) : this.itemText(item);
11081
- this.renderField(item, text, placeholder, template);
11082
- });
11111
+ }, ({ items, value, valueText, placeholder, template }) => this.renderField(items, value, valueText, placeholder, template));
11083
11112
  this.observeProperty("dataSource", () => this.renderSource());
11084
11113
  this.observeProperty("valueField", (field) => parts.source.valueField = typeof field === "string" ? field : void 0);
11085
11114
  parts.source.onChanged(() => this.sourceChanged());
@@ -11089,6 +11118,7 @@ var DropDown = class extends Field {
11089
11118
  clearTimeout(parts.timer);
11090
11119
  parts.source.dispose();
11091
11120
  parts.stopList?.();
11121
+ parts.stopLanguage?.();
11092
11122
  parts.releaseField();
11093
11123
  parts.opened.dispose();
11094
11124
  parts.closed.dispose();
@@ -11136,6 +11166,12 @@ var DropDown = class extends Field {
11136
11166
  set dataSource(value) {
11137
11167
  this.assignProperty("dataSource", value);
11138
11168
  }
11169
+ get valueText() {
11170
+ return this.getProperty("valueText") ?? "";
11171
+ }
11172
+ set valueText(value) {
11173
+ this.assignProperty("valueText", value);
11174
+ }
11139
11175
  get searchDelay() {
11140
11176
  return this.getProperty("searchDelay") ?? (this.dataSource ? 250 : 0);
11141
11177
  }
@@ -11208,8 +11244,9 @@ var DropDown = class extends Field {
11208
11244
  }
11209
11245
  /** Opens the list; `search` starts the search box with that text (or jumps to it without one). `false` when it cannot be used now. */
11210
11246
  open(search) {
11211
- if (!this.isEnabled || this.peekProperty("readOnly")) return false;
11212
11247
  const parts = this.dropParts;
11248
+ if (!this.isEnabled || this.peekProperty("readOnly") || parts.state === "loading") return false;
11249
+ if (parts.state === "failed") this.lookUp(this.peekValue(), true);
11213
11250
  const popup = parts.popup ??= this.createPopup();
11214
11251
  if (popup.isOpen) return true;
11215
11252
  parts.filter = "";
@@ -11292,6 +11329,9 @@ var DropDown = class extends Field {
11292
11329
  source: new DataItems(),
11293
11330
  chosen: void 0,
11294
11331
  lookup: 0,
11332
+ state: "shown",
11333
+ spinner: null,
11334
+ stopLanguage: null,
11295
11335
  timer: void 0,
11296
11336
  opened: new Emitter(),
11297
11337
  closed: new Emitter()
@@ -11328,13 +11368,54 @@ var DropDown = class extends Field {
11328
11368
  if (parts.chosen !== void 0 && same(parts.chosen)) return parts.chosen;
11329
11369
  const near = parts.source.findLoaded(value, (item) => this.itemValue(item), (a, b) => this.sameValue(a, b));
11330
11370
  if (near !== void 0) return near;
11371
+ const known = parts.source.known(value);
11372
+ if (known?.item !== void 0) return known.item;
11373
+ if (known?.state !== "found" && known?.state !== "missing") this.lookUp(value);
11374
+ }
11375
+ /** Asks the data source for the item of `value` (`again`: after its request failed); the field shows the answer. */
11376
+ lookUp(value, again = false) {
11377
+ const parts = this.dropParts;
11331
11378
  const lookup = ++parts.lookup;
11332
- parts.source.find(value, (item) => this.itemValue(item)).then((item) => {
11333
- if (lookup !== parts.lookup || this.isDisposed || item === void 0) return;
11334
- parts.chosen = item;
11379
+ (again ? parts.source.retry(value) : parts.source.find(value, (item) => this.itemValue(item))).then((item) => {
11380
+ if (lookup !== parts.lookup || this.isDisposed) return;
11381
+ if (item !== void 0) parts.chosen = item;
11335
11382
  this.setProperty("chosenTick", lookup);
11336
11383
  });
11337
11384
  }
11385
+ /** What the field shows for `value` and its text. */
11386
+ valueLook(items, value, valueText) {
11387
+ const item = this.itemOfValue(items, value);
11388
+ if (item !== void 0) return {
11389
+ item,
11390
+ text: this.itemText(item),
11391
+ state: "shown"
11392
+ };
11393
+ if (value === null || value === void 0) return {
11394
+ text: "",
11395
+ state: "shown"
11396
+ };
11397
+ const parts = this.dropParts;
11398
+ if (!parts.source.dataSource) return {
11399
+ text: String(value),
11400
+ state: "shown"
11401
+ };
11402
+ const known = parts.source.known(value);
11403
+ if (known?.state === "found") return {
11404
+ text: known.text ?? valueText,
11405
+ state: "shown"
11406
+ };
11407
+ if (known?.state === "missing") return {
11408
+ text: valueText || String(value),
11409
+ state: known.failed ? "failed" : "missing"
11410
+ };
11411
+ return valueText ? {
11412
+ text: valueText,
11413
+ state: "shown"
11414
+ } : {
11415
+ text: "",
11416
+ state: "loading"
11417
+ };
11418
+ }
11338
11419
  renderSource() {
11339
11420
  const parts = this.dropParts;
11340
11421
  const source = this.peekProperty("dataSource");
@@ -11400,7 +11481,7 @@ var DropDown = class extends Field {
11400
11481
  } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && e.key !== " ") {
11401
11482
  if (!this.open()) return;
11402
11483
  this.typeAhead(e.key);
11403
- } else if (e.key === "Escape" && this.peekProperty("clearButton") && !this.isEmptyValue(this.peekValue()) && !this.peekProperty("readOnly")) {
11484
+ } else if (e.key === "Escape" && this.peekProperty("clearButton") && !this.isEmptyValue(this.peekValue()) && !this.peekProperty("readOnly") && parts.state !== "loading") {
11404
11485
  e.preventDefault();
11405
11486
  e.stopPropagation();
11406
11487
  this.commit(null, e);
@@ -11546,20 +11627,57 @@ var DropDown = class extends Field {
11546
11627
  if (at >= 0) list.setActive(at, false);
11547
11628
  }
11548
11629
  }
11549
- renderField(item, text, placeholder, template) {
11630
+ renderField(items, value, valueText, placeholder, template) {
11550
11631
  const parts = this.dropParts;
11632
+ const { item, text, state } = this.valueLook(items, value, valueText);
11551
11633
  parts.releaseField();
11552
11634
  parts.releaseField = () => {};
11553
- const empty = item === void 0 && !text;
11635
+ parts.state = state;
11636
+ const loading = state === "loading";
11637
+ const empty = item === void 0 && !text && !loading;
11554
11638
  parts.text.toggleAttribute("data-placeholder", empty);
11555
- if (item !== void 0 && template) {
11639
+ parts.text.toggleAttribute("data-missing", state === "missing" || state === "failed");
11640
+ this.element.toggleAttribute("data-loading", loading);
11641
+ if (loading) parts.display.setAttribute("aria-busy", "true");
11642
+ else parts.display.removeAttribute("aria-busy");
11643
+ if (state !== "shown") this.followLanguage();
11644
+ if (loading) {
11645
+ const hidden = document.createElement("span");
11646
+ hidden.className = "mx-sr-only";
11647
+ hidden.textContent = uiLocale.strings.loading;
11648
+ parts.text.replaceChildren(hidden);
11649
+ this.addSpinner();
11650
+ } else if (item !== void 0 && template) {
11556
11651
  parts.text.replaceChildren();
11557
11652
  parts.releaseField = template(item, parts.text) ?? (() => {});
11558
11653
  } else parts.text.textContent = empty ? placeholder : text;
11654
+ if (state === "missing" || state === "failed") parts.text.title = state === "failed" ? uiLocale.strings.loadFailed : uiLocale.strings.notInList;
11655
+ else parts.text.removeAttribute("title");
11559
11656
  this.element.toggleAttribute("data-placeholder", !!placeholder);
11560
11657
  }
11658
+ /** The texts of the wait and of a missing key are the kit's: the field draws them again when its language changes. */
11659
+ followLanguage() {
11660
+ const parts = this.dropParts;
11661
+ if (parts.stopLanguage) return;
11662
+ const changed = uiLocale.onChanged(() => {
11663
+ if (!this.isDisposed && parts.state !== "shown") this.setProperty("refreshed", (this.peekProperty("refreshed") ?? 0) + 1);
11664
+ });
11665
+ parts.stopLanguage = () => changed.dispose();
11666
+ }
11667
+ /** The spinner in the arrow's place while the value's item is asked for; made the first time it is needed. */
11668
+ addSpinner() {
11669
+ const parts = this.dropParts;
11670
+ if (parts.spinner) return;
11671
+ const spinner = document.createElement("span");
11672
+ spinner.className = "mx-drop-down__spinner";
11673
+ spinner.setAttribute("aria-hidden", "true");
11674
+ this.area("actions").append(spinner);
11675
+ parts.spinner = spinner;
11676
+ }
11561
11677
  renderClear() {
11562
- this.showClearButton(!!this.peekProperty("clearButton"), (e) => this.commit(null, e), "mx-drop-down__clear");
11678
+ this.showClearButton(!!this.peekProperty("clearButton"), (e) => {
11679
+ if (this.dropParts.state !== "loading") this.commit(null, e);
11680
+ }, "mx-drop-down__clear");
11563
11681
  }
11564
11682
  };
11565
11683
  //#endregion
@@ -73312,7 +73430,7 @@ var AgendaView = class extends Component {
73312
73430
  onReState(this, () => this.draw());
73313
73431
  this.motif.setDisposable(host.keepDrawn(() => this.draw()));
73314
73432
  }
73315
- onMounted() {
73433
+ onConfig() {
73316
73434
  this.host.viewShown();
73317
73435
  }
73318
73436
  onDisposing() {