PageSourceSearch

https://www.eventeny.com/js/Components/Base/RadioSelectTile.js

js eventeny.com collected 2026-09-24 08:57:09 UTC 3,397 bytes, 93 lines download raw bytes

1/**
2 * RadioSelectTile - general-purpose tile group of selectable radio options.
3 *
4 * Configure with setTiles() after connection. Each tile descriptor:
5 *   { value: string, icon: string (SVG HTML), label: string, sublabel?: string, badge?: string (HTML) }
6 *
7 * Fires `selection-changed` (bubbles, composed) on tile click.
8 *   detail: { value: string }
9 *
10 * Methods:
11 *   setTiles(tiles)   configure and render tiles
12 *   reset()           clear selection
13 *   getValue()        return selected value, or ''
14 *
15 * Usage:
16 *   <radio-select-tile id="my-selector"></radio-select-tile>
17 *   el.setTiles([{ value: 'a', icon: '<svg>...</svg>', label: 'Option A', sublabel: 'Details' }]);
18 *   el.addEventListener('selection-changed', e => console.log(e.detail.value));
19 */
20
21import { WebComponent } from '/js/Components/Base/WebComponent.js';
22
23class RadioSelectTile extends WebComponent {
24
25    constructor() {
26        super();
27
28        const cssLink = document.createElement('link');
29        cssLink.rel   = 'stylesheet';
30        cssLink.href  = '/css/user/two-factor-modal.css';
31        this.shadowRoot.appendChild(cssLink);
32
33        const solidLink = document.createElement('link');
34        solidLink.rel   = 'stylesheet';
35        solidLink.href  = '/public/font-proxy.php?set=solid';
36        this.shadowRoot.appendChild(solidLink);
37
38        this._selected  = '';
39        this._tiles     = [];
40        this._group     = document.createElement('div');
41        this._group.className = 'mfa-radio-group';
42        this.shadowRoot.appendChild(this._group);
43    }
44
45    connectedCallback() {
46        this._group.addEventListener('click', e => {
47            const tile = e.target.closest('.mfa-radio-tile');
48            if (!tile) return;
49            this._group.querySelectorAll('.mfa-radio-tile').forEach(t => t.classList.remove('selected'));
50            tile.classList.add('selected');
51            tile.querySelector('input[type="radio"]').checked = true;
52            this._selected = tile.querySelector('input[type="radio"]').value;
53            this.dispatchEvent(new CustomEvent('selection-changed', {
54                bubbles:  true,
55                composed: true,
56                detail:   { value: this._selected },
57            }));
58        });
59    }
60
61    render() {}
62
63    setTiles(tiles) {
64        this._tiles = tiles;
65        this._group.innerHTML = tiles.map(t => `
66            <label class="mfa-radio-tile">
67                <input type="radio" name="radio-select-tile" value="${t.value}" />
68                ${t.icon ? `<div class="mfa-tile-icon">${t.icon}</div>` : ''}
69                <div class="mfa-tile-body">
70                    <div class="mfa-tile-label">
71                        ${t.label}
72                        ${t.badge ? `<span class="mfa-badge">${t.badge}</span>` : ''}
73                    </div>
74                    ${t.sublabel ? `<div class="mfa-tile-sublabel">${t.sublabel}</div>` : ''}
75                </div>
76            </label>
77        `).join('');
78    }
79
80    reset() {
81        this._selected = '';
82        this._group.querySelectorAll('input[type="radio"]').forEach(r => r.checked = false);
83        this._group.querySelectorAll('.mfa-radio-tile').forEach(t => t.classList.remove('selected'));
84    }
85
86    getValue() {
87        return this._selected;
88    }
89}
90
91if (!customElements.get('radio-select-tile')) {
92    customElements.define('radio-select-tile', RadioSelectTile);
93}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.