@web-atoms/web-controls 2.1.76 → 2.1.80

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.
@@ -0,0 +1,402 @@
1
+ import { AtomBinder } from "@web-atoms/core/dist/core/AtomBinder";
2
+ import Bind from "@web-atoms/core/dist/core/Bind";
3
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
4
+ import { IDisposable } from "@web-atoms/core/dist/core/types";
5
+ import XNode from "@web-atoms/core/dist/core/XNode";
6
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
7
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
8
+ import { PopupWindow } from "@web-atoms/core/dist/web/services/PopupService";
9
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
10
+
11
+ const popupCSS = CSS(StyleRule()
12
+ .height(500)
13
+ .width(300)
14
+ .verticalFlexLayout({ alignItems: "stretch" })
15
+ .child(StyleRule(".items")
16
+ .flexStretch()
17
+ .overflow("auto")
18
+ .child(StyleRule(".presenter")
19
+ .child(StyleRule("*")
20
+ .padding(5)
21
+ )
22
+ )
23
+ )
24
+ );
25
+
26
+ export type Match<T> = (text: string) => (item: T) => boolean;
27
+
28
+ export type IAskSuggestion<T> = (items: T[], itemRenderer: (item: T) => XNode, match: Match<T>) => any;
29
+
30
+ export const MatchTrue = (... a: any[]) => true;
31
+
32
+ export const MatchFalse = (... a: any[]) => false;
33
+
34
+ export const ArrowToString = (item) => item.label?.toString() ?? item.toString();
35
+
36
+ export const MatchCaseInsensitive = (textField?: (item) => string) => {
37
+ textField ??= ArrowToString;
38
+ return (s: string) => {
39
+ s = s.toLowerCase();
40
+ return (item) => textField(item)?.toLowerCase()?.includes(s);
41
+ };
42
+ };
43
+
44
+ export const SameObjectValue = (item) => item;
45
+
46
+ /**
47
+ * Asks user for selecting item from given suggestions
48
+ * @param items items to display
49
+ * @param itemRenderer render function
50
+ * @param match search match
51
+ * @returns selected item
52
+ */
53
+ export function askSuggestion<T>(
54
+ items: T[],
55
+ itemRenderer: (item: T) => XNode,
56
+ match: Match<T>): Promise<T> {
57
+ class Suggestions extends PopupWindow {
58
+
59
+ @BindableProperty
60
+ public search: string;
61
+
62
+ protected create(): void {
63
+ this.render(<div class={popupCSS}>
64
+ <input
65
+ type="search"
66
+ value={Bind.twoWaysImmediate(() => this.search)}
67
+ autofocus={true}/>
68
+ <div class="items">
69
+ <AtomRepeater
70
+ class="presenter"
71
+ itemRenderer={itemRenderer}
72
+ visibilityFilter={Bind.oneWay(() => match(this.search))}
73
+ eventItemClick={(e) => {
74
+ this.viewModel.close(e.detail);
75
+ }}
76
+ items={items}/>
77
+ </div>
78
+ </div>);
79
+ }
80
+ }
81
+
82
+ return Suggestions.showModal();
83
+ }
84
+
85
+ export interface ISelectorCheckBox {
86
+ text?: string;
87
+ iconSelected?: string;
88
+ icon?: string;
89
+ [key: string]: any;
90
+ }
91
+
92
+ CSS(StyleRule()
93
+ .nested(StyleRule("i[data-click-event]")
94
+ .padding(5)
95
+ )
96
+ , "*[data-selected-item]");
97
+
98
+ CSS(StyleRule()
99
+ .nested(StyleRule("i[data-click-event=item-select]")
100
+ .padding(5)
101
+ )
102
+ .displayNone(" i[data-click-event=item-select]")
103
+ , "*[data-selected-item=true]");
104
+
105
+ CSS(StyleRule()
106
+ .displayNone(" i[data-click-event=item-deselect]")
107
+ , "*[data-selected-item=false]");
108
+
109
+ export function SelectorCheckBox(
110
+ {
111
+ text,
112
+ icon = "far fa-square",
113
+ iconSelected = "fas fa-check-square",
114
+ ... a
115
+ }: ISelectorCheckBox,
116
+ ... nodes: XNode[]) {
117
+ if (text) {
118
+ return <label>
119
+ <i class={icon} data-click-event="item-select"/>
120
+ <i class={iconSelected} data-click-event="item-deselect"/>
121
+ <span text={text}/>
122
+ { ... nodes }
123
+ </label>;
124
+ }
125
+ return <label>
126
+ <i class={icon} data-click-event="item-select"/>
127
+ <i class={iconSelected} data-click-event="item-deselect"/>
128
+ { ... nodes }
129
+ </label>;
130
+ }
131
+
132
+ export default class AtomRepeater extends AtomControl {
133
+
134
+ public "event-item-click"?: (e: CustomEvent) => void;
135
+ public "event-item-select"?: (e: CustomEvent) => void;
136
+ public "event-item-deselect"?: (e: CustomEvent) => void;
137
+
138
+ @BindableProperty
139
+ public allowMultipleSelection: boolean;
140
+
141
+ @BindableProperty
142
+ public selectedItems: any[];
143
+
144
+ @BindableProperty
145
+ public itemsPresenter: any;
146
+
147
+ @BindableProperty
148
+ public items: any[];
149
+
150
+ @BindableProperty
151
+ public visibilityFilter: (item: any) => boolean;
152
+
153
+ @BindableProperty
154
+ public itemRenderer: (item) => XNode;
155
+
156
+ @BindableProperty
157
+ public valuePath: (a) => any;
158
+
159
+ public get value() {
160
+ if (this.initialValue !== undefined) {
161
+ return this.initialValue;
162
+ }
163
+ const vp = this.valuePath ?? SameObjectValue;
164
+ return vp(this.selectedItem);
165
+ }
166
+
167
+ public set value(v) {
168
+ this.initialValue = v;
169
+ if (!this.items) {
170
+ return;
171
+ }
172
+ const vp = this.valuePath ?? SameObjectValue;
173
+ const selectedItem = this.items.find((item) => vp(item) === v);
174
+ this.selectedItem = selectedItem;
175
+ delete this.initialValue;
176
+ }
177
+
178
+ public get selectedItem() {
179
+ return this.selectedItems?.[0];
180
+ }
181
+
182
+ public set selectedItem(value) {
183
+ const si = this.selectedItems ??= [];
184
+ const first = si[0];
185
+ if (value === first) {
186
+ return;
187
+ }
188
+ si.length = 0;
189
+ si[0] = value;
190
+ this.updateClasses();
191
+ AtomBinder.refreshValue(this, "selectedItem");
192
+ AtomBinder.refreshValue(this, "value");
193
+ }
194
+
195
+ private initialValue: any;
196
+
197
+ private itemsDisposable: IDisposable;
198
+
199
+ private selectedItemsDisposable: IDisposable;
200
+
201
+ public onPropertyChanged(name: string): void {
202
+ switch (name) {
203
+ case "items":
204
+ this.itemsDisposable?.dispose();
205
+ const items = this.items;
206
+ const d = items?.watch(() => {
207
+ this.updateItems();
208
+ AtomBinder.refreshValue(this, "selectedItem");
209
+ AtomBinder.refreshValue(this, "value");
210
+ });
211
+ if (d) {
212
+ this.itemsDisposable = this.registerDisposable(d);
213
+ }
214
+ const iv = this.initialValue;
215
+ if (iv) {
216
+ this.value = iv;
217
+ }
218
+ this.updateItems();
219
+ break;
220
+ case "selectedItems":
221
+ this.selectedItemsDisposable?.dispose();
222
+ const selectedItems = this.selectedItems;
223
+ const sd = selectedItems?.watch(() => {
224
+ this.updateClasses();
225
+ AtomBinder.refreshValue(this, "selectedItem");
226
+ AtomBinder.refreshValue(this, "value");
227
+ });
228
+ if (sd) {
229
+ this.selectedItemsDisposable = this.registerDisposable(sd);
230
+ }
231
+ this.updateClasses();
232
+ break;
233
+ case "itemRenderer":
234
+ this.updateItems();
235
+ break;
236
+ case "visibilityFilter":
237
+ this.updateVisibility();
238
+ break;
239
+ }
240
+ }
241
+
242
+ public forEach<T>(action: (item: T, element: HTMLElement) => void, container?: HTMLElement) {
243
+ container ??= this.itemsPresenter ?? this.element;
244
+ const items = this.items;
245
+ let start = container.firstElementChild as HTMLElement;
246
+ while (start) {
247
+ // tslint:disable-next-line: no-bitwise
248
+ const index = ~~start.dataset.itemIndex;
249
+ const item = items[index];
250
+ action(item, start);
251
+ start = start.nextElementSibling as HTMLElement;
252
+ }
253
+ }
254
+
255
+ public *any(fx?: (item) => boolean, itemSelector?: string, container?: HTMLElement) {
256
+ container ??= this.itemsPresenter ?? this.element;
257
+ const items = this.items;
258
+ let node = container.firstElementChild as HTMLElement;
259
+ while (node) {
260
+ // tslint:disable-next-line: no-bitwise
261
+ const index = ~~node.dataset.itemIndex;
262
+ const item = items[index];
263
+ let element = node;
264
+ if (itemSelector) {
265
+ element = element.querySelector(itemSelector);
266
+ }
267
+ const ie = { item, element };
268
+ if (fx) {
269
+ if (fx(item)) {
270
+ yield ie;
271
+ }
272
+ continue;
273
+ }
274
+ yield ie;
275
+ node = node.nextElementSibling as HTMLElement;
276
+ }
277
+ }
278
+
279
+ public *all(container?: HTMLElement) {
280
+ container ??= this.itemsPresenter ?? this.element;
281
+ const items = this.items;
282
+ let element = container.firstElementChild as HTMLElement;
283
+ while (element) {
284
+ // tslint:disable-next-line: no-bitwise
285
+ const index = ~~element.dataset.itemIndex;
286
+ const item = items[index];
287
+ yield { item, element };
288
+ element = element.nextElementSibling as HTMLElement;
289
+ }
290
+ }
291
+
292
+ public updateItems(container?: HTMLElement) {
293
+ container ??= this.itemsPresenter ?? this.element;
294
+ let start = container.firstElementChild;
295
+ while (start) {
296
+ const e = start as any;
297
+ start = start.nextElementSibling;
298
+ this.unbindEvent(e);
299
+ e.atomControl?.dispose();
300
+ e.remove();
301
+ }
302
+ const ir = this.itemRenderer;
303
+ if (!ir) {
304
+ return;
305
+ }
306
+ const items = this.items;
307
+ if (!items) {
308
+ return;
309
+ }
310
+
311
+ const vp = this.valuePath ?? ((it) => it);
312
+ const si = (this.selectedItems ?? []).map(vp);
313
+ let i = 0;
314
+ for (const iterator of items) {
315
+ const e = ir(iterator);
316
+ const ea = e.attributes ??= {};
317
+ const v = vp(iterator);
318
+ ea["data-item-index"] = (i++).toString();
319
+ ea["data-selected-item"] = si.indexOf(v) !== -1
320
+ ? "true"
321
+ : "false";
322
+ this.render(<div>
323
+ { e }
324
+ </div>, container, this);
325
+ }
326
+
327
+ }
328
+
329
+ protected updateClasses() {
330
+ const container = this.itemsPresenter ?? this.element;
331
+ const items = this.items;
332
+ let element = container.firstElementChild as HTMLElement;
333
+ const vp = this.valuePath ?? ((i) => i);
334
+ const si = (this.selectedItems ?? []).map(vp);
335
+ while (element) {
336
+ // tslint:disable-next-line: no-bitwise
337
+ const index = ~~element.dataset.itemIndex;
338
+ const item = items[index];
339
+ const v = vp(item);
340
+ element.dataset.selectedItem = si.indexOf(v) !== -1
341
+ ? "true"
342
+ : "false";
343
+ element = element.nextElementSibling as HTMLElement;
344
+ }
345
+
346
+ }
347
+
348
+ protected preCreate(): void {
349
+ this.bindEvent(this.element, "click", (e: MouseEvent) => this.onElementClick(e));
350
+ }
351
+
352
+ protected onElementClick(e: MouseEvent) {
353
+ const items = this.items;
354
+ let target = e.target as HTMLElement;
355
+ let eventName = "itemClick";
356
+ while (target) {
357
+ const itemIndex = target.dataset.itemIndex;
358
+ const itemClickEvent = target.dataset.clickEvent;
359
+ if (itemClickEvent) {
360
+ eventName = itemClickEvent.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
361
+ }
362
+ if (typeof itemIndex !== "undefined") {
363
+ // tslint:disable-next-line: no-bitwise
364
+ const item = items[~~itemIndex];
365
+ if (eventName === "itemSelect" || eventName === "itemDeselect") {
366
+ const si = this.selectedItems;
367
+ if (si) {
368
+ const index = si.indexOf(item);
369
+ if (index === -1) {
370
+ si.add(item);
371
+ } else {
372
+ si.removeAt(index);
373
+ }
374
+ }
375
+ }
376
+ if (item) {
377
+ this.element.dispatchEvent(new CustomEvent(eventName, {
378
+ detail: item,
379
+ bubbles: false
380
+ }));
381
+ }
382
+ return;
383
+ }
384
+ target = target.parentElement as HTMLElement;
385
+ }
386
+ }
387
+
388
+ protected updateVisibility() {
389
+ const container = this.itemsPresenter ?? this.element;
390
+ const items = this.items;
391
+ let element = container.firstElementChild as HTMLElement;
392
+ const vf = this.visibilityFilter ?? MatchTrue;
393
+ while (element) {
394
+ // tslint:disable-next-line: no-bitwise
395
+ const index = ~~element.dataset.itemIndex;
396
+ const item = items[index];
397
+ element.style.display = vf(item) ? "" : "none";
398
+ element = element.nextElementSibling as HTMLElement;
399
+ }
400
+ }
401
+
402
+ }
@@ -0,0 +1,56 @@
1
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
2
+ import Colors from "@web-atoms/core/dist/core/Colors";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
5
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
6
+ import AtomRepeater from "./AtomRepeater";
7
+
8
+ CSS(StyleRule()
9
+ .flexLayout({ inline: true, justifyContent: "flex-start"})
10
+ .flexFlow("wrap"),
11
+ "div[data-checkbox-list=checkbox-list]");
12
+
13
+ CSS(StyleRule()
14
+ .flexLayout({ justifyContent: "flex-start" })
15
+ .marginRight(5)
16
+ .child(StyleRule("span")
17
+ .cursor("pointer")
18
+ )
19
+ .and(StyleRule("[data-selected-item=true]")
20
+ .color(Colors.blue)
21
+ )
22
+ .displayNone("[data-selected-item=true] > i.far")
23
+ .displayNone("[data-selected-item=false] > i.fas")
24
+ , "div[data-item-type=checkbox]");
25
+
26
+ export default class CheckBoxList extends AtomRepeater {
27
+
28
+ @BindableProperty
29
+ public labelPath;
30
+
31
+ protected preCreate(): void {
32
+ super.preCreate();
33
+ this.element.dataset.checkboxList = "checkbox-list";
34
+ this.bindEvent(this.element, "itemClick", (e: CustomEvent) => {
35
+ const s = this.selectedItems;
36
+ if (!s) {
37
+ return;
38
+ }
39
+ const item = e.detail;
40
+ if (s.indexOf(item) === -1) {
41
+ s.add(item);
42
+ this.element.dispatchEvent(new CustomEvent("itemSelect", { detail: item, bubbles: false }));
43
+ } else {
44
+ this.element.dispatchEvent(new CustomEvent("itemDeselect", { detail: item, bubbles: false }));
45
+ s.remove(item);
46
+ }
47
+ });
48
+
49
+ this.itemRenderer = (item) => <div data-item-type="checkbox">
50
+ <i class="far fa-square"/>
51
+ <i class="fas fa-check-square"/>
52
+ <span text={item.label}/>
53
+ </div>;
54
+ }
55
+
56
+ }
@@ -0,0 +1,56 @@
1
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
2
+ import XNode from "@web-atoms/core/dist/core/XNode";
3
+ import AtomRepeater from "./AtomRepeater";
4
+
5
+ export default class ComboBox extends AtomRepeater {
6
+
7
+ @BindableProperty
8
+ public labelPath: any;
9
+
10
+ private isChanging = false;
11
+
12
+ constructor(app, e) {
13
+ super(app, e ?? document.createElement("select"));
14
+ }
15
+
16
+ public updateItems(container?: HTMLElement): void {
17
+ super.updateItems(container);
18
+ if (this.isChanging) {
19
+ return;
20
+ }
21
+ const selectedItems = this.selectedItems;
22
+ if (!selectedItems) {
23
+ return;
24
+ }
25
+ if (selectedItems.length === 0) {
26
+ return;
27
+ }
28
+ this.isChanging = true;
29
+ const first = selectedItems[0];
30
+ (this.element as HTMLSelectElement).selectedIndex = this.items.indexOf(first);
31
+ this.isChanging = false;
32
+ }
33
+
34
+ protected preCreate(): void {
35
+ super.preCreate();
36
+ this.labelPath = (item) => item?.label ?? item.toString();
37
+ this.valuePath = (item) => item?.value ?? item.toString();
38
+ this.itemRenderer = (item) => <option>{this.labelPath(item)}</option>;
39
+
40
+ this.bindEvent(this.element, "change", () => this.changeSelection());
41
+ }
42
+
43
+ protected changeSelection(): void {
44
+ if (this.isChanging) {
45
+ return;
46
+ }
47
+ this.isChanging = true;
48
+ this.selectedItems?.clear();
49
+ const index = (this.element as HTMLSelectElement).selectedIndex;
50
+ if (index !== -1) {
51
+ this.selectedItems?.add(this.items[index]);
52
+ }
53
+ this.isChanging = false;
54
+ }
55
+
56
+ }
@@ -0,0 +1,81 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind";
2
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
5
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
6
+ import { PopupWindow } from "@web-atoms/core/dist/web/services/PopupService";
7
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
8
+ import AtomRepeater, { askSuggestion, Match, MatchCaseInsensitive } from "./AtomRepeater";
9
+
10
+ CSS(StyleRule()
11
+ .flexLayout({ inline: true, justifyContent: "stretch" as any})
12
+ , "div[data-drop-down=drop-down]");
13
+
14
+ export default class DropDown extends AtomRepeater {
15
+
16
+ @BindableProperty
17
+ public prompt: string;
18
+
19
+ @BindableProperty
20
+ public labelPath: (item) => string;
21
+
22
+ @BindableProperty
23
+ public match: Match<any>;
24
+
25
+ @BindableProperty
26
+ public suggestionRenderer: (item) => XNode;
27
+
28
+ public updateItems(container?: HTMLElement): void {
29
+ // don't do anything...
30
+ }
31
+
32
+ public onPropertyChanged(name: string): void {
33
+ super.onPropertyChanged(name);
34
+ switch (name) {
35
+ case "labelPath":
36
+ this.itemRenderer = (item) => <div text={this.labelPath(item)}/>;
37
+ break;
38
+ case "prompt":
39
+ this.updateClasses();
40
+ break;
41
+ }
42
+ }
43
+
44
+ protected preCreate(): void {
45
+ // super.preCreate();
46
+ this.prompt = "Select";
47
+ this.bindEvent(this.element, "click", () => this.openPopup());
48
+ this.valuePath = (item) => item?.value ?? item;
49
+ this.labelPath = (item) => item?.label ?? item;
50
+ this.itemRenderer = (item) => <div text={this.labelPath(item)}/>;
51
+ this.element.dataset.dropDown = "drop-down";
52
+ }
53
+
54
+ protected async openPopup() {
55
+ const selected = await askSuggestion(
56
+ this.items,
57
+ this.suggestionRenderer ?? this.itemRenderer,
58
+ this.match ?? MatchCaseInsensitive(this.labelPath));
59
+ this.selectedItem = selected;
60
+ }
61
+
62
+ protected updateClasses(): void {
63
+ this.removeAllChildren(this.element);
64
+ const ir = this.itemRenderer;
65
+ if (!ir) {
66
+ return;
67
+ }
68
+ if (!this.selectedItem) {
69
+ this.render(<div>
70
+ <div text={this.prompt}/>
71
+ <i class="fad fa-caret-circle-down"/>
72
+ </div>);
73
+ return;
74
+ }
75
+ this.render(<div>
76
+ { ir(this.selectedItem) }
77
+ <i class="fad fa-caret-circle-down"/>
78
+ </div>);
79
+ }
80
+
81
+ }
@@ -39,6 +39,7 @@ const css = CSS(StyleRule()
39
39
  )
