@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.
- package/CHANGELOG.md +18 -0
- package/dist/components/dropdown/DropDown.d.ts +14 -0
- package/dist/components/dropdown/drop-down-props.d.ts +5 -0
- package/dist/components/scheduler/view/AgendaView.d.ts +1 -1
- package/dist/core/ui-strings.d.ts +2 -0
- package/dist/generated/tokens.d.ts +40 -0
- package/dist/index.js +133 -15
- package/dist/index.js.map +1 -1
- package/dist/locales/en.json +1 -0
- package/dist/locales/tr.json +1 -0
- package/dist/parts/data/DataItems.d.ts +5 -0
- package/dist/parts/data/KeyedItems.d.ts +2 -0
- package/dist/styles.css +87 -3
- package/dist/tokens/index.d.ts +40 -0
- package/dist/tokens/index.js +40 -0
- package/dist/tokens/index.js.map +1 -1
- package/docs/accordion.md +1 -1
- package/docs/actionsheet.md +1 -1
- package/docs/avatar.md +1 -1
- package/docs/badge.md +1 -1
- package/docs/bottomsheet.md +1 -1
- package/docs/breadcrumb.md +1 -1
- package/docs/button.md +1 -1
- package/docs/buttongroup.md +1 -1
- package/docs/calendar.md +1 -1
- package/docs/card.md +1 -1
- package/docs/checkbox.md +1 -1
- package/docs/chip.md +1 -1
- package/docs/colorbox.md +1 -1
- package/docs/combobox.md +1 -1
- package/docs/control.md +1 -1
- package/docs/datagrid-api.md +1 -1
- package/docs/datagrid-bands.md +1 -1
- package/docs/datagrid-drag-select.md +1 -1
- package/docs/datagrid-drag.md +1 -1
- package/docs/datagrid-editing.md +1 -1
- package/docs/datagrid-filtering.md +1 -1
- package/docs/datagrid-forms.md +1 -1
- package/docs/datagrid-grouping.md +1 -1
- package/docs/datagrid-layout.md +1 -1
- package/docs/datagrid-lookups.md +1 -1
- package/docs/datagrid-master-detail.md +1 -1
- package/docs/datagrid-scrolling.md +1 -1
- package/docs/datagrid-selection.md +1 -1
- package/docs/datagrid.md +1 -1
- package/docs/datebox.md +1 -1
- package/docs/drawer.md +1 -1
- package/docs/dropdown.md +11 -5
- package/docs/filterbuilder.md +1 -1
- package/docs/formlayout.md +1 -1
- package/docs/home.md +1 -1
- package/docs/keyboard.md +1 -1
- package/docs/layout.md +1 -1
- package/docs/listbox.md +1 -1
- package/docs/lookup.md +86 -2
- package/docs/menus.md +1 -1
- package/docs/numberbox.md +1 -1
- package/docs/pagination.md +1 -1
- package/docs/progress.md +1 -1
- package/docs/radiogroup.md +1 -1
- package/docs/rating.md +1 -1
- package/docs/scheduler-agenda.md +1 -1
- package/docs/scheduler-big-data.md +1 -1
- package/docs/scheduler-editing.md +1 -1
- package/docs/scheduler-form.md +1 -1
- package/docs/scheduler-icalendar.md +1 -1
- package/docs/scheduler-mobile.md +1 -1
- package/docs/scheduler-recurrence.md +1 -1
- package/docs/scheduler-resources.md +1 -1
- package/docs/scheduler-timeline.md +1 -1
- package/docs/scheduler.md +1 -1
- package/docs/showcase.md +1 -1
- package/docs/skeleton.md +1 -1
- package/docs/slider.md +1 -1
- package/docs/switch.md +1 -1
- package/docs/tabdocs-dock.md +1 -1
- package/docs/tabdocs-drag.md +1 -1
- package/docs/tabdocs-menus.md +1 -1
- package/docs/tabdocs-mobile.md +1 -1
- package/docs/tabdocs-tabs.md +1 -1
- package/docs/tabdocs-windows.md +1 -1
- package/docs/tabdocs-workspace.md +1 -1
- package/docs/tabdocs.md +1 -1
- package/docs/tabs.md +1 -1
- package/docs/tagbox.md +1 -1
- package/docs/textarea.md +1 -1
- package/docs/textbox.md +1 -1
- package/docs/toast.md +1 -1
- package/docs/tokens.md +9 -1
- package/docs/toolbar.md +1 -1
- package/docs/tooltip.md +1 -1
- package/docs/treeview.md +1 -1
- package/docs/window.md +1 -1
- package/llms-full.txt +181 -83
- package/llms.txt +1 -1
- 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
|
-
|
|
30
|
+
onConfig(): void;
|
|
31
31
|
onDisposing(): void;
|
|
32
32
|
/** All of the list, as the model has it now. */
|
|
33
33
|
draw(): void;
|
|
@@ -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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
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
|
-
|
|
73433
|
+
onConfig() {
|
|
73316
73434
|
this.host.viewShown();
|
|
73317
73435
|
}
|
|
73318
73436
|
onDisposing() {
|