PageSourceSearch

https://www.eventeny.com/js/Layouts/FieldPanel.js?v=1790189618

js eventeny.com collected 2026-09-24 08:55:53 UTC 3,543 bytes, 109 lines download raw bytes

1/**
2 * @file FieldPanel.js
3 * @description A layout-only web component that provides the gray panel chrome used in the bulk
4 * editor sidebar (background, padding, optional header). All content is slotted and stays in the
5 * light DOM — fully queryable from outside. No business logic or internal state.
6 *
7 * @class FieldPanel
8 * @extends WebComponent
9 *
10 * @example
11 * <!-- Basic panel with header -->
12 * <field-panel-element title="Pricing" subtitle="Set price and fees">
13 *     <form-field-element type="number" label="Price" prefix="$"></form-field-element>
14 * </field-panel-element>
15 *
16 * @example
17 * <!-- Bulk editor panel (activated by sidebar JS via data-field) -->
18 * <field-panel-element data-field="status" data-size="half" title="Status">
19 *     <form-field-element type="dropdown" label="Ticket status"></form-field-element>
20 * </field-panel-element>
21 *
22 * @attribute {string} title     - Bold header title (plain text, HTML-escaped)
23 * @attribute {string} subtitle  - Gray subtext rendered below the title
24 * @attribute data-field         - Identifies the bulk editor field; read by sidebar JS to show/hide the panel
25 * @attribute data-size          - 'half' | 'full' — controls grid column span in the values grid
26 */
27import { WebComponent } from '../Components/Base/WebComponent.js';
28
29class FieldPanel extends WebComponent {
30    static get observedAttributes() {
31        return ['title', 'subtitle'];
32    }
33
34    _built = false;
35
36    constructor() {
37        super();
38        this.loadBaseCSS();
39    }
40
41    connectedCallback() {
42        if (this._built) return;
43        this._built = true;
44        this.render();
45    }
46
47    attributeChangedCallback(name, oldVal, newVal) {
48        if (oldVal === newVal || !this._built) return;
49        this.render();
50    }
51
52    render() {
53        const title    = this.getAttribute('title')    || '';
54        const subtitle = this.getAttribute('subtitle') || '';
55
56        this.loadTemplate(`
57            <style>${this._styles()}</style>
58            <div class="fp-panel">
59                ${title ? `
60                <div class="fp-header flex flex-column gap-4">
61                    <span class="fp-title">${this._esc(title)}</span>
62                    ${subtitle ? `<span class="fp-subtitle font-14">${this._esc(subtitle)}</span>` : ''}
63                </div>` : ''}
64                <slot></slot>
65            </div>
66        `);
67    }
68
69    _esc(str) {
70        return String(str || '')
71            .replace(/&/g, '&amp;')
72            .replace(/</g, '&lt;')
73            .replace(/>/g, '&gt;')
74            .replace(/"/g, '&quot;');
75    }
76
77    _styles() {
78        return `
79            /* Top-level bulk editor field: hidden until activated by sidebar JS */
80            :host([data-field])           { display: none; }
81            :host([data-field].is-active) { display: block; }
82            /* Full-width span in the values grid */
83            :host([data-size="full"]), :host(.is-col-full) { grid-column: 1 / -1; }
84
85            .fp-panel {
86                background: #F5F6F6;
87                border-radius: 6px;
88                padding: 24px;
89            }
90
91            .fp-header {
92                margin-bottom: 16px;
93            }
94
95            .fp-title {
96                font-weight: 600;
97            }
98
99            /* subtitle uses .font-14 from base CSS; color override here */
100            .fp-subtitle {
101                color: #5E6463;
102            }
103        `;
104    }
105}
106
107if (!customElements.get('field-panel-element')) {
108    customElements.define('field-panel-element', FieldPanel);
109}

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.