40
40
  )
41
41
  .child(StyleRule(".label")
42
+ .display("flex")
42
43
  .child(StyleRule(".true")
43
44
  .visibility("visible")
44
45
  .color(Colors.red)
@@ -48,7 +49,8 @@ const css = CSS(StyleRule()
48
49
  )
49
50
  .child(StyleRule("i")
50
51
  .cursor("pointer")
51
- .marginLeft(5)
52
+ .marginLeft("auto")
53
+ .color(Colors.lightGreen)
52
54
  )
53
55
  )
54
56
  , "div[data-wa-form-field=wa-form-field]");
@@ -58,7 +60,7 @@ export default function FormField(
58
60
  label,
59
61
  required,
60
62
  error,
61
- helpIcon = "fad fa-question-circle",
63
+ helpIcon = "fas fa-question-circle",
62
64
  help,
63
65
  helpEventClick,
64
66
  helpTitle,
@@ -0,0 +1,56 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind";
2
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
3
+ import Colors from "@web-atoms/core/dist/core/Colors";
4
+ import XNode from "@web-atoms/core/dist/core/XNode";
5
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
6
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
7
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
8
+ import AtomRepeater from "./AtomRepeater";
9
+
10
+ CSS(StyleRule()
11
+ .flexLayout({ inline: true, justifyContent: "flex-start"})
12
+ .flexFlow("wrap"),
13
+ "*[data-radio-button-list=radio-button-list]");
14
+
15
+ CSS(StyleRule()
16
+ .flexLayout({ justifyContent: "flex-start" })
17
+ .marginRight(5)
18
+ .child(StyleRule("span")
19
+ .cursor("pointer")
20
+ )
21
+ .and(StyleRule("[data-selected-item=true]")
22
+ .color(Colors.blue)
23
+ )
24
+ .displayNone("[data-selected-item=true] > i.fa-circle")
25
+ .displayNone("[data-selected-item=false] > i.fa-dot-circle")
26
+ , "div[data-item-type=radio]");
27
+
28
+ export default class RadioButtonList extends AtomRepeater {
29
+
30
+ protected preCreate(): void {
31
+ super.preCreate();
32
+ this.valuePath = (item) => item?.value ?? item;
33
+ this.bindEvent(this.element, "itemClick", (e: CustomEvent) => {
34
+ const s = this.selectedItems;
35
+ if (!s) {
36
+ return;
37
+ }
38
+ const item = e.detail;
39
+ const old = this.selectedItem;
40
+ if (old) {
41
+ this.element.dispatchEvent(new CustomEvent("itemDeselect", { detail: old, bubbles: false }));
42
+ }
43
+ this.selectedItem = item;
44
+ this.element.dispatchEvent(new CustomEvent("itemSelect", { detail: item, bubbles: false }));
45
+ });
46
+ this.element.dataset.radioButtonList = "radio-button-list";
47
+ this.itemRenderer = (item) => <div
48
+ data-item-type="radio">
49
+ <i class="far fa-dot-circle"/>
50
+ <i class="far fa-circle"/>
51
+ <span text={item.label}/>
52
+ </div>;
53
+
54
+ }
55
+
56
+ }