@kodaris/krubble-components 1.0.48 → 1.0.49

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.
@@ -312,7 +312,7 @@
312
312
  {
313
313
  "kind": "variable",
314
314
  "name": "KRTable",
315
- "default": "class KRTable extends i$2 { constructor() { super(...arguments); /** * Internal flag to switch between scroll edge modes: * - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge) * - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling */ this._scrollStyle = 'overlay'; this._data = []; this._dataState = 'idle'; this._page = 1; this._pageSize = 50; this._totalItems = 0; this._totalPages = 0; this._searchQuery = ''; this._canScrollLeft = false; this._canScrollRight = false; this._canScrollHorizontal = false; this._columnPickerOpen = false; this._displayedColumns = []; this._resizing = null; this._resizeObserver = null; this._searchPositionLocked = false; this._def = { columns: [] }; this.def = { columns: [] }; this._handleClickOutsideColumnPicker = (e) => { if (!this._columnPickerOpen) return; const path = e.composedPath(); const picker = this.shadowRoot?.querySelector('.column-picker-wrapper'); if (picker && !path.includes(picker)) { this._columnPickerOpen = false; } }; this._handleResizeMove = (e) => { if (!this._resizing) return; const col = this._def.columns.find(c => c.id === this._resizing.columnId); if (col) { const newWidth = this._resizing.startWidth + (e.clientX - this._resizing.startX); col.width = `${Math.min(900, Math.max(50, newWidth))}px`; this.requestUpdate(); } }; this._handleResizeEnd = () => { this._resizing = null; document.removeEventListener('mousemove', this._handleResizeMove); document.removeEventListener('mouseup', this._handleResizeEnd); }; } connectedCallback() { super.connectedCallback(); this.classList.toggle('kr-table--scroll-overlay', this._scrollStyle === 'overlay'); this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge'); this._fetch(); this._initRefresh(); document.addEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver = new ResizeObserver(() => { // Unlock and recalculate on resize since layout changes this._searchPositionLocked = false; this._updateSearchPosition(); }); this._resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); clearInterval(this._refreshTimer); document.removeEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver?.disconnect(); } willUpdate(changedProperties) { if (changedProperties.has('def')) { // Copy user's def and normalize action columns this._def = { ...this.def, columns: this.def.columns.map(col => { if (col.type === 'actions') { return { ...col, label: col.label ?? '', sticky: 'right', resizable: false }; } return { ...col }; }) }; this._displayedColumns = this._def.displayedColumns || this._def.columns.map(c => c.id); this._fetch(); this._initRefresh(); } } updated(changedProperties) { this._updateScrollFlags(); this._syncSlottedContent(); } /** Syncs light DOM content for cells with custom render functions */ _syncSlottedContent() { const columns = this.getDisplayedColumns().filter(col => col.render); if (!columns.length) return; // Clear old slotted content this.querySelectorAll('[slot^=\"cell-\"]').forEach(el => el.remove()); // Create new slotted content this._data.forEach((row, rowIndex) => { columns.forEach(col => { const result = col.render(row); const content = typeof result === 'string' ? result : ''; if (content) { const el = document.createElement('span'); el.slot = `cell-${rowIndex}-${col.id}`; if (col.type === 'actions') { el.style.display = 'flex'; el.style.gap = '8px'; } el.innerHTML = content; this.appendChild(el); } }); }); } // ---------------------------------------------------------------------------- // Public Interface // ---------------------------------------------------------------------------- refresh() { this._fetch(); } goToPrevPage() { if (this._page > 1) { this._page--; this._fetch(); } } goToNextPage() { if (this._page < this._totalPages) { this._page++; this._fetch(); } } goToPage(page) { if (page >= 1 && page <= this._totalPages) { this._page = page; this._fetch(); } } // ---------------------------------------------------------------------------- // Data Fetching // ---------------------------------------------------------------------------- /** * Fetches data from the API and updates the table. * Shows a loading spinner while fetching, then displays rows on success * or an error snackbar on failure. * Request/response format depends on dataSource.mode (solr, opensearch, db). */ _fetch() { if (!this._def.dataSource) return; this._dataState = 'loading'; // Build request based on mode let request; switch (this._def.dataSource.mode) { case 'opensearch': throw Error('Opensearch not supported yet'); case 'db': request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { this._def.columns.filter(col => col.searchable).forEach(col => { request.queryFields.push({ name: col.id, operation: 'CONTAINS', value: this._searchQuery, and: false }); }); } break; default: // solr request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { request.queryFields.push({ name: '_text_', operation: 'IS', value: escapeSolrQuery(this._searchQuery) }); } } this._def.dataSource.fetch(request) .then(response => { // Parse response based on mode switch (this._def.dataSource?.mode) { case 'opensearch': { throw Error('Opensearch not supported yet'); } case 'db': { const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; break; } default: { // solr const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; } } this._dataState = 'success'; this._updateSearchPosition(); }) .catch(err => { this._dataState = 'error'; KRSnackbar.show({ message: err instanceof Error ? err.message : 'Failed to load data', type: 'error' }); }); } /** * Sets up auto-refresh so the table automatically fetches fresh data * at a regular interval (useful for dashboards, monitoring views). * Configured via def.refreshInterval in milliseconds. */ _initRefresh() { clearInterval(this._refreshTimer); if (this._def.refreshInterval && this._def.refreshInterval > 0) { this._refreshTimer = window.setInterval(() => { this._fetch(); }, this._def.refreshInterval); } } _handleSearch(e) { const input = e.target; this._searchQuery = input.value; this._page = 1; this._fetch(); } _getGridTemplateColumns() { const cols = this.getDisplayedColumns(); return cols.map((col) => { // If column has explicit width, use it if (col.width) { return col.width; } // Actions columns: fit content without minimum if (col.type === 'actions') { return 'max-content'; } // No width specified - use content-based sizing with minimum return 'minmax(80px, auto)'; }).join(' '); } /** * Updates search position to be centered with equal gaps from title and tools. * On first call: resets to flex centering, measures position, then locks with fixed margin. * Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize). */ _updateSearchPosition() { // Skip if already locked (prevents shifts on pagination changes) if (this._searchPositionLocked) return; const search = this.shadowRoot?.querySelector('.search'); const searchField = search?.querySelector('.search-field'); if (!search || !searchField) return; // Reset to flex centering search.style.justifyContent = 'center'; searchField.style.marginLeft = ''; requestAnimationFrame(() => { const searchRect = search.getBoundingClientRect(); const fieldRect = searchField.getBoundingClientRect(); // Calculate how far from the left of search container the field currently is const currentOffset = fieldRect.left - searchRect.left; // Lock position: switch to flex-start and use fixed margin search.style.justifyContent = 'flex-start'; searchField.style.marginLeft = `${currentOffset}px`; // Mark as locked so pagination changes don't shift the search this._searchPositionLocked = true; }); } // ---------------------------------------------------------------------------- // Columns // ---------------------------------------------------------------------------- _toggleColumnPicker() { this._columnPickerOpen = !this._columnPickerOpen; } _toggleColumn(columnId) { if (this._displayedColumns.includes(columnId)) { this._displayedColumns = this._displayedColumns.filter(id => id !== columnId); } else { this._displayedColumns = [...this._displayedColumns, columnId]; } } // Clear any existing text selection on mousedown so we only detect // selections made during this click gesture, not stale selections from elsewhere _handleRowMouseDown() { if (!this._def.rowClickable) { return; } window.getSelection()?.removeAllRanges(); } _handleRowClick(row, rowIndex) { if (!this._def.rowClickable) { return; } const selection = window.getSelection(); if (selection && selection.toString().length > 0) { return; } this.dispatchEvent(new CustomEvent('row-click', { detail: { row, rowIndex }, bubbles: true, composed: true })); } // When a user toggles a column on via the column picker, it gets appended // to _displayedColumns. By mapping over _displayedColumns (not def.columns), // the new column appears at the right edge of the table instead of jumping // back to its original position in the column definition. // Actions columns are always moved to the end. getDisplayedColumns() { return this._displayedColumns .map(id => this._def.columns.find(col => col.id === id)) .sort((a, b) => { if (a.type === 'actions' && b.type !== 'actions') return 1; if (a.type !== 'actions' && b.type === 'actions') return -1; return 0; }); } // ---------------------------------------------------------------------------- // Scrolling // ---------------------------------------------------------------------------- /** * Scroll event handler that updates scroll flags in real-time as user scrolls. * Updates shadow indicators to show if more content exists left/right. */ _handleScroll(e) { const container = e.target; this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1; } /** * Updates scroll state flags for the table content container. * - _canScrollLeft: true if scrolled right (can scroll back left) * - _canScrollRight: true if more content exists to the right * - _canScrollHorizontal: true if content is wider than container * These flags control scroll shadow indicators and CSS classes. */ _updateScrollFlags() { const container = this.shadowRoot?.querySelector('.content'); if (container) { this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1; this._canScrollHorizontal = container.scrollWidth > container.clientWidth; } this.classList.toggle('kr-table--scroll-left-available', this._canScrollLeft); this.classList.toggle('kr-table--scroll-right-available', this._canScrollRight); this.classList.toggle('kr-table--scroll-horizontal-available', this._canScrollHorizontal); this.classList.toggle('kr-table--sticky-left', this.getDisplayedColumns().some(c => c.sticky === 'left')); this.classList.toggle('kr-table--sticky-right', this.getDisplayedColumns().some(c => c.sticky === 'right')); } // ---------------------------------------------------------------------------- // Column Resizing // ---------------------------------------------------------------------------- _handleResizeStart(e, columnId) { e.preventDefault(); const headerCell = this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${columnId}\"]`); this._resizing = { columnId, startX: e.clientX, startWidth: headerCell?.offsetWidth || 200 }; document.addEventListener('mousemove', this._handleResizeMove); document.addEventListener('mouseup', this._handleResizeEnd); } // ---------------------------------------------------------------------------- // Header // ---------------------------------------------------------------------------- _handleAction(action) { if (action.href) { return; } this.dispatchEvent(new CustomEvent('action', { detail: { action: action.id }, bubbles: true, composed: true })); } // ---------------------------------------------------------------------------- // Rendering // ---------------------------------------------------------------------------- _renderCellContent(column, row, rowIndex) { const value = row[column.id]; if (column.render) { // Use slot to project content from light DOM so external styles apply return b `<slot name=\"cell-${rowIndex}-${column.id}\"></slot>`; } if (value === null || value === undefined) { return ''; } switch (column.type) { case 'number': return typeof value === 'number' ? value.toLocaleString() : String(value); case 'currency': return typeof value === 'number' ? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }) : String(value); case 'date': { let date; if (value instanceof Date) { date = value; } else if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(value)) { // MySQL datetime format (UTC): \"2026-01-28 01:33:44:517\" // Replace last colon before ms with dot, append Z for UTC const isoString = value.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/, '$1.$2').replace(' ', 'T') + 'Z'; date = new Date(isoString); } else { date = new Date(value); } // Show date and time for datetime values return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); } case 'boolean': if (value === true) return 'Yes'; if (value === false) return 'No'; return ''; default: return String(value); } } /** * Returns CSS classes for a header cell based on column config. */ _getHeaderCellClasses(column, index) { return { 'header-cell': true, 'header-cell--align-center': column.align === 'center', 'header-cell--align-right': column.align === 'right', 'header-cell--sticky-left': column.sticky === 'left', 'header-cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'header-cell--sticky-right': column.sticky === 'right', 'header-cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns CSS classes for a table cell based on column config: * - Alignment (center, right) * - Sticky positioning (left, right) * - Border classes for the last left-sticky or first right-sticky column */ _getCellClasses(column, index) { return { 'cell': true, 'cell--actions': column.type === 'actions', 'cell--align-center': column.align === 'center', 'cell--align-right': column.align === 'right', 'cell--sticky-left': column.sticky === 'left', 'cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'cell--sticky-right': column.sticky === 'right', 'cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns inline styles for a table cell: * - Width (from column config or default 150px) * - Min-width (if specified) * - Left/right offset for sticky columns (calculated from widths of preceding sticky columns) */ _getCellStyle(column, index) { const styles = {}; if (column.sticky === 'left') { let leftOffset = 0; for (let i = 0; i < index; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'left') { leftOffset += parseInt(col.width || '0', 10); } } styles.left = `${leftOffset}px`; } if (column.sticky === 'right') { let rightOffset = 0; for (let i = index + 1; i < this.getDisplayedColumns().length; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'right') { rightOffset += parseInt(col.width || '0', 10); } } styles.right = `${rightOffset}px`; } return styles; } /** * Renders the pagination controls: * - Previous page arrow (disabled on first page) * - Range text showing \"1-50 of 150\" format * - Next page arrow (disabled on last page) * * Hidden when there's no data or all data fits on one page. */ _renderPagination() { const start = (this._page - 1) * this._pageSize + 1; const end = Math.min(this._page * this._pageSize, this._totalItems); return b ` <div class=\"pagination\"> <span class=\"pagination-icon ${this._page === 1 ? 'pagination-icon--disabled' : ''}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${start}-${end} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page === this._totalPages ? 'pagination-icon--disabled' : ''}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `; } /** * Renders the header toolbar containing: * - Title (left) * - Search bar with view selector dropdown (center) * - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown * * Hidden when there's no title, no actions, and data fits on one page. */ _renderHeader() { if (!this._def.title && !this._def.actions?.length && this._totalPages <= 1) { return A; } return b ` <div class=\"header\"> <div class=\"title\">${this._def.title ?? ''}</div> ${this._def.dataSource?.mode === 'db' && !this._def.columns.some(col => col.searchable) ? b `<div class=\"search\"></div>` : b ` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${() => this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen ? 'open' : ''}\"> ${[...this._def.columns].filter(col => col.type !== 'actions').sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => b ` <div class=\"column-picker-item\" @click=${() => this._toggleColumn(col.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(col.id) ? 'checked' : ''}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${col.label ?? col.id}</span> </div> `)} </div> </div> ${this._def.actions?.length === 1 ? b ` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${() => this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> ` : this._def.actions?.length ? b ` <kr-button class=\"actions\" .options=${this._def.actions.map(a => ({ id: a.id, label: a.label }))} @option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })} > Actions </kr-button> ` : A} </div> </div> `; } /** Renders status message (loading, error, empty) */ _renderStatus() { if (this._dataState === 'loading' && this._data.length === 0) { return b `<div class=\"status\">Loading...</div>`; } if (this._dataState === 'error' && this._data.length === 0) { return b `<div class=\"status status--error\">Error loading data</div>`; } if (this._data.length === 0) { return b `<div class=\"status\">No data available</div>`; } return A; } /** Renders the scrollable data grid with column headers and rows. */ _renderTable() { return b ` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map((col, i) => b ` <div class=${e$1(this._getHeaderCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} >${col.label ?? col.id}${col.resizable !== false ? b `<div class=\"header-cell__resize\" @mousedown=${(e) => this._handleResizeStart(e, col.id)} ></div>` : A}</div> `)} </div> ${this._data.map((row, rowIndex) => { const cells = this.getDisplayedColumns().map((col, i) => b ` <div class=${e$1(this._getCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} > ${this._renderCellContent(col, row, rowIndex)} </div> `); if (this._def.rowHref) { return b ` <a href=${this._def.rowHref(row)} class=${e$1({ 'row': true, 'row--clickable': true, 'row--link': true })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</a> `; } return b ` <div class=${e$1({ 'row': true, 'row--clickable': !!this._def.rowClickable })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</div> `; })} </div> </div> </div> `; } /** * Renders a data table with: * - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown) * - Scrollable grid with sticky header row and optional sticky left/right columns * - Loading, error message, or empty state when no data */ render() { if (!this._def.columns.length) { return b `<slot></slot>`; } return b ` ${this._renderHeader()} ${this._renderTable()} `; } }"
315
+ "default": "class KRTable extends i$2 { constructor() { super(...arguments); /** * Internal flag to switch between scroll edge modes: * - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge) * - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling */ this._scrollStyle = 'overlay'; this._data = []; this._dataState = 'idle'; this._page = 1; this._pageSize = 50; this._totalItems = 0; this._totalPages = 0; this._searchQuery = ''; this._canScrollLeft = false; this._canScrollRight = false; this._canScrollHorizontal = false; this._columnPickerOpen = false; this._displayedColumns = []; this._resizing = null; this._resizeObserver = null; this._searchPositionLocked = false; this._def = { columns: [] }; this.def = { columns: [] }; this._handleClickOutsideColumnPicker = (e) => { if (!this._columnPickerOpen) return; const path = e.composedPath(); const picker = this.shadowRoot?.querySelector('.column-picker-wrapper'); if (picker && !path.includes(picker)) { this._columnPickerOpen = false; } }; this._handleResizeMove = (e) => { if (!this._resizing) return; const col = this._def.columns.find(c => c.id === this._resizing.columnId); if (col) { const newWidth = this._resizing.startWidth + (e.clientX - this._resizing.startX); col.width = `${Math.min(900, Math.max(50, newWidth))}px`; this.requestUpdate(); } }; this._handleResizeEnd = () => { this._resizing = null; document.removeEventListener('mousemove', this._handleResizeMove); document.removeEventListener('mouseup', this._handleResizeEnd); }; } connectedCallback() { super.connectedCallback(); this.classList.toggle('kr-table--scroll-overlay', this._scrollStyle === 'overlay'); this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge'); this._fetch(); this._initRefresh(); document.addEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver = new ResizeObserver(() => { // Unlock and recalculate on resize since layout changes this._searchPositionLocked = false; this._updateSearchPosition(); }); this._resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); clearInterval(this._refreshTimer); document.removeEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver?.disconnect(); } willUpdate(changedProperties) { if (changedProperties.has('def')) { // Copy user's def and normalize action columns this._def = { ...this.def, columns: this.def.columns.map(col => { if (col.type === 'actions') { return { ...col, label: col.label ?? '', sticky: 'right', resizable: false }; } return { ...col }; }) }; this._displayedColumns = this._def.displayedColumns || this._def.columns.map(c => c.id); this._fetch(); this._initRefresh(); } } updated(changedProperties) { this._updateScrollFlags(); this._syncSlottedContent(); } /** Syncs light DOM content for cells with custom render functions */ _syncSlottedContent() { const columns = this.getDisplayedColumns().filter(col => col.render); if (!columns.length) return; // Clear old slotted content this.querySelectorAll('[slot^=\"cell-\"]').forEach(el => el.remove()); // Create new slotted content this._data.forEach((row, rowIndex) => { columns.forEach(col => { const result = col.render(row); if (!result) return; const el = document.createElement('span'); el.slot = `cell-${rowIndex}-${col.id}`; if (col.type === 'actions') { el.style.display = 'flex'; el.style.gap = '8px'; } if (typeof result === 'string') { el.innerHTML = result; } else { D(result, el); } this.appendChild(el); }); }); } // ---------------------------------------------------------------------------- // Public Interface // ---------------------------------------------------------------------------- refresh() { this._fetch(); } goToPrevPage() { if (this._page > 1) { this._page--; this._fetch(); } } goToNextPage() { if (this._page < this._totalPages) { this._page++; this._fetch(); } } goToPage(page) { if (page >= 1 && page <= this._totalPages) { this._page = page; this._fetch(); } } // ---------------------------------------------------------------------------- // Data Fetching // ---------------------------------------------------------------------------- /** * Fetches data from the API and updates the table. * Shows a loading spinner while fetching, then displays rows on success * or an error snackbar on failure. * Request/response format depends on dataSource.mode (solr, opensearch, db). */ _fetch() { if (!this._def.dataSource) return; this._dataState = 'loading'; // Build request based on mode let request; switch (this._def.dataSource.mode) { case 'opensearch': throw Error('Opensearch not supported yet'); case 'db': request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { this._def.columns.filter(col => col.searchable).forEach(col => { request.queryFields.push({ name: col.id, operation: 'CONTAINS', value: this._searchQuery, and: false }); }); } break; default: // solr request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { request.queryFields.push({ name: '_text_', operation: 'IS', value: escapeSolrQuery(this._searchQuery) }); } } this._def.dataSource.fetch(request) .then(response => { // Parse response based on mode switch (this._def.dataSource?.mode) { case 'opensearch': { throw Error('Opensearch not supported yet'); } case 'db': { const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; break; } default: { // solr const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; } } this._dataState = 'success'; this._updateSearchPosition(); }) .catch(err => { this._dataState = 'error'; KRSnackbar.show({ message: err instanceof Error ? err.message : 'Failed to load data', type: 'error' }); }); } /** * Sets up auto-refresh so the table automatically fetches fresh data * at a regular interval (useful for dashboards, monitoring views). * Configured via def.refreshInterval in milliseconds. */ _initRefresh() { clearInterval(this._refreshTimer); if (this._def.refreshInterval && this._def.refreshInterval > 0) { this._refreshTimer = window.setInterval(() => { this._fetch(); }, this._def.refreshInterval); } } _handleSearch(e) { const input = e.target; this._searchQuery = input.value; this._page = 1; this._fetch(); } _getGridTemplateColumns() { const cols = this.getDisplayedColumns(); return cols.map((col) => { // If column has explicit width, use it if (col.width) { return col.width; } // Actions columns: fit content without minimum if (col.type === 'actions') { return 'max-content'; } // No width specified - use content-based sizing with minimum return 'minmax(80px, auto)'; }).join(' '); } /** * Updates search position to be centered with equal gaps from title and tools. * On first call: resets to flex centering, measures position, then locks with fixed margin. * Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize). */ _updateSearchPosition() { // Skip if already locked (prevents shifts on pagination changes) if (this._searchPositionLocked) return; const search = this.shadowRoot?.querySelector('.search'); const searchField = search?.querySelector('.search-field'); if (!search || !searchField) return; // Reset to flex centering search.style.justifyContent = 'center'; searchField.style.marginLeft = ''; requestAnimationFrame(() => { const searchRect = search.getBoundingClientRect(); const fieldRect = searchField.getBoundingClientRect(); // Calculate how far from the left of search container the field currently is const currentOffset = fieldRect.left - searchRect.left; // Lock position: switch to flex-start and use fixed margin search.style.justifyContent = 'flex-start'; searchField.style.marginLeft = `${currentOffset}px`; // Mark as locked so pagination changes don't shift the search this._searchPositionLocked = true; }); } // ---------------------------------------------------------------------------- // Columns // ---------------------------------------------------------------------------- _toggleColumnPicker() { this._columnPickerOpen = !this._columnPickerOpen; } _toggleColumn(columnId) { if (this._displayedColumns.includes(columnId)) { this._displayedColumns = this._displayedColumns.filter(id => id !== columnId); } else { this._displayedColumns = [...this._displayedColumns, columnId]; } } // Clear any existing text selection on mousedown so we only detect // selections made during this click gesture, not stale selections from elsewhere _handleRowMouseDown() { if (!this._def.rowClickable) { return; } window.getSelection()?.removeAllRanges(); } _handleRowClick(row, rowIndex) { if (!this._def.rowClickable) { return; } const selection = window.getSelection(); if (selection && selection.toString().length > 0) { return; } this.dispatchEvent(new CustomEvent('row-click', { detail: { row, rowIndex }, bubbles: true, composed: true })); } // When a user toggles a column on via the column picker, it gets appended // to _displayedColumns. By mapping over _displayedColumns (not def.columns), // the new column appears at the right edge of the table instead of jumping // back to its original position in the column definition. // Actions columns are always moved to the end. getDisplayedColumns() { return this._displayedColumns .map(id => this._def.columns.find(col => col.id === id)) .sort((a, b) => { if (a.type === 'actions' && b.type !== 'actions') return 1; if (a.type !== 'actions' && b.type === 'actions') return -1; return 0; }); } // ---------------------------------------------------------------------------- // Scrolling // ---------------------------------------------------------------------------- /** * Scroll event handler that updates scroll flags in real-time as user scrolls. * Updates shadow indicators to show if more content exists left/right. */ _handleScroll(e) { const container = e.target; this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1; } /** * Updates scroll state flags for the table content container. * - _canScrollLeft: true if scrolled right (can scroll back left) * - _canScrollRight: true if more content exists to the right * - _canScrollHorizontal: true if content is wider than container * These flags control scroll shadow indicators and CSS classes. */ _updateScrollFlags() { const container = this.shadowRoot?.querySelector('.content'); if (container) { this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1; this._canScrollHorizontal = container.scrollWidth > container.clientWidth; } this.classList.toggle('kr-table--scroll-left-available', this._canScrollLeft); this.classList.toggle('kr-table--scroll-right-available', this._canScrollRight); this.classList.toggle('kr-table--scroll-horizontal-available', this._canScrollHorizontal); this.classList.toggle('kr-table--sticky-left', this.getDisplayedColumns().some(c => c.sticky === 'left')); this.classList.toggle('kr-table--sticky-right', this.getDisplayedColumns().some(c => c.sticky === 'right')); } // ---------------------------------------------------------------------------- // Column Resizing // ---------------------------------------------------------------------------- _handleResizeStart(e, columnId) { e.preventDefault(); const headerCell = this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${columnId}\"]`); this._resizing = { columnId, startX: e.clientX, startWidth: headerCell?.offsetWidth || 200 }; document.addEventListener('mousemove', this._handleResizeMove); document.addEventListener('mouseup', this._handleResizeEnd); } // ---------------------------------------------------------------------------- // Header // ---------------------------------------------------------------------------- _handleAction(action) { if (action.href) { return; } this.dispatchEvent(new CustomEvent('action', { detail: { action: action.id }, bubbles: true, composed: true })); } // ---------------------------------------------------------------------------- // Rendering // ---------------------------------------------------------------------------- _renderCellContent(column, row, rowIndex) { const value = row[column.id]; if (column.render) { // Use slot to project content from light DOM so external styles apply return b `<slot name=\"cell-${rowIndex}-${column.id}\"></slot>`; } if (value === null || value === undefined) { return ''; } switch (column.type) { case 'number': return typeof value === 'number' ? value.toLocaleString() : String(value); case 'currency': return typeof value === 'number' ? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }) : String(value); case 'date': { let date; if (value instanceof Date) { date = value; } else if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(value)) { // MySQL datetime format (UTC): \"2026-01-28 01:33:44:517\" // Replace last colon before ms with dot, append Z for UTC const isoString = value.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/, '$1.$2').replace(' ', 'T') + 'Z'; date = new Date(isoString); } else { date = new Date(value); } // Show date and time for datetime values return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); } case 'boolean': if (value === true) return 'Yes'; if (value === false) return 'No'; return ''; default: return String(value); } } /** * Returns CSS classes for a header cell based on column config. */ _getHeaderCellClasses(column, index) { return { 'header-cell': true, 'header-cell--align-center': column.align === 'center', 'header-cell--align-right': column.align === 'right', 'header-cell--sticky-left': column.sticky === 'left', 'header-cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'header-cell--sticky-right': column.sticky === 'right', 'header-cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns CSS classes for a table cell based on column config: * - Alignment (center, right) * - Sticky positioning (left, right) * - Border classes for the last left-sticky or first right-sticky column */ _getCellClasses(column, index) { return { 'cell': true, 'cell--actions': column.type === 'actions', 'cell--align-center': column.align === 'center', 'cell--align-right': column.align === 'right', 'cell--sticky-left': column.sticky === 'left', 'cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'cell--sticky-right': column.sticky === 'right', 'cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns inline styles for a table cell: * - Width (from column config or default 150px) * - Min-width (if specified) * - Left/right offset for sticky columns (calculated from widths of preceding sticky columns) */ _getCellStyle(column, index) { const styles = {}; if (column.sticky === 'left') { let leftOffset = 0; for (let i = 0; i < index; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'left') { leftOffset += parseInt(col.width || '0', 10); } } styles.left = `${leftOffset}px`; } if (column.sticky === 'right') { let rightOffset = 0; for (let i = index + 1; i < this.getDisplayedColumns().length; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'right') { rightOffset += parseInt(col.width || '0', 10); } } styles.right = `${rightOffset}px`; } return styles; } /** * Renders the pagination controls: * - Previous page arrow (disabled on first page) * - Range text showing \"1-50 of 150\" format * - Next page arrow (disabled on last page) * * Hidden when there's no data or all data fits on one page. */ _renderPagination() { const start = (this._page - 1) * this._pageSize + 1; const end = Math.min(this._page * this._pageSize, this._totalItems); return b ` <div class=\"pagination\"> <span class=\"pagination-icon ${this._page === 1 ? 'pagination-icon--disabled' : ''}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${start}-${end} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page === this._totalPages ? 'pagination-icon--disabled' : ''}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `; } /** * Renders the header toolbar containing: * - Title (left) * - Search bar with view selector dropdown (center) * - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown * * Hidden when there's no title, no actions, and data fits on one page. */ _renderHeader() { if (!this._def.title && !this._def.actions?.length && this._totalPages <= 1) { return A; } return b ` <div class=\"header\"> <div class=\"title\">${this._def.title ?? ''}</div> ${this._def.dataSource?.mode === 'db' && !this._def.columns.some(col => col.searchable) ? b `<div class=\"search\"></div>` : b ` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${() => this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen ? 'open' : ''}\"> ${[...this._def.columns].filter(col => col.type !== 'actions').sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => b ` <div class=\"column-picker-item\" @click=${() => this._toggleColumn(col.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(col.id) ? 'checked' : ''}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${col.label ?? col.id}</span> </div> `)} </div> </div> ${this._def.actions?.length === 1 ? b ` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${() => this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> ` : this._def.actions?.length ? b ` <kr-button class=\"actions\" .options=${this._def.actions.map(a => ({ id: a.id, label: a.label }))} @option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })} > Actions </kr-button> ` : A} </div> </div> `; } /** Renders status message (loading, error, empty) */ _renderStatus() { if (this._dataState === 'loading' && this._data.length === 0) { return b `<div class=\"status\">Loading...</div>`; } if (this._dataState === 'error' && this._data.length === 0) { return b `<div class=\"status status--error\">Error loading data</div>`; } if (this._data.length === 0) { return b `<div class=\"status\">No data available</div>`; } return A; } /** Renders the scrollable data grid with column headers and rows. */ _renderTable() { return b ` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map((col, i) => b ` <div class=${e$1(this._getHeaderCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} >${col.label ?? col.id}${col.resizable !== false ? b `<div class=\"header-cell__resize\" @mousedown=${(e) => this._handleResizeStart(e, col.id)} ></div>` : A}</div> `)} </div> ${this._data.map((row, rowIndex) => { const cells = this.getDisplayedColumns().map((col, i) => b ` <div class=${e$1(this._getCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} > ${this._renderCellContent(col, row, rowIndex)} </div> `); if (this._def.rowHref) { return b ` <a href=${this._def.rowHref(row)} class=${e$1({ 'row': true, 'row--clickable': true, 'row--link': true })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</a> `; } return b ` <div class=${e$1({ 'row': true, 'row--clickable': !!this._def.rowClickable })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</div> `; })} </div> </div> </div> `; } /** * Renders a data table with: * - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown) * - Scrollable grid with sticky header row and optional sticky left/right columns * - Loading, error message, or empty state when no data */ render() { if (!this._def.columns.length) { return b `<slot></slot>`; } return b ` ${this._renderHeader()} ${this._renderTable()} `; } }"
316
316
  },
317
317
  {
318
318
  "kind": "variable",
@@ -569,38 +569,38 @@
569
569
  },
570
570
  {
571
571
  "kind": "variable",
572
- "name": "le",
572
+ "name": "ae",
573
573
  "default": "r` :host, *, *::before, *::after { box-sizing: border-box; } :host { /* Primary */ --kr-primary: rgb(22, 48, 82); --kr-primary-hover: rgb(16, 36, 62); --kr-primary-text: #ffffff; /* Accent */ --kr-accent: #BEEA4E; --kr-accent-hover: #a8d43a; --kr-accent-text: #000000; /* Text */ --kr-text: #000000; --kr-text-muted: #4b5563; --kr-text-disabled: #9ca3af; /* Borders */ --kr-border: #e5e7eb; } `"
574
574
  },
575
575
  {
576
576
  "kind": "variable",
577
- "name": "fe",
578
- "default": "class extends re{constructor(){super(...arguments),this.header=\"\",this.expanded=!1}toggle(){this.expanded=!this.expanded}render(){return B` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `}}"
577
+ "name": "ve",
578
+ "default": "class extends ne{constructor(){super(...arguments),this.header=\"\",this.expanded=!1}toggle(){this.expanded=!this.expanded}render(){return B` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `}}"
579
579
  },
580
580
  {
581
581
  "kind": "variable",
582
- "name": "$e",
583
- "default": "class extends re{constructor(){super(...arguments),this.type=\"info\",this.title=\"\",this.dismissible=!1,this.visible=!0}_handleDismiss(){this.visible=!1,this.dispatchEvent(new CustomEvent(\"dismiss\",{bubbles:!0,composed:!0}))}render(){const e={info:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`,success:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`,warning:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`,error:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`};return B` <div class=${ke({alert:!0,[\"alert--\"+this.type]:!0,\"alert--has-header\":!!this.title,\"alert--hidden\":!this.visible})} role=\"alert\" > ${e[this.type]} <div class=\"content\"> ${this.title?B`<h4 class=\"header\">${this.title}</h4>`:U} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible?B` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/> </svg> </button> `:U} </div> `}}"
582
+ "name": "Ce",
583
+ "default": "class extends ne{constructor(){super(...arguments),this.type=\"info\",this.title=\"\",this.dismissible=!1,this.visible=!0}_handleDismiss(){this.visible=!1,this.dispatchEvent(new CustomEvent(\"dismiss\",{bubbles:!0,composed:!0}))}render(){const e={info:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`,success:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`,warning:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`,error:B`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`};return B` <div class=${we({alert:!0,[\"alert--\"+this.type]:!0,\"alert--has-header\":!!this.title,\"alert--hidden\":!this.visible})} role=\"alert\" > ${e[this.type]} <div class=\"content\"> ${this.title?B`<h4 class=\"header\">${this.title}</h4>`:U} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible?B` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/> </svg> </button> `:U} </div> `}}"
584
584
  },
585
585
  {
586
586
  "kind": "variable",
587
- "name": "ze",
588
- "default": "class extends re{constructor(){super(...arguments),this.variant=\"flat\",this.color=\"primary\",this.size=\"medium\",this.disabled=!1,this.options=[],this.iconPosition=\"left\",this._state=\"idle\",this._stateText=\"\",this._dropdownOpened=!1,this._handleHostClick=e=>{this.options.length&&(e.stopPropagation(),this._toggleDropdown())},this._handleKeydown=e=>{\"Enter\"!==e.key&&\" \"!==e.key||(e.preventDefault(),this.options.length?this._toggleDropdown():this.click()),\"Escape\"===e.key&&this._dropdownOpened&&(this._dropdownOpened=!1)},this._handleClickOutside=e=>{this._dropdownOpened&&!this.contains(e.target)&&(this._dropdownOpened=!1)}}connectedCallback(){super.connectedCallback(),this.setAttribute(\"role\",this.href?\"link\":\"button\"),this.setAttribute(\"tabindex\",\"0\"),this.addEventListener(\"keydown\",this._handleKeydown),this.addEventListener(\"click\",this._handleHostClick),document.addEventListener(\"click\",this._handleClickOutside)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"keydown\",this._handleKeydown),this.removeEventListener(\"click\",this._handleHostClick),document.removeEventListener(\"click\",this._handleClickOutside)}_toggleDropdown(){this._dropdownOpened=!this._dropdownOpened,this._dropdownOpened&&requestAnimationFrame((()=>{const e=this.shadowRoot?.querySelector(\".dropdown\");if(e){const t=this.getBoundingClientRect();e.style.top=t.bottom+4+\"px\",e.style.bottom=\"\",e.style.left=t.left+\"px\",e.style.right=\"\",e.style.minWidth=t.width+\"px\",e.style.transformOrigin=\"top left\";const i=e.getBoundingClientRect();i.bottom>window.innerHeight?(e.style.top=\"\",e.style.bottom=window.innerHeight-t.top+4+\"px\",e.style.transformOrigin=\"bottom left\",e.classList.add(\"dropdown--above\")):e.classList.remove(\"dropdown--above\"),i.right>window.innerWidth&&(e.style.left=\"\",e.style.right=window.innerWidth-t.right+\"px\",i.bottom>window.innerHeight?e.style.transformOrigin=\"bottom right\":e.style.transformOrigin=\"top right\")}}))}_handleOptionClick(e,t){t.stopPropagation(),this._dropdownOpened=!1,this.dispatchEvent(new CustomEvent(\"option-select\",{detail:{id:e.id,label:e.label},bubbles:!0,composed:!0}))}showLoading(){this._clearStateTimeout(),this._state=\"loading\",this._stateText=\"\"}showSuccess(e=\"Success\",t=2e3){this._clearStateTimeout(),this._state=\"success\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout((()=>this.reset()),t))}showError(e=\"Error\",t=2e3){this._clearStateTimeout(),this._state=\"error\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout((()=>this.reset()),t))}isLoading(){return\"loading\"===this._state}reset(){this._clearStateTimeout(),this._state=\"idle\",this._stateText=\"\"}_clearStateTimeout(){this._stateTimeout&&(clearTimeout(this._stateTimeout),this._stateTimeout=void 0)}updated(e){this.classList.toggle(\"kr-button--loading\",\"loading\"===this._state),this.classList.toggle(\"kr-button--success\",\"success\"===this._state),this.classList.toggle(\"kr-button--error\",\"error\"===this._state),this.classList.toggle(`kr-button--${this.variant}`,!0),this.classList.toggle(`kr-button--${this.color}`,!0),this.classList.toggle(\"kr-button--small\",\"small\"===this.size),this.classList.toggle(\"kr-button--large\",\"large\"===this.size)}render(){const e=B` <span class=\"content\"> <slot name=\"icon\"></slot> <slot></slot> </span> ${this.options.length?B`<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg>`:U} ${\"idle\"!==this._state?B`<span class=\"state-overlay\"> ${\"loading\"===this._state?B`<span class=\"spinner\"></span>`:this._stateText} </span>`:U} ${this.options.length?B` <div class=\"dropdown ${this._dropdownOpened?\"dropdown--opened\":\"\"}\"> ${this.options.map((e=>B` <button class=\"dropdown-item\" @click=${t=>this._handleOptionClick(e,t)} >${e.label}</button> `))} </div> `:U} `;return this.href?B`<a class=\"link\" href=${this.href} target=${this.target||U}>${e}</a>`:e}}"
587
+ "name": "Se",
588
+ "default": "class extends ne{constructor(){super(...arguments),this.variant=\"flat\",this.color=\"primary\",this.size=\"medium\",this.disabled=!1,this.options=[],this.iconPosition=\"left\",this._state=\"idle\",this._stateText=\"\",this._dropdownOpened=!1,this._handleHostClick=e=>{this.options.length&&(e.stopPropagation(),this._toggleDropdown())},this._handleKeydown=e=>{\"Enter\"!==e.key&&\" \"!==e.key||(e.preventDefault(),this.options.length?this._toggleDropdown():this.click()),\"Escape\"===e.key&&this._dropdownOpened&&(this._dropdownOpened=!1)},this._handleClickOutside=e=>{this._dropdownOpened&&!this.contains(e.target)&&(this._dropdownOpened=!1)}}connectedCallback(){super.connectedCallback(),this.setAttribute(\"role\",this.href?\"link\":\"button\"),this.setAttribute(\"tabindex\",\"0\"),this.addEventListener(\"keydown\",this._handleKeydown),this.addEventListener(\"click\",this._handleHostClick),document.addEventListener(\"click\",this._handleClickOutside)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"keydown\",this._handleKeydown),this.removeEventListener(\"click\",this._handleHostClick),document.removeEventListener(\"click\",this._handleClickOutside)}_toggleDropdown(){this._dropdownOpened=!this._dropdownOpened,this._dropdownOpened&&requestAnimationFrame((()=>{const e=this.shadowRoot?.querySelector(\".dropdown\");if(e){const t=this.getBoundingClientRect();e.style.top=t.bottom+4+\"px\",e.style.bottom=\"\",e.style.left=t.left+\"px\",e.style.right=\"\",e.style.minWidth=t.width+\"px\",e.style.transformOrigin=\"top left\";const i=e.getBoundingClientRect();i.bottom>window.innerHeight?(e.style.top=\"\",e.style.bottom=window.innerHeight-t.top+4+\"px\",e.style.transformOrigin=\"bottom left\",e.classList.add(\"dropdown--above\")):e.classList.remove(\"dropdown--above\"),i.right>window.innerWidth&&(e.style.left=\"\",e.style.right=window.innerWidth-t.right+\"px\",i.bottom>window.innerHeight?e.style.transformOrigin=\"bottom right\":e.style.transformOrigin=\"top right\")}}))}_handleOptionClick(e,t){t.stopPropagation(),this._dropdownOpened=!1,this.dispatchEvent(new CustomEvent(\"option-select\",{detail:{id:e.id,label:e.label},bubbles:!0,composed:!0}))}showLoading(){this._clearStateTimeout(),this._state=\"loading\",this._stateText=\"\"}showSuccess(e=\"Success\",t=2e3){this._clearStateTimeout(),this._state=\"success\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout((()=>this.reset()),t))}showError(e=\"Error\",t=2e3){this._clearStateTimeout(),this._state=\"error\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout((()=>this.reset()),t))}isLoading(){return\"loading\"===this._state}reset(){this._clearStateTimeout(),this._state=\"idle\",this._stateText=\"\"}_clearStateTimeout(){this._stateTimeout&&(clearTimeout(this._stateTimeout),this._stateTimeout=void 0)}updated(e){this.classList.toggle(\"kr-button--loading\",\"loading\"===this._state),this.classList.toggle(\"kr-button--success\",\"success\"===this._state),this.classList.toggle(\"kr-button--error\",\"error\"===this._state),this.classList.toggle(`kr-button--${this.variant}`,!0),this.classList.toggle(`kr-button--${this.color}`,!0),this.classList.toggle(\"kr-button--small\",\"small\"===this.size),this.classList.toggle(\"kr-button--large\",\"large\"===this.size)}render(){const e=B` <span class=\"content\"> <slot name=\"icon\"></slot> <slot></slot> </span> ${this.options.length?B`<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg>`:U} ${\"idle\"!==this._state?B`<span class=\"state-overlay\"> ${\"loading\"===this._state?B`<span class=\"spinner\"></span>`:this._stateText} </span>`:U} ${this.options.length?B` <div class=\"dropdown ${this._dropdownOpened?\"dropdown--opened\":\"\"}\"> ${this.options.map((e=>B` <button class=\"dropdown-item\" @click=${t=>this._handleOptionClick(e,t)} >${e.label}</button> `))} </div> `:U} `;return this.href?B`<a class=\"link\" href=${this.href} target=${this.target||U}>${e}</a>`:e}}"
589
589
  },
590
590
  {
591
591
  "kind": "variable",
592
- "name": "Ae",
593
- "default": "class extends re{constructor(){super(...arguments),this.language=\"html\",this.code=\"\",this.activeTab=\"preview\",this.copied=!1,this.highlightedCode=\"\"}connectedCallback(){super.connectedCallback(),requestAnimationFrame((()=>{this.code||(this.code=this.innerHTML.trim().replace(/=\"\"(?=[\\s>])/g,\"\")),this.querySelectorAll(\"script\").forEach((e=>{const t=document.createElement(\"script\");t.textContent=e.textContent,e.replaceWith(t)})),this.code&&window.hljs&&window.hljs.getLanguage(this.language)?this.highlightedCode=window.hljs.highlight(this.code,{language:this.language}).value:this.highlightedCode=this.code.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")}))}activateTab(e){this.activeTab=e}copyCode(){this.code&&navigator.clipboard.writeText(this.code).then((()=>{this.copied=!0,setTimeout((()=>{this.copied=!1}),2e3)}))}render(){return B` <div class=\"tabs\"> <button class=${ke({tab:!0,\"tab--active\":\"preview\"===this.activeTab})} @click=${()=>this.activateTab(\"preview\")} > Preview </button> <button class=${ke({tab:!0,\"tab--active\":\"code\"===this.activeTab})} @click=${()=>this.activateTab(\"code\")} > Code </button> <button class=${ke({copy:!0,\"copy--success\":this.copied})} @click=${this.copyCode} title=${this.copied?\"Copied!\":\"Copy code\"} > ${this.copied?B`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>`:B`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`} </button> </div> <div class=${ke({panel:!0,\"panel--active\":\"preview\"===this.activeTab,\"panel--preview\":!0})}> <slot></slot> </div> <div class=${ke({panel:!0,\"panel--active\":\"code\"===this.activeTab,\"panel--code\":!0})}> <pre class=\"code\"><code>${Ee(this.highlightedCode)}</code></pre> </div> `}}"
592
+ "name": "Te",
593
+ "default": "class extends ne{constructor(){super(...arguments),this.language=\"html\",this.code=\"\",this.activeTab=\"preview\",this.copied=!1,this.highlightedCode=\"\"}connectedCallback(){super.connectedCallback(),requestAnimationFrame((()=>{this.code||(this.code=this.innerHTML.trim().replace(/=\"\"(?=[\\s>])/g,\"\")),this.querySelectorAll(\"script\").forEach((e=>{const t=document.createElement(\"script\");t.textContent=e.textContent,e.replaceWith(t)})),this.code&&window.hljs&&window.hljs.getLanguage(this.language)?this.highlightedCode=window.hljs.highlight(this.code,{language:this.language}).value:this.highlightedCode=this.code.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")}))}activateTab(e){this.activeTab=e}copyCode(){this.code&&navigator.clipboard.writeText(this.code).then((()=>{this.copied=!0,setTimeout((()=>{this.copied=!1}),2e3)}))}render(){return B` <div class=\"tabs\"> <button class=${we({tab:!0,\"tab--active\":\"preview\"===this.activeTab})} @click=${()=>this.activateTab(\"preview\")} > Preview </button> <button class=${we({tab:!0,\"tab--active\":\"code\"===this.activeTab})} @click=${()=>this.activateTab(\"code\")} > Code </button> <button class=${we({copy:!0,\"copy--success\":this.copied})} @click=${this.copyCode} title=${this.copied?\"Copied!\":\"Copy code\"} > ${this.copied?B`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>`:B`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`} </button> </div> <div class=${we({panel:!0,\"panel--active\":\"preview\"===this.activeTab,\"panel--preview\":!0})}> <slot></slot> </div> <div class=${we({panel:!0,\"panel--active\":\"code\"===this.activeTab,\"panel--code\":!0})}> <pre class=\"code\"><code>${Oe(this.highlightedCode)}</code></pre> </div> `}}"
594
594
  },
595
595
  {
596
596
  "kind": "variable",
597
- "name": "Le",
598
- "default": "class extends re{constructor(){super(...arguments),this.items=[],this.resolvePromise=null,this.boundHandleOutsideClick=this.handleOutsideClick.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this)}static async open(e){const t=document.querySelector(\"kr-context-menu\");t&&t.remove();const i=document.createElement(\"kr-context-menu\");return document.body.appendChild(i),i.show(e)}async show(e){this.items=e.items,this.style.left=`${e.x}px`,this.style.top=`${e.y}px`,await this.updateComplete;const t=this.getBoundingClientRect();return t.right>window.innerWidth&&(this.style.left=e.x-t.width+\"px\"),t.bottom>window.innerHeight&&(this.style.top=e.y-t.height+\"px\"),requestAnimationFrame((()=>{document.addEventListener(\"click\",this.boundHandleOutsideClick),document.addEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.addEventListener(\"keydown\",this.boundHandleKeyDown)})),new Promise((e=>{this.resolvePromise=e}))}handleOutsideClick(e){this.contains(e.target)||this.close(null)}handleKeyDown(e){\"Escape\"===e.key&&this.close(null)}handleItemClick(e){e.disabled||e.divider||this.close(e)}close(e){document.removeEventListener(\"click\",this.boundHandleOutsideClick),document.removeEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.removeEventListener(\"keydown\",this.boundHandleKeyDown),this.resolvePromise&&(this.resolvePromise(e),this.resolvePromise=null),this.remove()}render(){return B` <div class=\"menu\"> ${this.items.map((e=>e.divider?B`<div class=\"menu__divider\"></div>`:B` <button class=\"menu__item\" ?disabled=${e.disabled} @click=${()=>this.handleItemClick(e)} > ${e.icon?B`<span class=\"menu__item-icon\">${e.icon}</span>`:null} ${e.label} </button> `))} </div> `}}"
597
+ "name": "Pe",
598
+ "default": "class extends ne{constructor(){super(...arguments),this.items=[],this.resolvePromise=null,this.boundHandleOutsideClick=this.handleOutsideClick.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this)}static async open(e){const t=document.querySelector(\"kr-context-menu\");t&&t.remove();const i=document.createElement(\"kr-context-menu\");return document.body.appendChild(i),i.show(e)}async show(e){this.items=e.items,this.style.left=`${e.x}px`,this.style.top=`${e.y}px`,await this.updateComplete;const t=this.getBoundingClientRect();return t.right>window.innerWidth&&(this.style.left=e.x-t.width+\"px\"),t.bottom>window.innerHeight&&(this.style.top=e.y-t.height+\"px\"),requestAnimationFrame((()=>{document.addEventListener(\"click\",this.boundHandleOutsideClick),document.addEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.addEventListener(\"keydown\",this.boundHandleKeyDown)})),new Promise((e=>{this.resolvePromise=e}))}handleOutsideClick(e){this.contains(e.target)||this.close(null)}handleKeyDown(e){\"Escape\"===e.key&&this.close(null)}handleItemClick(e){e.disabled||e.divider||this.close(e)}close(e){document.removeEventListener(\"click\",this.boundHandleOutsideClick),document.removeEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.removeEventListener(\"keydown\",this.boundHandleKeyDown),this.resolvePromise&&(this.resolvePromise(e),this.resolvePromise=null),this.remove()}render(){return B` <div class=\"menu\"> ${this.items.map((e=>e.divider?B`<div class=\"menu__divider\"></div>`:B` <button class=\"menu__item\" ?disabled=${e.disabled} @click=${()=>this.handleItemClick(e)} > ${e.icon?B`<span class=\"menu__item-icon\">${e.icon}</span>`:null} ${e.label} </button> `))} </div> `}}"
599
599
  },
600
600
  {
601
601
  "kind": "class",
602
602
  "description": "",
603
- "name": "Ve",
603
+ "name": "Be",
604
604
  "members": [
605
605
  {
606
606
  "kind": "method",
@@ -649,71 +649,71 @@
649
649
  },
650
650
  {
651
651
  "kind": "variable",
652
- "name": "Be",
653
- "default": "class extends re{constructor(){super(...arguments),this._dialogRef=null,this._contentElement=null,this.opened=!1,this.label=\"\",this.width=\"560px\",this._handleDocumentKeyDown=e=>{\"Escape\"===e.key&&this.close()}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"keydown\",this._handleDocumentKeyDown)}updated(e){super.updated(e),e.has(\"opened\")&&(this.opened?document.addEventListener(\"keydown\",this._handleDocumentKeyDown):document.removeEventListener(\"keydown\",this._handleDocumentKeyDown))}open(){this.opened=!0}close(){this._dialogRef?this._dialogRef.close(void 0):(this.opened=!1,this.dispatchEvent(new CustomEvent(\"close\",{bubbles:!0,composed:!0})))}static open(e,t){document.querySelectorAll(\"kr-dialog\").forEach((e=>{e._dialogRef&&e.remove()}));const i=new Ve,o=document.createElement(\"kr-dialog\");i.setDialogElement(o),o._dialogRef=i;const s=new e;return s.dialogRef=i,t?.data&&(s.data=t.data),t?.label&&(o.label=t.label),t?.width&&(o.width=t.width),o._contentElement=s,o.opened=!0,document.body.appendChild(o),i}_handleBackdropClick(e){e.target.classList.contains(\"backdrop\")&&this.close()}render(){return B` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\" style=${je({width:this.width})}> ${this.label?B`<div class=\"dialog__header\"><div class=\"dialog__header-label\">${this.label}</div></div>`:\"\"} ${this._contentElement?this._contentElement:B`<slot></slot>`} </div> `}}"
652
+ "name": "qe",
653
+ "default": "class extends ne{constructor(){super(...arguments),this._dialogRef=null,this._contentElement=null,this.opened=!1,this.label=\"\",this.width=\"560px\",this._handleDocumentKeyDown=e=>{\"Escape\"===e.key&&this.close()}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"keydown\",this._handleDocumentKeyDown)}updated(e){super.updated(e),e.has(\"opened\")&&(this.opened?document.addEventListener(\"keydown\",this._handleDocumentKeyDown):document.removeEventListener(\"keydown\",this._handleDocumentKeyDown))}open(){this.opened=!0}close(){this._dialogRef?this._dialogRef.close(void 0):(this.opened=!1,this.dispatchEvent(new CustomEvent(\"close\",{bubbles:!0,composed:!0})))}static open(e,t){document.querySelectorAll(\"kr-dialog\").forEach((e=>{e._dialogRef&&e.remove()}));const i=new Be,o=document.createElement(\"kr-dialog\");i.setDialogElement(o),o._dialogRef=i;const s=new e;return s.dialogRef=i,t?.data&&(s.data=t.data),t?.label&&(o.label=t.label),t?.width&&(o.width=t.width),o._contentElement=s,o.opened=!0,document.body.appendChild(o),i}_handleBackdropClick(e){e.target.classList.contains(\"backdrop\")&&this.close()}render(){return B` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\" style=${Me({width:this.width})}> ${this.label?B`<div class=\"dialog__header\"><div class=\"dialog__header-label\">${this.label}</div></div>`:\"\"} ${this._contentElement?this._contentElement:B`<slot></slot>`} </div> `}}"
654
654
  },
655
655
  {
656
656
  "kind": "variable",
657
- "name": "Ne"
657
+ "name": "Fe"
658
658
  },
659
659
  {
660
660
  "kind": "variable",
661
- "name": "We",
662
- "default": "class extends re{constructor(){super(...arguments),this.justified=!1,this.size=\"medium\"}updated(e){e.has(\"activeTabId\")&&this._updateActiveTab()}firstUpdated(){this._updateActiveTab()}_getTabs(){return Array.from(this.querySelectorAll(\"kr-tab\"))}_updateActiveTab(){const e=this._getTabs();0!==e.length&&(this.activeTabId||(this.activeTabId=e[0]?.id),e.forEach((e=>{e.active=e.id===this.activeTabId})),this.requestUpdate())}_handleTabClick(e){e.disabled||(this.activeTabId=e.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:e.id},bubbles:!0,composed:!0})))}_handleTabDismiss(e,t){t.stopPropagation(),this.dispatchEvent(new CustomEvent(\"tab-dismiss\",{detail:{tabId:e.id},bubbles:!0,composed:!0}))}_handleKeyDown(e){const t=this._getTabs().filter((e=>!e.disabled)),i=t.findIndex((e=>e.id===this.activeTabId));let o=-1;switch(e.key){case\"ArrowLeft\":o=i>0?i-1:t.length-1;break;case\"ArrowRight\":o=i<t.length-1?i+1:0;break;case\"Home\":o=0;break;case\"End\":o=t.length-1}if(o>=0){e.preventDefault();const i=t[o];this.activeTabId=i.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:i.id},bubbles:!0,composed:!0}));const s=this.shadowRoot?.querySelectorAll(\".label\"),r=Array.from(s||[]).find((e=>e.getAttribute(\"data-tab-id\")===i.id));r?.focus()}}_renderTabIcon(e){const t=e.getIconElement();if(!t)return U;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),B`<span class=\"label-icon\">${i}</span>`}render(){return B` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((e=>B` <button class=${ke({label:!0,\"label--active\":e.id===this.activeTabId,\"label--justified\":this.justified})} role=\"tab\" data-tab-id=${e.id} aria-selected=${e.id===this.activeTabId} aria-controls=${`panel-${e.id}`} tabindex=${e.id===this.activeTabId?0:-1} ?disabled=${e.disabled} @click=${()=>this._handleTabClick(e)} > ${this._renderTabIcon(e)} <span>${e.label}</span> ${e.badge?B`<span class=\"label-badge\" style=${je({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:U} ${e.dismissible?B` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${t=>this._handleTabDismiss(e,t)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> `:U} </button> `))} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
661
+ "name": "Ke",
662
+ "default": "class extends ne{constructor(){super(...arguments),this.justified=!1,this.size=\"medium\"}updated(e){e.has(\"activeTabId\")&&this._updateActiveTab()}firstUpdated(){this._updateActiveTab()}_getTabs(){return Array.from(this.querySelectorAll(\"kr-tab\"))}_updateActiveTab(){const e=this._getTabs();0!==e.length&&(this.activeTabId||(this.activeTabId=e[0]?.id),e.forEach((e=>{e.active=e.id===this.activeTabId})),this.requestUpdate())}_handleTabClick(e){e.disabled||(this.activeTabId=e.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:e.id},bubbles:!0,composed:!0})))}_handleTabDismiss(e,t){t.stopPropagation(),this.dispatchEvent(new CustomEvent(\"tab-dismiss\",{detail:{tabId:e.id},bubbles:!0,composed:!0}))}_handleKeyDown(e){const t=this._getTabs().filter((e=>!e.disabled)),i=t.findIndex((e=>e.id===this.activeTabId));let o=-1;switch(e.key){case\"ArrowLeft\":o=i>0?i-1:t.length-1;break;case\"ArrowRight\":o=i<t.length-1?i+1:0;break;case\"Home\":o=0;break;case\"End\":o=t.length-1}if(o>=0){e.preventDefault();const i=t[o];this.activeTabId=i.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:i.id},bubbles:!0,composed:!0}));const s=this.shadowRoot?.querySelectorAll(\".label\"),r=Array.from(s||[]).find((e=>e.getAttribute(\"data-tab-id\")===i.id));r?.focus()}}_renderTabIcon(e){const t=e.getIconElement();if(!t)return U;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),B`<span class=\"label-icon\">${i}</span>`}render(){return B` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((e=>B` <button class=${we({label:!0,\"label--active\":e.id===this.activeTabId,\"label--justified\":this.justified})} role=\"tab\" data-tab-id=${e.id} aria-selected=${e.id===this.activeTabId} aria-controls=${`panel-${e.id}`} tabindex=${e.id===this.activeTabId?0:-1} ?disabled=${e.disabled} @click=${()=>this._handleTabClick(e)} > ${this._renderTabIcon(e)} <span>${e.label}</span> ${e.badge?B`<span class=\"label-badge\" style=${Me({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:U} ${e.dismissible?B` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${t=>this._handleTabDismiss(e,t)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> `:U} </button> `))} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
663
663
  },
664
664
  {
665
665
  "kind": "variable",
666
- "name": "Xe",
667
- "default": "class extends re{constructor(){super(...arguments),this.id=\"\",this.label=\"\",this.badge=\"\",this.badgeBackground=\"\",this.badgeColor=\"\",this.disabled=!1,this.dismissible=!1,this.active=!1}getIconElement(){return this.querySelector('[slot=\"icon\"]')}render(){return console.log(\"tab render\"),B`<slot></slot>`}}"
666
+ "name": "Ye",
667
+ "default": "class extends ne{constructor(){super(...arguments),this.id=\"\",this.label=\"\",this.badge=\"\",this.badgeBackground=\"\",this.badgeColor=\"\",this.disabled=!1,this.dismissible=!1,this.active=!1}getIconElement(){return this.querySelector('[slot=\"icon\"]')}render(){return console.log(\"tab render\"),B`<slot></slot>`}}"
668
668
  },
669
669
  {
670
670
  "kind": "variable",
671
- "name": "Je",
672
- "default": "class extends re{constructor(){super(...arguments),this._scrollStyle=\"overlay\",this._data=[],this._dataState=\"idle\",this._page=1,this._pageSize=50,this._totalItems=0,this._totalPages=0,this._searchQuery=\"\",this._canScrollLeft=!1,this._canScrollRight=!1,this._canScrollHorizontal=!1,this._columnPickerOpen=!1,this._displayedColumns=[],this._resizing=null,this._resizeObserver=null,this._searchPositionLocked=!1,this._def={columns:[]},this.def={columns:[]},this._handleClickOutsideColumnPicker=e=>{if(!this._columnPickerOpen)return;const t=e.composedPath(),i=this.shadowRoot?.querySelector(\".column-picker-wrapper\");i&&!t.includes(i)&&(this._columnPickerOpen=!1)},this._handleResizeMove=e=>{if(!this._resizing)return;const t=this._def.columns.find((e=>e.id===this._resizing.columnId));if(t){const i=this._resizing.startWidth+(e.clientX-this._resizing.startX);t.width=`${Math.min(900,Math.max(50,i))}px`,this.requestUpdate()}},this._handleResizeEnd=()=>{this._resizing=null,document.removeEventListener(\"mousemove\",this._handleResizeMove),document.removeEventListener(\"mouseup\",this._handleResizeEnd)}}connectedCallback(){super.connectedCallback(),this.classList.toggle(\"kr-table--scroll-overlay\",\"overlay\"===this._scrollStyle),this.classList.toggle(\"kr-table--scroll-edge\",\"edge\"===this._scrollStyle),this._fetch(),this._initRefresh(),document.addEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver=new ResizeObserver((()=>{this._searchPositionLocked=!1,this._updateSearchPosition()})),this._resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),clearInterval(this._refreshTimer),document.removeEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver?.disconnect()}willUpdate(e){e.has(\"def\")&&(this._def={...this.def,columns:this.def.columns.map((e=>\"actions\"===e.type?{...e,label:e.label??\"\",sticky:\"right\",resizable:!1}:{...e}))},this._displayedColumns=this._def.displayedColumns||this._def.columns.map((e=>e.id)),this._fetch(),this._initRefresh())}updated(e){this._updateScrollFlags(),this._syncSlottedContent()}_syncSlottedContent(){const e=this.getDisplayedColumns().filter((e=>e.render));e.length&&(this.querySelectorAll('[slot^=\"cell-\"]').forEach((e=>e.remove())),this._data.forEach(((t,i)=>{e.forEach((e=>{const o=e.render(t),s=\"string\"==typeof o?o:\"\";if(s){const t=document.createElement(\"span\");t.slot=`cell-${i}-${e.id}`,\"actions\"===e.type&&(t.style.display=\"flex\",t.style.gap=\"8px\"),t.innerHTML=s,this.appendChild(t)}}))})))}refresh(){this._fetch()}goToPrevPage(){this._page>1&&(this._page--,this._fetch())}goToNextPage(){this._page<this._totalPages&&(this._page++,this._fetch())}goToPage(e){e>=1&&e<=this._totalPages&&(this._page=e,this._fetch())}_fetch(){if(!this._def.dataSource)return;let e;switch(this._dataState=\"loading\",this._def.dataSource.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&this._def.columns.filter((e=>e.searchable)).forEach((t=>{e.queryFields.push({name:t.id,operation:\"CONTAINS\",value:this._searchQuery,and:!1})}));break;default:e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&e.queryFields.push({name:\"_text_\",operation:\"IS\",value:Ge(this._searchQuery)})}this._def.dataSource.fetch(e).then((e=>{switch(this._def.dataSource?.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size;break}default:{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size}}this._dataState=\"success\",this._updateSearchPosition()})).catch((e=>{this._dataState=\"error\",Ne.show({message:e instanceof Error?e.message:\"Failed to load data\",type:\"error\"})}))}_initRefresh(){clearInterval(this._refreshTimer),this._def.refreshInterval&&this._def.refreshInterval>0&&(this._refreshTimer=window.setInterval((()=>{this._fetch()}),this._def.refreshInterval))}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._page=1,this._fetch()}_getGridTemplateColumns(){return this.getDisplayedColumns().map((e=>e.width?e.width:\"actions\"===e.type?\"max-content\":\"minmax(80px, auto)\")).join(\" \")}_updateSearchPosition(){if(this._searchPositionLocked)return;const e=this.shadowRoot?.querySelector(\".search\"),t=e?.querySelector(\".search-field\");e&&t&&(e.style.justifyContent=\"center\",t.style.marginLeft=\"\",requestAnimationFrame((()=>{const i=e.getBoundingClientRect(),o=t.getBoundingClientRect().left-i.left;e.style.justifyContent=\"flex-start\",t.style.marginLeft=`${o}px`,this._searchPositionLocked=!0})))}_toggleColumnPicker(){this._columnPickerOpen=!this._columnPickerOpen}_toggleColumn(e){this._displayedColumns.includes(e)?this._displayedColumns=this._displayedColumns.filter((t=>t!==e)):this._displayedColumns=[...this._displayedColumns,e]}_handleRowMouseDown(){this._def.rowClickable&&window.getSelection()?.removeAllRanges()}_handleRowClick(e,t){if(!this._def.rowClickable)return;const i=window.getSelection();i&&i.toString().length>0||this.dispatchEvent(new CustomEvent(\"row-click\",{detail:{row:e,rowIndex:t},bubbles:!0,composed:!0}))}getDisplayedColumns(){return this._displayedColumns.map((e=>this._def.columns.find((t=>t.id===e)))).sort(((e,t)=>\"actions\"===e.type&&\"actions\"!==t.type?1:\"actions\"!==e.type&&\"actions\"===t.type?-1:0))}_handleScroll(e){const t=e.target;this._canScrollLeft=t.scrollLeft>0,this._canScrollRight=t.scrollLeft<t.scrollWidth-t.clientWidth-1}_updateScrollFlags(){const e=this.shadowRoot?.querySelector(\".content\");e&&(this._canScrollLeft=e.scrollLeft>0,this._canScrollRight=e.scrollWidth>e.clientWidth&&e.scrollLeft<e.scrollWidth-e.clientWidth-1,this._canScrollHorizontal=e.scrollWidth>e.clientWidth),this.classList.toggle(\"kr-table--scroll-left-available\",this._canScrollLeft),this.classList.toggle(\"kr-table--scroll-right-available\",this._canScrollRight),this.classList.toggle(\"kr-table--scroll-horizontal-available\",this._canScrollHorizontal),this.classList.toggle(\"kr-table--sticky-left\",this.getDisplayedColumns().some((e=>\"left\"===e.sticky))),this.classList.toggle(\"kr-table--sticky-right\",this.getDisplayedColumns().some((e=>\"right\"===e.sticky)))}_handleResizeStart(e,t){e.preventDefault();const i=this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${t}\"]`);this._resizing={columnId:t,startX:e.clientX,startWidth:i?.offsetWidth||200},document.addEventListener(\"mousemove\",this._handleResizeMove),document.addEventListener(\"mouseup\",this._handleResizeEnd)}_handleAction(e){e.href||this.dispatchEvent(new CustomEvent(\"action\",{detail:{action:e.id},bubbles:!0,composed:!0}))}_renderCellContent(e,t,i){const o=t[e.id];if(e.render)return B`<slot name=\"cell-${i}-${e.id}\"></slot>`;if(null==o)return\"\";switch(e.type){case\"number\":return\"number\"==typeof o?o.toLocaleString():String(o);case\"currency\":return\"number\"==typeof o?o.toLocaleString(\"en-US\",{style:\"currency\",currency:\"USD\"}):String(o);case\"date\":{let e;if(o instanceof Date)e=o;else if(\"string\"==typeof o&&/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(o)){const t=o.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/,\"$1.$2\").replace(\" \",\"T\")+\"Z\";e=new Date(t)}else e=new Date(o);return e.toLocaleString(void 0,{year:\"numeric\",month:\"short\",day:\"numeric\",hour:\"numeric\",minute:\"2-digit\"})}case\"boolean\":return!0===o?\"Yes\":!1===o?\"No\":\"\";default:return String(o)}}_getHeaderCellClasses(e,t){return{\"header-cell\":!0,\"header-cell--align-center\":\"center\"===e.align,\"header-cell--align-right\":\"right\"===e.align,\"header-cell--sticky-left\":\"left\"===e.sticky,\"header-cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"header-cell--sticky-right\":\"right\"===e.sticky,\"header-cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellClasses(e,t){return{cell:!0,\"cell--actions\":\"actions\"===e.type,\"cell--align-center\":\"center\"===e.align,\"cell--align-right\":\"right\"===e.align,\"cell--sticky-left\":\"left\"===e.sticky,\"cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"cell--sticky-right\":\"right\"===e.sticky,\"cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellStyle(e,t){const i={};if(\"left\"===e.sticky){let e=0;for(let i=0;i<t;i++){const t=this.getDisplayedColumns()[i];\"left\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.left=`${e}px`}if(\"right\"===e.sticky){let e=0;for(let i=t+1;i<this.getDisplayedColumns().length;i++){const t=this.getDisplayedColumns()[i];\"right\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.right=`${e}px`}return i}_renderPagination(){const e=(this._page-1)*this._pageSize+1,t=Math.min(this._page*this._pageSize,this._totalItems);return B` <div class=\"pagination\"> <span class=\"pagination-icon ${1===this._page?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${e}-${t} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page===this._totalPages?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `}_renderHeader(){return!this._def.title&&!this._def.actions?.length&&this._totalPages<=1?U:B` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some((e=>e.searchable))?B` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `:B`<div class=\"search\"></div>`} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${()=>this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen?\"open\":\"\"}\"> ${[...this._def.columns].filter((e=>\"actions\"!==e.type)).sort(((e,t)=>(e.label??e.id).localeCompare(t.label??t.id))).map((e=>B` <div class=\"column-picker-item\" @click=${()=>this._toggleColumn(e.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(e.id)?\"checked\":\"\"}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${e.label??e.id}</span> </div> `))} </div> </div> ${1===this._def.actions?.length?B` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${()=>this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> `:this._def.actions?.length?B` <kr-button class=\"actions\" .options=${this._def.actions.map((e=>({id:e.id,label:e.label})))} @option-select=${e=>this._handleAction({id:e.detail.id,label:e.detail.label})} > Actions </kr-button> `:U} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?B`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?B`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?B`<div class=\"status\">No data available</div>`:U}_renderTable(){return B` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map(((e,t)=>B` <div class=${ke(this._getHeaderCellClasses(e,t))} style=${je(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?B`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:U}</div> `))} </div> ${this._data.map(((e,t)=>{const i=this.getDisplayedColumns().map(((i,o)=>B` <div class=${ke(this._getCellClasses(i,o))} style=${je(this._getCellStyle(i,o))} data-column-id=${i.id} > ${this._renderCellContent(i,e,t)} </div> `));return this._def.rowHref?B` <a href=${this._def.rowHref(e)} class=${ke({row:!0,\"row--clickable\":!0,\"row--link\":!0})} @mousedown=${()=>this._handleRowMouseDown()} @click=${()=>this._handleRowClick(e,t)} >${i}</a> `:B` <div class=${ke({row:!0,\"row--clickable\":!!this._def.rowClickable})} @mousedown=${()=>this._handleRowMouseDown()} @click=${()=>this._handleRowClick(e,t)} >${i}</div> `}))} </div> </div> </div> `}render(){return this._def.columns.length?B` ${this._renderHeader()} ${this._renderTable()} `:B`<slot></slot>`}}"
671
+ "name": "et",
672
+ "default": "class extends ne{constructor(){super(...arguments),this._scrollStyle=\"overlay\",this._data=[],this._dataState=\"idle\",this._page=1,this._pageSize=50,this._totalItems=0,this._totalPages=0,this._searchQuery=\"\",this._canScrollLeft=!1,this._canScrollRight=!1,this._canScrollHorizontal=!1,this._columnPickerOpen=!1,this._displayedColumns=[],this._resizing=null,this._resizeObserver=null,this._searchPositionLocked=!1,this._def={columns:[]},this.def={columns:[]},this._handleClickOutsideColumnPicker=e=>{if(!this._columnPickerOpen)return;const t=e.composedPath(),i=this.shadowRoot?.querySelector(\".column-picker-wrapper\");i&&!t.includes(i)&&(this._columnPickerOpen=!1)},this._handleResizeMove=e=>{if(!this._resizing)return;const t=this._def.columns.find((e=>e.id===this._resizing.columnId));if(t){const i=this._resizing.startWidth+(e.clientX-this._resizing.startX);t.width=`${Math.min(900,Math.max(50,i))}px`,this.requestUpdate()}},this._handleResizeEnd=()=>{this._resizing=null,document.removeEventListener(\"mousemove\",this._handleResizeMove),document.removeEventListener(\"mouseup\",this._handleResizeEnd)}}connectedCallback(){super.connectedCallback(),this.classList.toggle(\"kr-table--scroll-overlay\",\"overlay\"===this._scrollStyle),this.classList.toggle(\"kr-table--scroll-edge\",\"edge\"===this._scrollStyle),this._fetch(),this._initRefresh(),document.addEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver=new ResizeObserver((()=>{this._searchPositionLocked=!1,this._updateSearchPosition()})),this._resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),clearInterval(this._refreshTimer),document.removeEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver?.disconnect()}willUpdate(e){e.has(\"def\")&&(this._def={...this.def,columns:this.def.columns.map((e=>\"actions\"===e.type?{...e,label:e.label??\"\",sticky:\"right\",resizable:!1}:{...e}))},this._displayedColumns=this._def.displayedColumns||this._def.columns.map((e=>e.id)),this._fetch(),this._initRefresh())}updated(e){this._updateScrollFlags(),this._syncSlottedContent()}_syncSlottedContent(){const e=this.getDisplayedColumns().filter((e=>e.render));e.length&&(this.querySelectorAll('[slot^=\"cell-\"]').forEach((e=>e.remove())),this._data.forEach(((t,i)=>{e.forEach((e=>{const o=e.render(t);if(!o)return;const s=document.createElement(\"span\");s.slot=`cell-${i}-${e.id}`,\"actions\"===e.type&&(s.style.display=\"flex\",s.style.gap=\"8px\"),\"string\"==typeof o?s.innerHTML=o:se(o,s),this.appendChild(s)}))})))}refresh(){this._fetch()}goToPrevPage(){this._page>1&&(this._page--,this._fetch())}goToNextPage(){this._page<this._totalPages&&(this._page++,this._fetch())}goToPage(e){e>=1&&e<=this._totalPages&&(this._page=e,this._fetch())}_fetch(){if(!this._def.dataSource)return;let e;switch(this._dataState=\"loading\",this._def.dataSource.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&this._def.columns.filter((e=>e.searchable)).forEach((t=>{e.queryFields.push({name:t.id,operation:\"CONTAINS\",value:this._searchQuery,and:!1})}));break;default:e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&e.queryFields.push({name:\"_text_\",operation:\"IS\",value:Je(this._searchQuery)})}this._def.dataSource.fetch(e).then((e=>{switch(this._def.dataSource?.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size;break}default:{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size}}this._dataState=\"success\",this._updateSearchPosition()})).catch((e=>{this._dataState=\"error\",Fe.show({message:e instanceof Error?e.message:\"Failed to load data\",type:\"error\"})}))}_initRefresh(){clearInterval(this._refreshTimer),this._def.refreshInterval&&this._def.refreshInterval>0&&(this._refreshTimer=window.setInterval((()=>{this._fetch()}),this._def.refreshInterval))}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._page=1,this._fetch()}_getGridTemplateColumns(){return this.getDisplayedColumns().map((e=>e.width?e.width:\"actions\"===e.type?\"max-content\":\"minmax(80px, auto)\")).join(\" \")}_updateSearchPosition(){if(this._searchPositionLocked)return;const e=this.shadowRoot?.querySelector(\".search\"),t=e?.querySelector(\".search-field\");e&&t&&(e.style.justifyContent=\"center\",t.style.marginLeft=\"\",requestAnimationFrame((()=>{const i=e.getBoundingClientRect(),o=t.getBoundingClientRect().left-i.left;e.style.justifyContent=\"flex-start\",t.style.marginLeft=`${o}px`,this._searchPositionLocked=!0})))}_toggleColumnPicker(){this._columnPickerOpen=!this._columnPickerOpen}_toggleColumn(e){this._displayedColumns.includes(e)?this._displayedColumns=this._displayedColumns.filter((t=>t!==e)):this._displayedColumns=[...this._displayedColumns,e]}_handleRowMouseDown(){this._def.rowClickable&&window.getSelection()?.removeAllRanges()}_handleRowClick(e,t){if(!this._def.rowClickable)return;const i=window.getSelection();i&&i.toString().length>0||this.dispatchEvent(new CustomEvent(\"row-click\",{detail:{row:e,rowIndex:t},bubbles:!0,composed:!0}))}getDisplayedColumns(){return this._displayedColumns.map((e=>this._def.columns.find((t=>t.id===e)))).sort(((e,t)=>\"actions\"===e.type&&\"actions\"!==t.type?1:\"actions\"!==e.type&&\"actions\"===t.type?-1:0))}_handleScroll(e){const t=e.target;this._canScrollLeft=t.scrollLeft>0,this._canScrollRight=t.scrollLeft<t.scrollWidth-t.clientWidth-1}_updateScrollFlags(){const e=this.shadowRoot?.querySelector(\".content\");e&&(this._canScrollLeft=e.scrollLeft>0,this._canScrollRight=e.scrollWidth>e.clientWidth&&e.scrollLeft<e.scrollWidth-e.clientWidth-1,this._canScrollHorizontal=e.scrollWidth>e.clientWidth),this.classList.toggle(\"kr-table--scroll-left-available\",this._canScrollLeft),this.classList.toggle(\"kr-table--scroll-right-available\",this._canScrollRight),this.classList.toggle(\"kr-table--scroll-horizontal-available\",this._canScrollHorizontal),this.classList.toggle(\"kr-table--sticky-left\",this.getDisplayedColumns().some((e=>\"left\"===e.sticky))),this.classList.toggle(\"kr-table--sticky-right\",this.getDisplayedColumns().some((e=>\"right\"===e.sticky)))}_handleResizeStart(e,t){e.preventDefault();const i=this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${t}\"]`);this._resizing={columnId:t,startX:e.clientX,startWidth:i?.offsetWidth||200},document.addEventListener(\"mousemove\",this._handleResizeMove),document.addEventListener(\"mouseup\",this._handleResizeEnd)}_handleAction(e){e.href||this.dispatchEvent(new CustomEvent(\"action\",{detail:{action:e.id},bubbles:!0,composed:!0}))}_renderCellContent(e,t,i){const o=t[e.id];if(e.render)return B`<slot name=\"cell-${i}-${e.id}\"></slot>`;if(null==o)return\"\";switch(e.type){case\"number\":return\"number\"==typeof o?o.toLocaleString():String(o);case\"currency\":return\"number\"==typeof o?o.toLocaleString(\"en-US\",{style:\"currency\",currency:\"USD\"}):String(o);case\"date\":{let e;if(o instanceof Date)e=o;else if(\"string\"==typeof o&&/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(o)){const t=o.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/,\"$1.$2\").replace(\" \",\"T\")+\"Z\";e=new Date(t)}else e=new Date(o);return e.toLocaleString(void 0,{year:\"numeric\",month:\"short\",day:\"numeric\",hour:\"numeric\",minute:\"2-digit\"})}case\"boolean\":return!0===o?\"Yes\":!1===o?\"No\":\"\";default:return String(o)}}_getHeaderCellClasses(e,t){return{\"header-cell\":!0,\"header-cell--align-center\":\"center\"===e.align,\"header-cell--align-right\":\"right\"===e.align,\"header-cell--sticky-left\":\"left\"===e.sticky,\"header-cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"header-cell--sticky-right\":\"right\"===e.sticky,\"header-cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellClasses(e,t){return{cell:!0,\"cell--actions\":\"actions\"===e.type,\"cell--align-center\":\"center\"===e.align,\"cell--align-right\":\"right\"===e.align,\"cell--sticky-left\":\"left\"===e.sticky,\"cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"cell--sticky-right\":\"right\"===e.sticky,\"cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellStyle(e,t){const i={};if(\"left\"===e.sticky){let e=0;for(let i=0;i<t;i++){const t=this.getDisplayedColumns()[i];\"left\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.left=`${e}px`}if(\"right\"===e.sticky){let e=0;for(let i=t+1;i<this.getDisplayedColumns().length;i++){const t=this.getDisplayedColumns()[i];\"right\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.right=`${e}px`}return i}_renderPagination(){const e=(this._page-1)*this._pageSize+1,t=Math.min(this._page*this._pageSize,this._totalItems);return B` <div class=\"pagination\"> <span class=\"pagination-icon ${1===this._page?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${e}-${t} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page===this._totalPages?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `}_renderHeader(){return!this._def.title&&!this._def.actions?.length&&this._totalPages<=1?U:B` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some((e=>e.searchable))?B` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `:B`<div class=\"search\"></div>`} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${()=>this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen?\"open\":\"\"}\"> ${[...this._def.columns].filter((e=>\"actions\"!==e.type)).sort(((e,t)=>(e.label??e.id).localeCompare(t.label??t.id))).map((e=>B` <div class=\"column-picker-item\" @click=${()=>this._toggleColumn(e.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(e.id)?\"checked\":\"\"}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${e.label??e.id}</span> </div> `))} </div> </div> ${1===this._def.actions?.length?B` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${()=>this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> `:this._def.actions?.length?B` <kr-button class=\"actions\" .options=${this._def.actions.map((e=>({id:e.id,label:e.label})))} @option-select=${e=>this._handleAction({id:e.detail.id,label:e.detail.label})} > Actions </kr-button> `:U} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?B`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?B`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?B`<div class=\"status\">No data available</div>`:U}_renderTable(){return B` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map(((e,t)=>B` <div class=${we(this._getHeaderCellClasses(e,t))} style=${Me(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?B`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:U}</div> `))} </div> ${this._data.map(((e,t)=>{const i=this.getDisplayedColumns().map(((i,o)=>B` <div class=${we(this._getCellClasses(i,o))} style=${Me(this._getCellStyle(i,o))} data-column-id=${i.id} > ${this._renderCellContent(i,e,t)} </div> `));return this._def.rowHref?B` <a href=${this._def.rowHref(e)} class=${we({row:!0,\"row--clickable\":!0,\"row--link\":!0})} @mousedown=${()=>this._handleRowMouseDown()} @click=${()=>this._handleRowClick(e,t)} >${i}</a> `:B` <div class=${we({row:!0,\"row--clickable\":!!this._def.rowClickable})} @mousedown=${()=>this._handleRowMouseDown()} @click=${()=>this._handleRowClick(e,t)} >${i}</div> `}))} </div> </div> </div> `}render(){return this._def.columns.length?B` ${this._renderHeader()} ${this._renderTable()} `:B`<slot></slot>`}}"
673
673
  },
674
674
  {
675
675
  "kind": "variable",
676
- "name": "tt",
677
- "default": "class extends re{constructor(){super(...arguments),this.size=\"md\",this.color=\"dark\"}render(){var e=\"\",t=\"\";return e=\"sm\"==this.size?\"16px\":\"md\"==this.size?\"24px\":\"lg\"==this.size?\"32px\":\"xl\"==this.size?\"48px\":this.size,t=\"dark\"==this.color?\"#163052\":\"light\"==this.color?\"#ffffff\":this.color,B` <svg class=\"spinner\" style=${`width: ${e}; height: ${e}; color: ${t}`} viewBox=\"0 0 44 44\" role=\"status\" aria-label=\"Loading\" > <circle class=\"circle\" cx=\"22\" cy=\"22\" r=\"20\" fill=\"none\" stroke-width=\"4\" /> </svg> `}}"
676
+ "name": "it",
677
+ "default": "class extends ne{constructor(){super(...arguments),this.size=\"md\",this.color=\"dark\"}render(){var e=\"\",t=\"\";return e=\"sm\"==this.size?\"16px\":\"md\"==this.size?\"24px\":\"lg\"==this.size?\"32px\":\"xl\"==this.size?\"48px\":this.size,t=\"dark\"==this.color?\"#163052\":\"light\"==this.color?\"#ffffff\":this.color,B` <svg class=\"spinner\" style=${`width: ${e}; height: ${e}; color: ${t}`} viewBox=\"0 0 44 44\" role=\"status\" aria-label=\"Loading\" > <circle class=\"circle\" cx=\"22\" cy=\"22\" r=\"20\" fill=\"none\" stroke-width=\"4\" /> </svg> `}}"
678
678
  },
679
679
  {
680
680
  "kind": "variable",
681
- "name": "ot",
682
- "default": "class extends re{constructor(){super(...arguments),this.color=\"dark\"}render(){let e=\"\",t=\"\";return e=\"dark\"===this.color?\"#163052\":\"light\"===this.color?\"#ffffff\":this.color,t=this.trackColor?this.trackColor:\"light\"===this.color?\"#ffffff4d\":\"#0000001a\",B` <div class=\"progress-bar\" style=${`background: ${t}`} role=\"status\" aria-label=\"Loading\" > <div class=\"fill\" style=${`background: ${e}`}></div> </div> `}}"
681
+ "name": "st",
682
+ "default": "class extends ne{constructor(){super(...arguments),this.color=\"dark\"}render(){let e=\"\",t=\"\";return e=\"dark\"===this.color?\"#163052\":\"light\"===this.color?\"#ffffff\":this.color,t=this.trackColor?this.trackColor:\"light\"===this.color?\"#ffffff4d\":\"#0000001a\",B` <div class=\"progress-bar\" style=${`background: ${t}`} role=\"status\" aria-label=\"Loading\" > <div class=\"fill\" style=${`background: ${e}`}></div> </div> `}}"
683
683
  },
684
684
  {
685
685
  "kind": "variable",
686
- "name": "nt"
686
+ "name": "lt"
687
687
  },
688
688
  {
689
689
  "kind": "variable",
690
- "name": "at",
691
- "default": "class extends re{constructor(){super(...arguments),this.files=[],this.emptyMessage=\"No files\"}_handleFileClick(e){if(this.dispatchEvent(new CustomEvent(\"file-click\",{bubbles:!0,composed:!0,detail:{file:e}})),e.url){nt.open({src:e.url,name:e.name}).addEventListener(\"download\",(()=>{this._handleDownload(e)}))}}_handleDownload(e){this.dispatchEvent(new CustomEvent(\"download\",{bubbles:!0,composed:!0,detail:{file:e}}))}_handleDelete(e){this.dispatchEvent(new CustomEvent(\"delete\",{bubbles:!0,composed:!0,detail:{file:e}}))}_getExtension(e){return e.split(\".\").pop()?.toLowerCase()||\"\"}_getExtClass(e){return[\"pdf\"].includes(e)?\"file-list__ext--pdf\":[\"doc\",\"docx\",\"rtf\",\"txt\"].includes(e)?\"file-list__ext--doc\":[\"xls\",\"xlsx\",\"csv\"].includes(e)?\"file-list__ext--xls\":[\"zip\",\"rar\",\"7z\",\"gz\",\"tar\"].includes(e)?\"file-list__ext--zip\":[\"jpg\",\"jpeg\",\"png\",\"gif\",\"webp\",\"svg\",\"bmp\"].includes(e)?\"file-list__ext--img\":\"file-list__ext--default\"}_getExtIcon(e){return[\"jpg\",\"jpeg\",\"png\",\"gif\",\"webp\",\"svg\",\"bmp\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86-3 3.87L9 13.14 6 17h12l-3.86-5.14z\"/></svg>`:[\"pdf\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 7.5c0 .83-.67 1.5-1.5 1.5H9v2H7.5V7H10c.83 0 1.5.67 1.5 1.5v1zm5 2c0 .83-.67 1.5-1.5 1.5h-2.5V7H15c.83 0 1.5.67 1.5 1.5v3zm4-3H19v1h1.5V11H19v2h-1.5V7h3v1.5zM9 9.5h1v-1H9v1zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm10 5.5h1v-3h-1v3z\"/></svg>`:[\"doc\",\"docx\",\"rtf\",\"txt\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6zm2-6h8v2H8v-2zm0-4h8v2H8v-2zm0 8h5v2H8v-2z\"/></svg>`:[\"xls\",\"xlsx\",\"csv\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v3H5V5h14zm0 5v4H5v-4h14zM5 19v-3h14v3H5zm2-8h4v2H7v-2zm0 5h4v2H7v-2z\"/></svg>`:[\"zip\",\"rar\",\"7z\",\"gz\",\"tar\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V6h5.17l2 2H20v10zm-8-4h2v2h-2v-2zm0-4h2v2h-2v-2zm-2 2h2v2h-2v-2z\"/></svg>`:B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z\"/></svg>`}render(){return this.files.length?B` <div class=\"file-list\"> ${this.files.map((e=>{const t=this._getExtension(e.name),i=e.meta||e.date||\"\";return B` <div class=\"file-list__item\"> <div class=\"file-list__ext ${this._getExtClass(t)}\">${this._getExtIcon(t)}</div> <div class=\"file-list__info\"> <a class=\"file-list__name\" @click=${()=>this._handleFileClick(e)}>${e.name}</a> ${i?B`<div class=\"file-list__meta\">${i}</div>`:\"\"} </div> <div class=\"file-list__actions\"> <svg class=\"file-list__action\" @click=${()=>this._handleDownload(e)} xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" title=\"Download\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zm-8 2V5h2v6h1.17L12 13.17 9.83 11H11zm-6 7h14v2H5v-2z\"/></svg> <svg class=\"file-list__action file-list__action--delete\" @click=${()=>this._handleDelete(e)} xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" title=\"Delete\"><path d=\"M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z\"/></svg> </div> </div> `}))} </div> `:B`<div class=\"file-list__empty\">${this.emptyMessage}</div>`}}"
690
+ "name": "dt",
691
+ "default": "class extends ne{constructor(){super(...arguments),this.files=[],this.emptyMessage=\"No files\"}_handleFileClick(e){if(this.dispatchEvent(new CustomEvent(\"file-click\",{bubbles:!0,composed:!0,detail:{file:e}})),e.url){lt.open({src:e.url,name:e.name}).addEventListener(\"download\",(()=>{this._handleDownload(e)}))}}_handleDownload(e){this.dispatchEvent(new CustomEvent(\"download\",{bubbles:!0,composed:!0,detail:{file:e}}))}_handleDelete(e){this.dispatchEvent(new CustomEvent(\"delete\",{bubbles:!0,composed:!0,detail:{file:e}}))}_getExtension(e){return e.split(\".\").pop()?.toLowerCase()||\"\"}_getExtClass(e){return[\"pdf\"].includes(e)?\"file-list__ext--pdf\":[\"doc\",\"docx\",\"rtf\",\"txt\"].includes(e)?\"file-list__ext--doc\":[\"xls\",\"xlsx\",\"csv\"].includes(e)?\"file-list__ext--xls\":[\"zip\",\"rar\",\"7z\",\"gz\",\"tar\"].includes(e)?\"file-list__ext--zip\":[\"jpg\",\"jpeg\",\"png\",\"gif\",\"webp\",\"svg\",\"bmp\"].includes(e)?\"file-list__ext--img\":\"file-list__ext--default\"}_getExtIcon(e){return[\"jpg\",\"jpeg\",\"png\",\"gif\",\"webp\",\"svg\",\"bmp\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86-3 3.87L9 13.14 6 17h12l-3.86-5.14z\"/></svg>`:[\"pdf\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 7.5c0 .83-.67 1.5-1.5 1.5H9v2H7.5V7H10c.83 0 1.5.67 1.5 1.5v1zm5 2c0 .83-.67 1.5-1.5 1.5h-2.5V7H15c.83 0 1.5.67 1.5 1.5v3zm4-3H19v1h1.5V11H19v2h-1.5V7h3v1.5zM9 9.5h1v-1H9v1zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm10 5.5h1v-3h-1v3z\"/></svg>`:[\"doc\",\"docx\",\"rtf\",\"txt\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6zm2-6h8v2H8v-2zm0-4h8v2H8v-2zm0 8h5v2H8v-2z\"/></svg>`:[\"xls\",\"xlsx\",\"csv\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v3H5V5h14zm0 5v4H5v-4h14zM5 19v-3h14v3H5zm2-8h4v2H7v-2zm0 5h4v2H7v-2z\"/></svg>`:[\"zip\",\"rar\",\"7z\",\"gz\",\"tar\"].includes(e)?B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V6h5.17l2 2H20v10zm-8-4h2v2h-2v-2zm0-4h2v2h-2v-2zm-2 2h2v2h-2v-2z\"/></svg>`:B`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z\"/></svg>`}render(){return this.files.length?B` <div class=\"file-list\"> ${this.files.map((e=>{const t=this._getExtension(e.name),i=e.meta||e.date||\"\";return B` <div class=\"file-list__item\"> <div class=\"file-list__ext ${this._getExtClass(t)}\">${this._getExtIcon(t)}</div> <div class=\"file-list__info\"> <a class=\"file-list__name\" @click=${()=>this._handleFileClick(e)}>${e.name}</a> ${i?B`<div class=\"file-list__meta\">${i}</div>`:\"\"} </div> <div class=\"file-list__actions\"> <svg class=\"file-list__action\" @click=${()=>this._handleDownload(e)} xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" title=\"Download\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zm-8 2V5h2v6h1.17L12 13.17 9.83 11H11zm-6 7h14v2H5v-2z\"/></svg> <svg class=\"file-list__action file-list__action--delete\" @click=${()=>this._handleDelete(e)} xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" title=\"Delete\"><path d=\"M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z\"/></svg> </div> </div> `}))} </div> `:B`<div class=\"file-list__empty\">${this.emptyMessage}</div>`}}"
692
692
  },
693
693
  {
694
694
  "kind": "variable",
695
- "name": "ut",
696
- "default": "class extends re{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.type=\"text\",this.required=!1,this.disabled=!1,this.readonly=!1,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._input&&this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._input.validity,this._input.validationMessage)}render(){let e=\"\";return this._touched&&this._input&&!this._input.validity.valid&&(e=this._input.validationMessage),B` <div class=\"wrapper\"> ${this.label?B` <label for=\"input\"> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:\"\"} <input id=\"input\" class=${ke({\"input--invalid\":this._touched&&this._input&&!this._input.validity.valid})} type=${this.type} name=${this.name} .value=${ht(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} minlength=${dt(this.minlength)} maxlength=${dt(this.maxlength)} pattern=${dt(this.pattern)} autocomplete=${dt(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} /> ${e?B`<div class=\"validation-message\">${e}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> `}focus(){this._input?.focus()}blur(){this._input?.blur()}select(){this._input?.select()}}"
695
+ "name": "gt",
696
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.type=\"text\",this.required=!1,this.disabled=!1,this.readonly=!1,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._input&&this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._input.validity,this._input.validationMessage)}render(){let e=\"\";return this._touched&&this._input&&!this._input.validity.valid&&(e=this._input.validationMessage),B` <div class=\"wrapper\"> ${this.label?B` <label for=\"input\"> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:\"\"} <input id=\"input\" class=${we({\"input--invalid\":this._touched&&this._input&&!this._input.validity.valid})} type=${this.type} name=${this.name} .value=${pt(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} minlength=${ct(this.minlength)} maxlength=${ct(this.maxlength)} pattern=${ct(this.pattern)} autocomplete=${ct(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} /> ${e?B`<div class=\"validation-message\">${e}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> `}focus(){this._input?.focus()}blur(){this._input?.blur()}select(){this._input?.select()}}"
697
697
  },
698
698
  {
699
699
  "kind": "variable",
700
- "name": "ft",
701
- "default": "class extends re{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"Select an option\",this.disabled=!1,this.required=!1,this.readonly=!1,this.hint=\"\",this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._handleOutsideClick=e=>{e.composedPath().includes(this)||this._close()},this._handleKeyDown=e=>{if(!this._isOpen)return;const t=Array.from(this.querySelectorAll(\"kr-select-option\"));switch(e.key){case\"Escape\":this._close(),this._triggerElement?.focus();break;case\"ArrowDown\":if(e.preventDefault(),t.some((e=>!e.disabled))){let e=this._highlightedIndex+1;for(;e<t.length&&t[e]?.disabled;)e++;e<t.length&&(this._highlightedIndex=e)}break;case\"ArrowUp\":e.preventDefault();{let e=this._highlightedIndex-1;for(;e>=0&&t[e]?.disabled;)e--;e>=0&&(this._highlightedIndex=e)}break;case\"Enter\":e.preventDefault(),this._highlightedIndex>=0&&this._highlightedIndex<t.length&&this._selectOption(t[this._highlightedIndex])}},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleOutsideClick),document.addEventListener(\"keydown\",this._handleKeyDown),this.addEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleOutsideClick),document.removeEventListener(\"keydown\",this._handleKeyDown),this.removeEventListener(\"invalid\",this._handleInvalid)}_toggle(){if(!this.disabled&&!this.readonly)if(this._isOpen)this._close();else{this._isOpen=!0;const e=Array.from(this.querySelectorAll(\"kr-select-option\"));this._highlightedIndex=e.findIndex((e=>e.value===this.value)),requestAnimationFrame((()=>{const e=this.shadowRoot?.querySelector(\".select-dropdown\");if(e){const t=this._triggerElement.getBoundingClientRect(),i=window.innerHeight-t.bottom-4-8;e.style.top=t.bottom+4+\"px\",e.style.left=t.left+\"px\",e.style.width=t.width+\"px\",e.style.maxHeight=i+\"px\"}}))}}_close(){this._isOpen=!1,this._highlightedIndex=-1}_selectOption(e){e.disabled||(this.value=e.value,this._internals.setFormValue(this.value),this._updateValidity(),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})),this._close(),this._triggerElement?.focus())}_handleBlur(){this._touched=!0,this._updateValidity()}_updateValidity(){this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"Please select an option\",this._triggerElement):this._internals.setValidity({})}render(){const e=Array.from(this.querySelectorAll(\"kr-select-option\")),t=e.find((e=>e.value===this.value))?.label;return B` <div class=\"wrapper\"> ${this.label?B` <label> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:U} <div class=\"select-wrapper\"> <button class=${ke({\"select-trigger\":!0,\"select-trigger--open\":this._isOpen,\"select-trigger--invalid\":this._touched&&this.required&&!this.value})} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${ke({\"select-value\":!0,\"select-placeholder\":!t})}> ${t||this.placeholder} </span> <svg class=${ke({\"chevron-icon\":!0,\"select-icon\":!0,\"select-icon--open\":this._isOpen})} viewBox=\"0 0 24 24\" fill=\"currentColor\" > <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z\"/> </svg> </button> <div class=${ke({\"select-dropdown\":!0,hidden:!this._isOpen})} role=\"listbox\"> <div class=\"select-options\"> ${0===e.length?B`<div class=\"select-empty\">No options available</div>`:e.map(((e,t)=>{const i=e.value===this.value;return B` <div class=${ke({\"select-option\":!0,\"select-option--selected\":i,\"select-option--disabled\":e.disabled,\"select-option--highlighted\":t===this._highlightedIndex})} role=\"option\" aria-selected=${i} @click=${()=>this._selectOption(e)} @mouseenter=${()=>this._highlightedIndex=t} > ${e.label} </div> `}))} </div> </div> </div> ${this._touched&&this.required&&!this.value?B`<div class=\"validation-message\">Please select an option</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> <div class=\"options-slot\"> <slot @slotchange=${()=>this.requestUpdate()}></slot> </div> `}focus(){this._triggerElement?.focus()}blur(){this._triggerElement?.blur()}}"
700
+ "name": "vt",
701
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"Select an option\",this.disabled=!1,this.required=!1,this.readonly=!1,this.hint=\"\",this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._handleOutsideClick=e=>{e.composedPath().includes(this)||this._close()},this._handleKeyDown=e=>{if(!this._isOpen)return;const t=Array.from(this.querySelectorAll(\"kr-select-option\"));switch(e.key){case\"Escape\":this._close(),this._triggerElement?.focus();break;case\"ArrowDown\":if(e.preventDefault(),t.some((e=>!e.disabled))){let e=this._highlightedIndex+1;for(;e<t.length&&t[e]?.disabled;)e++;e<t.length&&(this._highlightedIndex=e)}break;case\"ArrowUp\":e.preventDefault();{let e=this._highlightedIndex-1;for(;e>=0&&t[e]?.disabled;)e--;e>=0&&(this._highlightedIndex=e)}break;case\"Enter\":e.preventDefault(),this._highlightedIndex>=0&&this._highlightedIndex<t.length&&this._selectOption(t[this._highlightedIndex])}},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleOutsideClick),document.addEventListener(\"keydown\",this._handleKeyDown),this.addEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleOutsideClick),document.removeEventListener(\"keydown\",this._handleKeyDown),this.removeEventListener(\"invalid\",this._handleInvalid)}_toggle(){if(!this.disabled&&!this.readonly)if(this._isOpen)this._close();else{this._isOpen=!0;const e=Array.from(this.querySelectorAll(\"kr-select-option\"));this._highlightedIndex=e.findIndex((e=>e.value===this.value)),requestAnimationFrame((()=>{const e=this.shadowRoot?.querySelector(\".select-dropdown\");if(e){const t=this._triggerElement.getBoundingClientRect(),i=window.innerHeight-t.bottom-4-8;e.style.top=t.bottom+4+\"px\",e.style.left=t.left+\"px\",e.style.width=t.width+\"px\",e.style.maxHeight=i+\"px\"}}))}}_close(){this._isOpen=!1,this._highlightedIndex=-1}_selectOption(e){e.disabled||(this.value=e.value,this._internals.setFormValue(this.value),this._updateValidity(),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})),this._close(),this._triggerElement?.focus())}_handleBlur(){this._touched=!0,this._updateValidity()}_updateValidity(){this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"Please select an option\",this._triggerElement):this._internals.setValidity({})}render(){const e=Array.from(this.querySelectorAll(\"kr-select-option\")),t=e.find((e=>e.value===this.value))?.label;return B` <div class=\"wrapper\"> ${this.label?B` <label> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:U} <div class=\"select-wrapper\"> <button class=${we({\"select-trigger\":!0,\"select-trigger--open\":this._isOpen,\"select-trigger--invalid\":this._touched&&this.required&&!this.value})} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${we({\"select-value\":!0,\"select-placeholder\":!t})}> ${t||this.placeholder} </span> <svg class=${we({\"chevron-icon\":!0,\"select-icon\":!0,\"select-icon--open\":this._isOpen})} viewBox=\"0 0 24 24\" fill=\"currentColor\" > <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z\"/> </svg> </button> <div class=${we({\"select-dropdown\":!0,hidden:!this._isOpen})} role=\"listbox\"> <div class=\"select-options\"> ${0===e.length?B`<div class=\"select-empty\">No options available</div>`:e.map(((e,t)=>{const i=e.value===this.value;return B` <div class=${we({\"select-option\":!0,\"select-option--selected\":i,\"select-option--disabled\":e.disabled,\"select-option--highlighted\":t===this._highlightedIndex})} role=\"option\" aria-selected=${i} @click=${()=>this._selectOption(e)} @mouseenter=${()=>this._highlightedIndex=t} > ${e.label} </div> `}))} </div> </div> </div> ${this._touched&&this.required&&!this.value?B`<div class=\"validation-message\">Please select an option</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> <div class=\"options-slot\"> <slot @slotchange=${()=>this.requestUpdate()}></slot> </div> `}focus(){this._triggerElement?.focus()}blur(){this._triggerElement?.blur()}}"
702
702
  },
703
703
  {
704
704
  "kind": "variable",
705
- "name": "bt",
706
- "default": "class extends re{constructor(){super(...arguments),this.value=\"\",this.disabled=!1}get label(){return this.textContent?.trim()||\"\"}render(){return B`<slot></slot>`}}"
705
+ "name": "mt",
706
+ "default": "class extends ne{constructor(){super(...arguments),this.value=\"\",this.disabled=!1}get label(){return this.textContent?.trim()||\"\"}render(){return B`<slot></slot>`}}"
707
707
  },
708
708
  {
709
709
  "kind": "variable",
710
- "name": "yt",
711
- "default": "class extends re{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.required=!1,this.disabled=!1,this.readonly=!1,this.rows=3,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._textarea&&this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}render(){let e=\"\";return this._touched&&this._textarea&&!this._textarea.validity.valid&&(e=this._textarea.validationMessage),B` <div class=\"wrapper\"> ${this.label?B` <label for=\"textarea\"> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:U} </label> `:U} <textarea id=\"textarea\" class=${ke({\"textarea--invalid\":this._touched&&this._textarea&&!this._textarea.validity.valid})} name=${this.name} .value=${ht(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} rows=${this.rows} cols=${dt(this.cols)} minlength=${dt(this.minlength)} maxlength=${dt(this.maxlength)} autocomplete=${dt(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} ></textarea> ${e?B`<div class=\"validation-message\">${e}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:U} </div> `}focus(){this._textarea?.focus()}blur(){this._textarea?.blur()}select(){this._textarea?.select()}}"
710
+ "name": "_t",
711
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.required=!1,this.disabled=!1,this.readonly=!1,this.rows=3,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._textarea&&this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}render(){let e=\"\";return this._touched&&this._textarea&&!this._textarea.validity.valid&&(e=this._textarea.validationMessage),B` <div class=\"wrapper\"> ${this.label?B` <label for=\"textarea\"> ${this.label} ${this.required?B`<span class=\"required\" aria-hidden=\"true\">*</span>`:U} </label> `:U} <textarea id=\"textarea\" class=${we({\"textarea--invalid\":this._touched&&this._textarea&&!this._textarea.validity.valid})} name=${this.name} .value=${pt(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} rows=${this.rows} cols=${ct(this.cols)} minlength=${ct(this.minlength)} maxlength=${ct(this.maxlength)} autocomplete=${ct(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} ></textarea> ${e?B`<div class=\"validation-message\">${e}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:U} </div> `}focus(){this._textarea?.focus()}blur(){this._textarea?.blur()}select(){this._textarea?.select()}}"
712
712
  },
713
713
  {
714
714
  "kind": "variable",
715
- "name": "$t",
716
- "default": "class extends re{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.disabled=!1,this.readonly=!1,this.required=!1,this.hint=\"\",this.options=[],this.statusType=\"finished\",this.loadingText=\"Loading...\",this.errorText=\"Error loading options\",this.emptyText=\"No matches found\",this.filteringType=\"auto\",this.highlightMatches=!0,this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._dirty=!1,this._handleDocumentClick=this._onDocumentClick.bind(this),this._internals=this.attachInternals()}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleDocumentClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleDocumentClick)}firstUpdated(){this._updateFormValue()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._isOpen=!1,this._highlightedIndex=-1,this._updateFormValue()}formStateRestoreCallback(e){this.value=e}get _filteredOptions(){if(\"manual\"===this.filteringType||!this.value)return this.options;const e=this.value.toLowerCase(),t=[];for(const i of this.options)if(wt(i)){const o=i.options.filter((t=>{const i=(t.label||t.value).toLowerCase(),o=t.filteringTags?.join(\" \").toLowerCase()||\"\";return i.includes(e)||o.includes(e)}));o.length>0&&t.push({...i,options:o})}else{const o=(i.label||i.value).toLowerCase(),s=i.filteringTags?.join(\" \").toLowerCase()||\"\";(o.includes(e)||s.includes(e))&&t.push(i)}return t}get _flatOptions(){const e=[];for(const t of this._filteredOptions)wt(t)?e.push(...t.options):e.push(t);return e}_updateFormValue(){this._internals.setFormValue(this.value),this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"This field is required\",this._input):this._internals.setValidity({})}_onInput(e){const t=e.target;this.value=t.value,this._dirty=!0,this._isOpen=!0,this._highlightedIndex=-1,this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"change\",{detail:{value:this.value},bubbles:!0,composed:!0})),\"manual\"===this.filteringType&&this.dispatchEvent(new CustomEvent(\"load-items\",{detail:{filteringText:this.value},bubbles:!0,composed:!0}))}_onFocus(){this._isOpen=!0,\"manual\"===this.filteringType&&this.dispatchEvent(new CustomEvent(\"load-items\",{detail:{filteringText:this.value},bubbles:!0,composed:!0}))}_onBlur(){this._touched=!0,setTimeout((()=>{this._isOpen=!1,this._highlightedIndex=-1}),200),this._updateFormValue()}_onKeyDown(e){const t=this._flatOptions;switch(e.key){case\"ArrowDown\":e.preventDefault(),this._isOpen=!0,this._highlightedIndex=Math.min(this._highlightedIndex+1,t.length-1),this._scrollToHighlighted();break;case\"ArrowUp\":e.preventDefault(),this._highlightedIndex=Math.max(this._highlightedIndex-1,-1),this._scrollToHighlighted();break;case\"Enter\":this._highlightedIndex>=0&&t[this._highlightedIndex]&&(e.preventDefault(),this._selectOption(t[this._highlightedIndex]));break;case\"Escape\":e.preventDefault(),this._isOpen=!1,this._highlightedIndex=-1;break;case\"Tab\":this._isOpen=!1,this._highlightedIndex=-1}}_scrollToHighlighted(){this.updateComplete.then((()=>{const e=this.shadowRoot?.querySelector(\".dropdown\"),t=this.shadowRoot?.querySelector(\".option.is-highlighted\");if(e&&t){const i=e.getBoundingClientRect(),o=t.getBoundingClientRect();(o.bottom>i.bottom||o.top<i.top)&&t.scrollIntoView({block:\"nearest\"})}}))}_selectOption(e){e.disabled||(this.value=e.label||e.value,this._isOpen=!1,this._highlightedIndex=-1,this._dirty=!0,this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"select\",{detail:{value:e.value,selectedOption:e},bubbles:!0,composed:!0})),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})))}_handleClear(){this.value=\"\",this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"change\",{detail:{value:\"\"},bubbles:!0,composed:!0})),this._input?.focus()}_onDocumentClick(e){e.composedPath().includes(this)||(this._isOpen=!1)}_highlightMatch(e){if(!this.value||\"manual\"===this.filteringType||!this.highlightMatches)return B`${e}`;const t=this.value.toLowerCase(),i=e.toLowerCase().indexOf(t);if(-1===i)return B`${e}`;const o=e.slice(0,i),s=e.slice(i,i+this.value.length),r=e.slice(i+this.value.length);return B`${o}<span class=\"highlight\">${s}</span>${r}`}_renderOption(e,t){const i=t===this._highlightedIndex;return B` <button class=${ke({option:!0,\"is-highlighted\":i})} type=\"button\" role=\"option\" aria-selected=${i} ?disabled=${e.disabled} @click=${()=>this._selectOption(e)} @mouseenter=${()=>{this._highlightedIndex=t}} > <div class=\"option-content\"> <div class=\"option-label\"> ${this._highlightMatch(e.label||e.value)} ${e.labelTag?B`<span class=\"option-tag\">${e.labelTag}</span>`:U} </div> ${e.description?B`<div class=\"option-description\">${e.description}</div>`:U} ${e.tags&&e.tags.length>0?B` <div class=\"option-tags\"> ${e.tags.map((e=>B`<span class=\"option-tag\">${e}</span>`))} </div> `:U} </div> </button> `}_renderDropdownContent(){if(\"loading\"===this.statusType)return B` <div class=\"status\"> <div class=\"spinner\"></div> ${this.loadingText} </div> `;if(\"error\"===this.statusType)return B` <div class=\"status is-error\"> <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z\" /> </svg> ${this.errorText} </div> `;const e=this._filteredOptions;if(0===e.length)return B`<div class=\"empty\">${this.emptyText}</div>`;let t=0;return B` ${e.map((e=>{if(wt(e)){const i=e.options.map((e=>{const i=this._renderOption(e,t);return t++,i}));return B` <div class=\"group-label\">${e.label}</div> ${i} `}const i=this._renderOption(e,t);return t++,i}))} `}render(){const e=this._touched&&!this.validity.valid;return B` <div class=\"field-wrapper\"> ${this.label?B` <label> ${this.label} ${this.required?B`<span class=\"required\">*</span>`:U} </label> `:U} <div class=\"input-container\"> <div class=\"input-wrapper\"> <input type=\"text\" .value=${ht(this.value)} placeholder=${dt(this.placeholder||void 0)} ?disabled=${this.disabled} ?readonly=${this.readonly} ?required=${this.required} name=${dt(this.name||void 0)} autocomplete=\"off\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=${this._isOpen} aria-controls=\"dropdown\" class=${ke({\"input--invalid\":e})} @input=${this._onInput} @blur=${this._onBlur} @focus=${this._onFocus} @keydown=${this._onKeyDown} /> <div class=\"icon-container\"> ${!this.value||this.disabled||this.readonly?\"\":B` <button class=\"clear-button\" type=\"button\" aria-label=\"Clear\" @click=${this._handleClear} > <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" /> </svg> </button> `} ${this.value||this.disabled||this.readonly?\"\":B` <svg class=\"search-icon\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z\" /> </svg> `} </div> </div> <div id=\"dropdown\" role=\"listbox\" class=${ke({dropdown:!0,\"is-open\":this._isOpen})} > ${this._renderDropdownContent()} </div> </div> ${e?B`<div class=\"validation-message\">${this.validationMessage}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:U} </div> `}}"
715
+ "name": "Ct",
716
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.disabled=!1,this.readonly=!1,this.required=!1,this.hint=\"\",this.options=[],this.statusType=\"finished\",this.loadingText=\"Loading...\",this.errorText=\"Error loading options\",this.emptyText=\"No matches found\",this.filteringType=\"auto\",this.highlightMatches=!0,this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._dirty=!1,this._handleDocumentClick=this._onDocumentClick.bind(this),this._internals=this.attachInternals()}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleDocumentClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleDocumentClick)}firstUpdated(){this._updateFormValue()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._isOpen=!1,this._highlightedIndex=-1,this._updateFormValue()}formStateRestoreCallback(e){this.value=e}get _filteredOptions(){if(\"manual\"===this.filteringType||!this.value)return this.options;const e=this.value.toLowerCase(),t=[];for(const i of this.options)if($t(i)){const o=i.options.filter((t=>{const i=(t.label||t.value).toLowerCase(),o=t.filteringTags?.join(\" \").toLowerCase()||\"\";return i.includes(e)||o.includes(e)}));o.length>0&&t.push({...i,options:o})}else{const o=(i.label||i.value).toLowerCase(),s=i.filteringTags?.join(\" \").toLowerCase()||\"\";(o.includes(e)||s.includes(e))&&t.push(i)}return t}get _flatOptions(){const e=[];for(const t of this._filteredOptions)$t(t)?e.push(...t.options):e.push(t);return e}_updateFormValue(){this._internals.setFormValue(this.value),this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"This field is required\",this._input):this._internals.setValidity({})}_onInput(e){const t=e.target;this.value=t.value,this._dirty=!0,this._isOpen=!0,this._highlightedIndex=-1,this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"change\",{detail:{value:this.value},bubbles:!0,composed:!0})),\"manual\"===this.filteringType&&this.dispatchEvent(new CustomEvent(\"load-items\",{detail:{filteringText:this.value},bubbles:!0,composed:!0}))}_onFocus(){this._isOpen=!0,\"manual\"===this.filteringType&&this.dispatchEvent(new CustomEvent(\"load-items\",{detail:{filteringText:this.value},bubbles:!0,composed:!0}))}_onBlur(){this._touched=!0,setTimeout((()=>{this._isOpen=!1,this._highlightedIndex=-1}),200),this._updateFormValue()}_onKeyDown(e){const t=this._flatOptions;switch(e.key){case\"ArrowDown\":e.preventDefault(),this._isOpen=!0,this._highlightedIndex=Math.min(this._highlightedIndex+1,t.length-1),this._scrollToHighlighted();break;case\"ArrowUp\":e.preventDefault(),this._highlightedIndex=Math.max(this._highlightedIndex-1,-1),this._scrollToHighlighted();break;case\"Enter\":this._highlightedIndex>=0&&t[this._highlightedIndex]&&(e.preventDefault(),this._selectOption(t[this._highlightedIndex]));break;case\"Escape\":e.preventDefault(),this._isOpen=!1,this._highlightedIndex=-1;break;case\"Tab\":this._isOpen=!1,this._highlightedIndex=-1}}_scrollToHighlighted(){this.updateComplete.then((()=>{const e=this.shadowRoot?.querySelector(\".dropdown\"),t=this.shadowRoot?.querySelector(\".option.is-highlighted\");if(e&&t){const i=e.getBoundingClientRect(),o=t.getBoundingClientRect();(o.bottom>i.bottom||o.top<i.top)&&t.scrollIntoView({block:\"nearest\"})}}))}_selectOption(e){e.disabled||(this.value=e.label||e.value,this._isOpen=!1,this._highlightedIndex=-1,this._dirty=!0,this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"select\",{detail:{value:e.value,selectedOption:e},bubbles:!0,composed:!0})),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})))}_handleClear(){this.value=\"\",this._updateFormValue(),this.dispatchEvent(new CustomEvent(\"change\",{detail:{value:\"\"},bubbles:!0,composed:!0})),this._input?.focus()}_onDocumentClick(e){e.composedPath().includes(this)||(this._isOpen=!1)}_highlightMatch(e){if(!this.value||\"manual\"===this.filteringType||!this.highlightMatches)return B`${e}`;const t=this.value.toLowerCase(),i=e.toLowerCase().indexOf(t);if(-1===i)return B`${e}`;const o=e.slice(0,i),s=e.slice(i,i+this.value.length),r=e.slice(i+this.value.length);return B`${o}<span class=\"highlight\">${s}</span>${r}`}_renderOption(e,t){const i=t===this._highlightedIndex;return B` <button class=${we({option:!0,\"is-highlighted\":i})} type=\"button\" role=\"option\" aria-selected=${i} ?disabled=${e.disabled} @click=${()=>this._selectOption(e)} @mouseenter=${()=>{this._highlightedIndex=t}} > <div class=\"option-content\"> <div class=\"option-label\"> ${this._highlightMatch(e.label||e.value)} ${e.labelTag?B`<span class=\"option-tag\">${e.labelTag}</span>`:U} </div> ${e.description?B`<div class=\"option-description\">${e.description}</div>`:U} ${e.tags&&e.tags.length>0?B` <div class=\"option-tags\"> ${e.tags.map((e=>B`<span class=\"option-tag\">${e}</span>`))} </div> `:U} </div> </button> `}_renderDropdownContent(){if(\"loading\"===this.statusType)return B` <div class=\"status\"> <div class=\"spinner\"></div> ${this.loadingText} </div> `;if(\"error\"===this.statusType)return B` <div class=\"status is-error\"> <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z\" /> </svg> ${this.errorText} </div> `;const e=this._filteredOptions;if(0===e.length)return B`<div class=\"empty\">${this.emptyText}</div>`;let t=0;return B` ${e.map((e=>{if($t(e)){const i=e.options.map((e=>{const i=this._renderOption(e,t);return t++,i}));return B` <div class=\"group-label\">${e.label}</div> ${i} `}const i=this._renderOption(e,t);return t++,i}))} `}render(){const e=this._touched&&!this.validity.valid;return B` <div class=\"field-wrapper\"> ${this.label?B` <label> ${this.label} ${this.required?B`<span class=\"required\">*</span>`:U} </label> `:U} <div class=\"input-container\"> <div class=\"input-wrapper\"> <input type=\"text\" .value=${pt(this.value)} placeholder=${ct(this.placeholder||void 0)} ?disabled=${this.disabled} ?readonly=${this.readonly} ?required=${this.required} name=${ct(this.name||void 0)} autocomplete=\"off\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=${this._isOpen} aria-controls=\"dropdown\" class=${we({\"input--invalid\":e})} @input=${this._onInput} @blur=${this._onBlur} @focus=${this._onFocus} @keydown=${this._onKeyDown} /> <div class=\"icon-container\"> ${!this.value||this.disabled||this.readonly?\"\":B` <button class=\"clear-button\" type=\"button\" aria-label=\"Clear\" @click=${this._handleClear} > <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" /> </svg> </button> `} ${this.value||this.disabled||this.readonly?\"\":B` <svg class=\"search-icon\" fill=\"currentColor\" viewBox=\"0 0 16 16\"> <path d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z\" /> </svg> `} </div> </div> <div id=\"dropdown\" role=\"listbox\" class=${we({dropdown:!0,\"is-open\":this._isOpen})} > ${this._renderDropdownContent()} </div> </div> ${e?B`<div class=\"validation-message\">${this.validationMessage}</div>`:this.hint?B`<div class=\"hint\">${this.hint}</div>`:U} </div> `}}"
717
717
  }
718
718
  ],
719
719
  "exports": [
@@ -737,7 +737,7 @@
737
737
  "kind": "js",
738
738
  "name": "KRAccordion",
739
739
  "declaration": {
740
- "name": "fe",
740
+ "name": "ve",
741
741
  "module": "dist/krubble-components.bundled.min.js"
742
742
  }
743
743
  },
@@ -745,7 +745,7 @@
745
745
  "kind": "js",
746
746
  "name": "KRAlert",
747
747
  "declaration": {
748
- "name": "$e",
748
+ "name": "Ce",
749
749
  "module": "dist/krubble-components.bundled.min.js"
750
750
  }
751
751
  },
@@ -753,7 +753,7 @@
753
753
  "kind": "js",
754
754
  "name": "KRAutoSuggest",
755
755
  "declaration": {
756
- "name": "$t",
756
+ "name": "Ct",
757
757
  "module": "dist/krubble-components.bundled.min.js"
758
758
  }
759
759
  },
@@ -761,7 +761,7 @@
761
761
  "kind": "js",
762
762
  "name": "KRButton",
763
763
  "declaration": {
764
- "name": "ze",
764
+ "name": "Se",
765
765
  "module": "dist/krubble-components.bundled.min.js"
766
766
  }
767
767
  },
@@ -769,7 +769,7 @@
769
769
  "kind": "js",
770
770
  "name": "KRCodeDemo",
771
771
  "declaration": {
772
- "name": "Ae",
772
+ "name": "Te",
773
773
  "module": "dist/krubble-components.bundled.min.js"
774
774
  }
775
775
  },
@@ -777,7 +777,7 @@
777
777
  "kind": "js",
778
778
  "name": "KRContextMenu",
779
779
  "declaration": {
780
- "name": "Le",
780
+ "name": "Pe",
781
781
  "module": "dist/krubble-components.bundled.min.js"
782
782
  }
783
783
  },
@@ -785,7 +785,7 @@
785
785
  "kind": "js",
786
786
  "name": "KRDialog",
787
787
  "declaration": {
788
- "name": "Be",
788
+ "name": "qe",
789
789
  "module": "dist/krubble-components.bundled.min.js"
790
790
  }
791
791
  },
@@ -793,7 +793,7 @@
793
793
  "kind": "js",
794
794
  "name": "KRDialogRef",
795
795
  "declaration": {
796
- "name": "Ve",
796
+ "name": "Be",
797
797
  "module": "dist/krubble-components.bundled.min.js"
798
798
  }
799
799
  },
@@ -801,7 +801,7 @@
801
801
  "kind": "js",
802
802
  "name": "KRFileList",
803
803
  "declaration": {
804
- "name": "at",
804
+ "name": "dt",
805
805
  "module": "dist/krubble-components.bundled.min.js"
806
806
  }
807
807
  },
@@ -809,7 +809,7 @@
809
809
  "kind": "js",
810
810
  "name": "KRFilePreview",
811
811
  "declaration": {
812
- "name": "nt",
812
+ "name": "lt",
813
813
  "module": "dist/krubble-components.bundled.min.js"
814
814
  }
815
815
  },
@@ -817,7 +817,7 @@
817
817
  "kind": "js",
818
818
  "name": "KRProgressBar",
819
819
  "declaration": {
820
- "name": "ot",
820
+ "name": "st",
821
821
  "module": "dist/krubble-components.bundled.min.js"
822
822
  }
823
823
  },
@@ -825,7 +825,7 @@
825
825
  "kind": "js",
826
826
  "name": "KRSelectField",
827
827
  "declaration": {
828
- "name": "ft",
828
+ "name": "vt",
829
829
  "module": "dist/krubble-components.bundled.min.js"
830
830
  }
831
831
  },
@@ -833,7 +833,7 @@
833
833
  "kind": "js",
834
834
  "name": "KRSelectOption",
835
835
  "declaration": {
836
- "name": "bt",
836
+ "name": "mt",
837
837
  "module": "dist/krubble-components.bundled.min.js"
838
838
  }
839
839
  },
@@ -841,7 +841,7 @@
841
841
  "kind": "js",
842
842
  "name": "KRSnackbar",
843
843
  "declaration": {
844
- "name": "Ne",
844
+ "name": "Fe",
845
845
  "module": "dist/krubble-components.bundled.min.js"
846
846
  }
847
847
  },
@@ -849,7 +849,7 @@
849
849
  "kind": "js",
850
850
  "name": "KRSpinner",
851
851
  "declaration": {
852
- "name": "tt",
852
+ "name": "it",
853
853
  "module": "dist/krubble-components.bundled.min.js"
854
854
  }
855
855
  },
@@ -857,7 +857,7 @@
857
857
  "kind": "js",
858
858
  "name": "KRTab",
859
859
  "declaration": {
860
- "name": "Xe",
860
+ "name": "Ye",
861
861
  "module": "dist/krubble-components.bundled.min.js"
862
862
  }
863
863
  },
@@ -865,7 +865,7 @@
865
865
  "kind": "js",
866
866
  "name": "KRTabGroup",
867
867
  "declaration": {
868
- "name": "We",
868
+ "name": "Ke",
869
869
  "module": "dist/krubble-components.bundled.min.js"
870
870
  }
871
871
  },
@@ -873,7 +873,7 @@
873
873
  "kind": "js",
874
874
  "name": "KRTable",
875
875
  "declaration": {
876
- "name": "Je",
876
+ "name": "et",
877
877
  "module": "dist/krubble-components.bundled.min.js"
878
878
  }
879
879
  },
@@ -881,7 +881,7 @@
881
881
  "kind": "js",
882
882
  "name": "KRTextField",
883
883
  "declaration": {
884
- "name": "ut",
884
+ "name": "gt",
885
885
  "module": "dist/krubble-components.bundled.min.js"
886
886
  }
887
887
  },
@@ -889,7 +889,7 @@
889
889
  "kind": "js",
890
890
  "name": "KRTextareaField",
891
891
  "declaration": {
892
- "name": "yt",
892
+ "name": "_t",
893
893
  "module": "dist/krubble-components.bundled.min.js"
894
894
  }
895
895
  },
@@ -897,7 +897,7 @@
897
897
  "kind": "js",
898
898
  "name": "krBaseCSS",
899
899
  "declaration": {
900
- "name": "le",
900
+ "name": "ae",
901
901
  "module": "dist/krubble-components.bundled.min.js"
902
902
  }
903
903
  }
@@ -980,6 +980,28 @@
980
980
  }
981
981
  ]
982
982
  },
983
+ {
984
+ "kind": "javascript-module",
985
+ "path": "dist/accordion/accordion.js",
986
+ "declarations": [
987
+ {
988
+ "kind": "variable",
989
+ "name": "KRAccordion",
990
+ "default": "class KRAccordion extends LitElement { constructor() { super(...arguments); /** * Section header text */ this.header = ''; /** * Whether the accordion is expanded */ this.expanded = false; } toggle() { this.expanded = !this.expanded; } render() { return html ` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `; } }",
991
+ "description": "Accordion component for collapsible content sections.\n\n## Usage\n```html\n<kr-accordion header=\"Basic Information\" expanded>\n <div>Content here</div>\n</kr-accordion>\n```"
992
+ }
993
+ ],
994
+ "exports": [
995
+ {
996
+ "kind": "js",
997
+ "name": "KRAccordion",
998
+ "declaration": {
999
+ "name": "KRAccordion",
1000
+ "module": "dist/accordion/accordion.js"
1001
+ }
1002
+ }
1003
+ ]
1004
+ },
983
1005
  {
984
1006
  "kind": "javascript-module",
985
1007
  "path": "src/index.ts",
@@ -1283,28 +1305,6 @@
1283
1305
  }
1284
1306
  ]
1285
1307
  },
1286
- {
1287
- "kind": "javascript-module",
1288
- "path": "dist/accordion/accordion.js",
1289
- "declarations": [
1290
- {
1291
- "kind": "variable",
1292
- "name": "KRAccordion",
1293
- "default": "class KRAccordion extends LitElement { constructor() { super(...arguments); /** * Section header text */ this.header = ''; /** * Whether the accordion is expanded */ this.expanded = false; } toggle() { this.expanded = !this.expanded; } render() { return html ` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `; } }",
1294
- "description": "Accordion component for collapsible content sections.\n\n## Usage\n```html\n<kr-accordion header=\"Basic Information\" expanded>\n <div>Content here</div>\n</kr-accordion>\n```"
1295
- }
1296
- ],
1297
- "exports": [
1298
- {
1299
- "kind": "js",
1300
- "name": "KRAccordion",
1301
- "declaration": {
1302
- "name": "KRAccordion",
1303
- "module": "dist/accordion/accordion.js"
1304
- }
1305
- }
1306
- ]
1307
- },
1308
1308
  {
1309
1309
  "kind": "javascript-module",
1310
1310
  "path": "dist/alert/alert.js",
@@ -1733,7 +1733,7 @@
1733
1733
  {
1734
1734
  "kind": "variable",
1735
1735
  "name": "KRTable",
1736
- "default": "class KRTable extends LitElement { constructor() { super(...arguments); /** * Internal flag to switch between scroll edge modes: * - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge) * - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling */ this._scrollStyle = 'overlay'; this._data = []; this._dataState = 'idle'; this._page = 1; this._pageSize = 50; this._totalItems = 0; this._totalPages = 0; this._searchQuery = ''; this._canScrollLeft = false; this._canScrollRight = false; this._canScrollHorizontal = false; this._columnPickerOpen = false; this._displayedColumns = []; this._resizing = null; this._resizeObserver = null; this._searchPositionLocked = false; this._def = { columns: [] }; this.def = { columns: [] }; this._handleClickOutsideColumnPicker = (e) => { if (!this._columnPickerOpen) return; const path = e.composedPath(); const picker = this.shadowRoot?.querySelector('.column-picker-wrapper'); if (picker && !path.includes(picker)) { this._columnPickerOpen = false; } }; this._handleResizeMove = (e) => { if (!this._resizing) return; const col = this._def.columns.find(c => c.id === this._resizing.columnId); if (col) { const newWidth = this._resizing.startWidth + (e.clientX - this._resizing.startX); col.width = `${Math.min(900, Math.max(50, newWidth))}px`; this.requestUpdate(); } }; this._handleResizeEnd = () => { this._resizing = null; document.removeEventListener('mousemove', this._handleResizeMove); document.removeEventListener('mouseup', this._handleResizeEnd); }; } connectedCallback() { super.connectedCallback(); this.classList.toggle('kr-table--scroll-overlay', this._scrollStyle === 'overlay'); this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge'); this._fetch(); this._initRefresh(); document.addEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver = new ResizeObserver(() => { // Unlock and recalculate on resize since layout changes this._searchPositionLocked = false; this._updateSearchPosition(); }); this._resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); clearInterval(this._refreshTimer); document.removeEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver?.disconnect(); } willUpdate(changedProperties) { if (changedProperties.has('def')) { // Copy user's def and normalize action columns this._def = { ...this.def, columns: this.def.columns.map(col => { if (col.type === 'actions') { return { ...col, label: col.label ?? '', sticky: 'right', resizable: false }; } return { ...col }; }) }; this._displayedColumns = this._def.displayedColumns || this._def.columns.map(c => c.id); this._fetch(); this._initRefresh(); } } updated(changedProperties) { this._updateScrollFlags(); this._syncSlottedContent(); } /** Syncs light DOM content for cells with custom render functions */ _syncSlottedContent() { const columns = this.getDisplayedColumns().filter(col => col.render); if (!columns.length) return; // Clear old slotted content this.querySelectorAll('[slot^=\"cell-\"]').forEach(el => el.remove()); // Create new slotted content this._data.forEach((row, rowIndex) => { columns.forEach(col => { const result = col.render(row); const content = typeof result === 'string' ? result : ''; if (content) { const el = document.createElement('span'); el.slot = `cell-${rowIndex}-${col.id}`; if (col.type === 'actions') { el.style.display = 'flex'; el.style.gap = '8px'; } el.innerHTML = content; this.appendChild(el); } }); }); } // ---------------------------------------------------------------------------- // Public Interface // ---------------------------------------------------------------------------- refresh() { this._fetch(); } goToPrevPage() { if (this._page > 1) { this._page--; this._fetch(); } } goToNextPage() { if (this._page < this._totalPages) { this._page++; this._fetch(); } } goToPage(page) { if (page >= 1 && page <= this._totalPages) { this._page = page; this._fetch(); } } // ---------------------------------------------------------------------------- // Data Fetching // ---------------------------------------------------------------------------- /** * Fetches data from the API and updates the table. * Shows a loading spinner while fetching, then displays rows on success * or an error snackbar on failure. * Request/response format depends on dataSource.mode (solr, opensearch, db). */ _fetch() { if (!this._def.dataSource) return; this._dataState = 'loading'; // Build request based on mode let request; switch (this._def.dataSource.mode) { case 'opensearch': throw Error('Opensearch not supported yet'); case 'db': request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { this._def.columns.filter(col => col.searchable).forEach(col => { request.queryFields.push({ name: col.id, operation: 'CONTAINS', value: this._searchQuery, and: false }); }); } break; default: // solr request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { request.queryFields.push({ name: '_text_', operation: 'IS', value: escapeSolrQuery(this._searchQuery) }); } } this._def.dataSource.fetch(request) .then(response => { // Parse response based on mode switch (this._def.dataSource?.mode) { case 'opensearch': { throw Error('Opensearch not supported yet'); break; } case 'db': { const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; break; } default: { // solr const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; } } this._dataState = 'success'; this._updateSearchPosition(); }) .catch(err => { this._dataState = 'error'; KRSnackbar.show({ message: err instanceof Error ? err.message : 'Failed to load data', type: 'error' }); }); } /** * Sets up auto-refresh so the table automatically fetches fresh data * at a regular interval (useful for dashboards, monitoring views). * Configured via def.refreshInterval in milliseconds. */ _initRefresh() { clearInterval(this._refreshTimer); if (this._def.refreshInterval && this._def.refreshInterval > 0) { this._refreshTimer = window.setInterval(() => { this._fetch(); }, this._def.refreshInterval); } } _handleSearch(e) { const input = e.target; this._searchQuery = input.value; this._page = 1; this._fetch(); } _getGridTemplateColumns() { const cols = this.getDisplayedColumns(); return cols.map((col) => { // If column has explicit width, use it if (col.width) { return col.width; } // Actions columns: fit content without minimum if (col.type === 'actions') { return 'max-content'; } // No width specified - use content-based sizing with minimum return 'minmax(80px, auto)'; }).join(' '); } /** * Updates search position to be centered with equal gaps from title and tools. * On first call: resets to flex centering, measures position, then locks with fixed margin. * Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize). */ _updateSearchPosition() { // Skip if already locked (prevents shifts on pagination changes) if (this._searchPositionLocked) return; const search = this.shadowRoot?.querySelector('.search'); const searchField = search?.querySelector('.search-field'); if (!search || !searchField) return; // Reset to flex centering search.style.justifyContent = 'center'; searchField.style.marginLeft = ''; requestAnimationFrame(() => { const searchRect = search.getBoundingClientRect(); const fieldRect = searchField.getBoundingClientRect(); // Calculate how far from the left of search container the field currently is const currentOffset = fieldRect.left - searchRect.left; // Lock position: switch to flex-start and use fixed margin search.style.justifyContent = 'flex-start'; searchField.style.marginLeft = `${currentOffset}px`; // Mark as locked so pagination changes don't shift the search this._searchPositionLocked = true; }); } // ---------------------------------------------------------------------------- // Columns // ---------------------------------------------------------------------------- _toggleColumnPicker() { this._columnPickerOpen = !this._columnPickerOpen; } _toggleColumn(columnId) { if (this._displayedColumns.includes(columnId)) { this._displayedColumns = this._displayedColumns.filter(id => id !== columnId); } else { this._displayedColumns = [...this._displayedColumns, columnId]; } } // Clear any existing text selection on mousedown so we only detect // selections made during this click gesture, not stale selections from elsewhere _handleRowMouseDown() { if (!this._def.rowClickable) { return; } window.getSelection()?.removeAllRanges(); } _handleRowClick(row, rowIndex) { if (!this._def.rowClickable) { return; } const selection = window.getSelection(); if (selection && selection.toString().length > 0) { return; } this.dispatchEvent(new CustomEvent('row-click', { detail: { row, rowIndex }, bubbles: true, composed: true })); } // When a user toggles a column on via the column picker, it gets appended // to _displayedColumns. By mapping over _displayedColumns (not def.columns), // the new column appears at the right edge of the table instead of jumping // back to its original position in the column definition. // Actions columns are always moved to the end. getDisplayedColumns() { return this._displayedColumns .map(id => this._def.columns.find(col => col.id === id)) .sort((a, b) => { if (a.type === 'actions' && b.type !== 'actions') return 1; if (a.type !== 'actions' && b.type === 'actions') return -1; return 0; }); } // ---------------------------------------------------------------------------- // Scrolling // ---------------------------------------------------------------------------- /** * Scroll event handler that updates scroll flags in real-time as user scrolls. * Updates shadow indicators to show if more content exists left/right. */ _handleScroll(e) { const container = e.target; this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1; } /** * Updates scroll state flags for the table content container. * - _canScrollLeft: true if scrolled right (can scroll back left) * - _canScrollRight: true if more content exists to the right * - _canScrollHorizontal: true if content is wider than container * These flags control scroll shadow indicators and CSS classes. */ _updateScrollFlags() { const container = this.shadowRoot?.querySelector('.content'); if (container) { this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1; this._canScrollHorizontal = container.scrollWidth > container.clientWidth; } this.classList.toggle('kr-table--scroll-left-available', this._canScrollLeft); this.classList.toggle('kr-table--scroll-right-available', this._canScrollRight); this.classList.toggle('kr-table--scroll-horizontal-available', this._canScrollHorizontal); this.classList.toggle('kr-table--sticky-left', this.getDisplayedColumns().some(c => c.sticky === 'left')); this.classList.toggle('kr-table--sticky-right', this.getDisplayedColumns().some(c => c.sticky === 'right')); } // ---------------------------------------------------------------------------- // Column Resizing // ---------------------------------------------------------------------------- _handleResizeStart(e, columnId) { e.preventDefault(); const headerCell = this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${columnId}\"]`); this._resizing = { columnId, startX: e.clientX, startWidth: headerCell?.offsetWidth || 200 }; document.addEventListener('mousemove', this._handleResizeMove); document.addEventListener('mouseup', this._handleResizeEnd); } // ---------------------------------------------------------------------------- // Header // ---------------------------------------------------------------------------- _handleAction(action) { if (action.href) { return; } this.dispatchEvent(new CustomEvent('action', { detail: { action: action.id }, bubbles: true, composed: true })); } // ---------------------------------------------------------------------------- // Rendering // ---------------------------------------------------------------------------- _renderCellContent(column, row, rowIndex) { const value = row[column.id]; if (column.render) { // Use slot to project content from light DOM so external styles apply return html `<slot name=\"cell-${rowIndex}-${column.id}\"></slot>`; } if (value === null || value === undefined) { return ''; } switch (column.type) { case 'number': return typeof value === 'number' ? value.toLocaleString() : String(value); case 'currency': return typeof value === 'number' ? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }) : String(value); case 'date': { let date; if (value instanceof Date) { date = value; } else if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(value)) { // MySQL datetime format (UTC): \"2026-01-28 01:33:44:517\" // Replace last colon before ms with dot, append Z for UTC const isoString = value.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/, '$1.$2').replace(' ', 'T') + 'Z'; date = new Date(isoString); } else { date = new Date(value); } // Show date and time for datetime values return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); } case 'boolean': if (value === true) return 'Yes'; if (value === false) return 'No'; return ''; default: return String(value); } } /** * Returns CSS classes for a header cell based on column config. */ _getHeaderCellClasses(column, index) { return { 'header-cell': true, 'header-cell--align-center': column.align === 'center', 'header-cell--align-right': column.align === 'right', 'header-cell--sticky-left': column.sticky === 'left', 'header-cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'header-cell--sticky-right': column.sticky === 'right', 'header-cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns CSS classes for a table cell based on column config: * - Alignment (center, right) * - Sticky positioning (left, right) * - Border classes for the last left-sticky or first right-sticky column */ _getCellClasses(column, index) { return { 'cell': true, 'cell--actions': column.type === 'actions', 'cell--align-center': column.align === 'center', 'cell--align-right': column.align === 'right', 'cell--sticky-left': column.sticky === 'left', 'cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'cell--sticky-right': column.sticky === 'right', 'cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns inline styles for a table cell: * - Width (from column config or default 150px) * - Min-width (if specified) * - Left/right offset for sticky columns (calculated from widths of preceding sticky columns) */ _getCellStyle(column, index) { const styles = {}; if (column.sticky === 'left') { let leftOffset = 0; for (let i = 0; i < index; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'left') { leftOffset += parseInt(col.width || '0', 10); } } styles.left = `${leftOffset}px`; } if (column.sticky === 'right') { let rightOffset = 0; for (let i = index + 1; i < this.getDisplayedColumns().length; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'right') { rightOffset += parseInt(col.width || '0', 10); } } styles.right = `${rightOffset}px`; } return styles; } /** * Renders the pagination controls: * - Previous page arrow (disabled on first page) * - Range text showing \"1-50 of 150\" format * - Next page arrow (disabled on last page) * * Hidden when there's no data or all data fits on one page. */ _renderPagination() { const start = (this._page - 1) * this._pageSize + 1; const end = Math.min(this._page * this._pageSize, this._totalItems); return html ` <div class=\"pagination\"> <span class=\"pagination-icon ${this._page === 1 ? 'pagination-icon--disabled' : ''}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${start}-${end} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page === this._totalPages ? 'pagination-icon--disabled' : ''}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `; } /** * Renders the header toolbar containing: * - Title (left) * - Search bar with view selector dropdown (center) * - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown * * Hidden when there's no title, no actions, and data fits on one page. */ _renderHeader() { if (!this._def.title && !this._def.actions?.length && this._totalPages <= 1) { return nothing; } return html ` <div class=\"header\"> <div class=\"title\">${this._def.title ?? ''}</div> ${this._def.dataSource?.mode === 'db' && !this._def.columns.some(col => col.searchable) ? html `<div class=\"search\"></div>` : html ` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${() => this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen ? 'open' : ''}\"> ${[...this._def.columns].filter(col => col.type !== 'actions').sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => html ` <div class=\"column-picker-item\" @click=${() => this._toggleColumn(col.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(col.id) ? 'checked' : ''}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${col.label ?? col.id}</span> </div> `)} </div> </div> ${this._def.actions?.length === 1 ? html ` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${() => this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> ` : this._def.actions?.length ? html ` <kr-button class=\"actions\" .options=${this._def.actions.map(a => ({ id: a.id, label: a.label }))} @option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })} > Actions </kr-button> ` : nothing} </div> </div> `; } /** Renders status message (loading, error, empty) */ _renderStatus() { if (this._dataState === 'loading' && this._data.length === 0) { return html `<div class=\"status\">Loading...</div>`; } if (this._dataState === 'error' && this._data.length === 0) { return html `<div class=\"status status--error\">Error loading data</div>`; } if (this._data.length === 0) { return html `<div class=\"status\">No data available</div>`; } return nothing; } /** Renders the scrollable data grid with column headers and rows. */ _renderTable() { return html ` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map((col, i) => html ` <div class=${classMap(this._getHeaderCellClasses(col, i))} style=${styleMap(this._getCellStyle(col, i))} data-column-id=${col.id} >${col.label ?? col.id}${col.resizable !== false ? html `<div class=\"header-cell__resize\" @mousedown=${(e) => this._handleResizeStart(e, col.id)} ></div>` : nothing}</div> `)} </div> ${this._data.map((row, rowIndex) => { const cells = this.getDisplayedColumns().map((col, i) => html ` <div class=${classMap(this._getCellClasses(col, i))} style=${styleMap(this._getCellStyle(col, i))} data-column-id=${col.id} > ${this._renderCellContent(col, row, rowIndex)} </div> `); if (this._def.rowHref) { return html ` <a href=${this._def.rowHref(row)} class=${classMap({ 'row': true, 'row--clickable': true, 'row--link': true })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</a> `; } return html ` <div class=${classMap({ 'row': true, 'row--clickable': !!this._def.rowClickable })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</div> `; })} </div> </div> </div> `; } /** * Renders a data table with: * - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown) * - Scrollable grid with sticky header row and optional sticky left/right columns * - Loading, error message, or empty state when no data */ render() { if (!this._def.columns.length) { return html `<slot></slot>`; } return html ` ${this._renderHeader()} ${this._renderTable()} `; } }"
1736
+ "default": "class KRTable extends LitElement { constructor() { super(...arguments); /** * Internal flag to switch between scroll edge modes: * - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge) * - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling */ this._scrollStyle = 'overlay'; this._data = []; this._dataState = 'idle'; this._page = 1; this._pageSize = 50; this._totalItems = 0; this._totalPages = 0; this._searchQuery = ''; this._canScrollLeft = false; this._canScrollRight = false; this._canScrollHorizontal = false; this._columnPickerOpen = false; this._displayedColumns = []; this._resizing = null; this._resizeObserver = null; this._searchPositionLocked = false; this._def = { columns: [] }; this.def = { columns: [] }; this._handleClickOutsideColumnPicker = (e) => { if (!this._columnPickerOpen) return; const path = e.composedPath(); const picker = this.shadowRoot?.querySelector('.column-picker-wrapper'); if (picker && !path.includes(picker)) { this._columnPickerOpen = false; } }; this._handleResizeMove = (e) => { if (!this._resizing) return; const col = this._def.columns.find(c => c.id === this._resizing.columnId); if (col) { const newWidth = this._resizing.startWidth + (e.clientX - this._resizing.startX); col.width = `${Math.min(900, Math.max(50, newWidth))}px`; this.requestUpdate(); } }; this._handleResizeEnd = () => { this._resizing = null; document.removeEventListener('mousemove', this._handleResizeMove); document.removeEventListener('mouseup', this._handleResizeEnd); }; } connectedCallback() { super.connectedCallback(); this.classList.toggle('kr-table--scroll-overlay', this._scrollStyle === 'overlay'); this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge'); this._fetch(); this._initRefresh(); document.addEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver = new ResizeObserver(() => { // Unlock and recalculate on resize since layout changes this._searchPositionLocked = false; this._updateSearchPosition(); }); this._resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); clearInterval(this._refreshTimer); document.removeEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver?.disconnect(); } willUpdate(changedProperties) { if (changedProperties.has('def')) { // Copy user's def and normalize action columns this._def = { ...this.def, columns: this.def.columns.map(col => { if (col.type === 'actions') { return { ...col, label: col.label ?? '', sticky: 'right', resizable: false }; } return { ...col }; }) }; this._displayedColumns = this._def.displayedColumns || this._def.columns.map(c => c.id); this._fetch(); this._initRefresh(); } } updated(changedProperties) { this._updateScrollFlags(); this._syncSlottedContent(); } /** Syncs light DOM content for cells with custom render functions */ _syncSlottedContent() { const columns = this.getDisplayedColumns().filter(col => col.render); if (!columns.length) return; // Clear old slotted content this.querySelectorAll('[slot^=\"cell-\"]').forEach(el => el.remove()); // Create new slotted content this._data.forEach((row, rowIndex) => { columns.forEach(col => { const result = col.render(row); if (!result) return; const el = document.createElement('span'); el.slot = `cell-${rowIndex}-${col.id}`; if (col.type === 'actions') { el.style.display = 'flex'; el.style.gap = '8px'; } if (typeof result === 'string') { el.innerHTML = result; } else { render(result, el); } this.appendChild(el); }); }); } // ---------------------------------------------------------------------------- // Public Interface // ---------------------------------------------------------------------------- refresh() { this._fetch(); } goToPrevPage() { if (this._page > 1) { this._page--; this._fetch(); } } goToNextPage() { if (this._page < this._totalPages) { this._page++; this._fetch(); } } goToPage(page) { if (page >= 1 && page <= this._totalPages) { this._page = page; this._fetch(); } } // ---------------------------------------------------------------------------- // Data Fetching // ---------------------------------------------------------------------------- /** * Fetches data from the API and updates the table. * Shows a loading spinner while fetching, then displays rows on success * or an error snackbar on failure. * Request/response format depends on dataSource.mode (solr, opensearch, db). */ _fetch() { if (!this._def.dataSource) return; this._dataState = 'loading'; // Build request based on mode let request; switch (this._def.dataSource.mode) { case 'opensearch': throw Error('Opensearch not supported yet'); case 'db': request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { this._def.columns.filter(col => col.searchable).forEach(col => { request.queryFields.push({ name: col.id, operation: 'CONTAINS', value: this._searchQuery, and: false }); }); } break; default: // solr request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { request.queryFields.push({ name: '_text_', operation: 'IS', value: escapeSolrQuery(this._searchQuery) }); } } this._def.dataSource.fetch(request) .then(response => { // Parse response based on mode switch (this._def.dataSource?.mode) { case 'opensearch': { throw Error('Opensearch not supported yet'); break; } case 'db': { const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; break; } default: { // solr const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; } } this._dataState = 'success'; this._updateSearchPosition(); }) .catch(err => { this._dataState = 'error'; KRSnackbar.show({ message: err instanceof Error ? err.message : 'Failed to load data', type: 'error' }); }); } /** * Sets up auto-refresh so the table automatically fetches fresh data * at a regular interval (useful for dashboards, monitoring views). * Configured via def.refreshInterval in milliseconds. */ _initRefresh() { clearInterval(this._refreshTimer); if (this._def.refreshInterval && this._def.refreshInterval > 0) { this._refreshTimer = window.setInterval(() => { this._fetch(); }, this._def.refreshInterval); } } _handleSearch(e) { const input = e.target; this._searchQuery = input.value; this._page = 1; this._fetch(); } _getGridTemplateColumns() { const cols = this.getDisplayedColumns(); return cols.map((col) => { // If column has explicit width, use it if (col.width) { return col.width; } // Actions columns: fit content without minimum if (col.type === 'actions') { return 'max-content'; } // No width specified - use content-based sizing with minimum return 'minmax(80px, auto)'; }).join(' '); } /** * Updates search position to be centered with equal gaps from title and tools. * On first call: resets to flex centering, measures position, then locks with fixed margin. * Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize). */ _updateSearchPosition() { // Skip if already locked (prevents shifts on pagination changes) if (this._searchPositionLocked) return; const search = this.shadowRoot?.querySelector('.search'); const searchField = search?.querySelector('.search-field'); if (!search || !searchField) return; // Reset to flex centering search.style.justifyContent = 'center'; searchField.style.marginLeft = ''; requestAnimationFrame(() => { const searchRect = search.getBoundingClientRect(); const fieldRect = searchField.getBoundingClientRect(); // Calculate how far from the left of search container the field currently is const currentOffset = fieldRect.left - searchRect.left; // Lock position: switch to flex-start and use fixed margin search.style.justifyContent = 'flex-start'; searchField.style.marginLeft = `${currentOffset}px`; // Mark as locked so pagination changes don't shift the search this._searchPositionLocked = true; }); } // ---------------------------------------------------------------------------- // Columns // ---------------------------------------------------------------------------- _toggleColumnPicker() { this._columnPickerOpen = !this._columnPickerOpen; } _toggleColumn(columnId) { if (this._displayedColumns.includes(columnId)) { this._displayedColumns = this._displayedColumns.filter(id => id !== columnId); } else { this._displayedColumns = [...this._displayedColumns, columnId]; } } // Clear any existing text selection on mousedown so we only detect // selections made during this click gesture, not stale selections from elsewhere _handleRowMouseDown() { if (!this._def.rowClickable) { return; } window.getSelection()?.removeAllRanges(); } _handleRowClick(row, rowIndex) { if (!this._def.rowClickable) { return; } const selection = window.getSelection(); if (selection && selection.toString().length > 0) { return; } this.dispatchEvent(new CustomEvent('row-click', { detail: { row, rowIndex }, bubbles: true, composed: true })); } // When a user toggles a column on via the column picker, it gets appended // to _displayedColumns. By mapping over _displayedColumns (not def.columns), // the new column appears at the right edge of the table instead of jumping // back to its original position in the column definition. // Actions columns are always moved to the end. getDisplayedColumns() { return this._displayedColumns .map(id => this._def.columns.find(col => col.id === id)) .sort((a, b) => { if (a.type === 'actions' && b.type !== 'actions') return 1; if (a.type !== 'actions' && b.type === 'actions') return -1; return 0; }); } // ---------------------------------------------------------------------------- // Scrolling // ---------------------------------------------------------------------------- /** * Scroll event handler that updates scroll flags in real-time as user scrolls. * Updates shadow indicators to show if more content exists left/right. */ _handleScroll(e) { const container = e.target; this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1; } /** * Updates scroll state flags for the table content container. * - _canScrollLeft: true if scrolled right (can scroll back left) * - _canScrollRight: true if more content exists to the right * - _canScrollHorizontal: true if content is wider than container * These flags control scroll shadow indicators and CSS classes. */ _updateScrollFlags() { const container = this.shadowRoot?.querySelector('.content'); if (container) { this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1; this._canScrollHorizontal = container.scrollWidth > container.clientWidth; } this.classList.toggle('kr-table--scroll-left-available', this._canScrollLeft); this.classList.toggle('kr-table--scroll-right-available', this._canScrollRight); this.classList.toggle('kr-table--scroll-horizontal-available', this._canScrollHorizontal); this.classList.toggle('kr-table--sticky-left', this.getDisplayedColumns().some(c => c.sticky === 'left')); this.classList.toggle('kr-table--sticky-right', this.getDisplayedColumns().some(c => c.sticky === 'right')); } // ---------------------------------------------------------------------------- // Column Resizing // ---------------------------------------------------------------------------- _handleResizeStart(e, columnId) { e.preventDefault(); const headerCell = this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${columnId}\"]`); this._resizing = { columnId, startX: e.clientX, startWidth: headerCell?.offsetWidth || 200 }; document.addEventListener('mousemove', this._handleResizeMove); document.addEventListener('mouseup', this._handleResizeEnd); } // ---------------------------------------------------------------------------- // Header // ---------------------------------------------------------------------------- _handleAction(action) { if (action.href) { return; } this.dispatchEvent(new CustomEvent('action', { detail: { action: action.id }, bubbles: true, composed: true })); } // ---------------------------------------------------------------------------- // Rendering // ---------------------------------------------------------------------------- _renderCellContent(column, row, rowIndex) { const value = row[column.id]; if (column.render) { // Use slot to project content from light DOM so external styles apply return html `<slot name=\"cell-${rowIndex}-${column.id}\"></slot>`; } if (value === null || value === undefined) { return ''; } switch (column.type) { case 'number': return typeof value === 'number' ? value.toLocaleString() : String(value); case 'currency': return typeof value === 'number' ? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }) : String(value); case 'date': { let date; if (value instanceof Date) { date = value; } else if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(value)) { // MySQL datetime format (UTC): \"2026-01-28 01:33:44:517\" // Replace last colon before ms with dot, append Z for UTC const isoString = value.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/, '$1.$2').replace(' ', 'T') + 'Z'; date = new Date(isoString); } else { date = new Date(value); } // Show date and time for datetime values return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); } case 'boolean': if (value === true) return 'Yes'; if (value === false) return 'No'; return ''; default: return String(value); } } /** * Returns CSS classes for a header cell based on column config. */ _getHeaderCellClasses(column, index) { return { 'header-cell': true, 'header-cell--align-center': column.align === 'center', 'header-cell--align-right': column.align === 'right', 'header-cell--sticky-left': column.sticky === 'left', 'header-cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'header-cell--sticky-right': column.sticky === 'right', 'header-cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns CSS classes for a table cell based on column config: * - Alignment (center, right) * - Sticky positioning (left, right) * - Border classes for the last left-sticky or first right-sticky column */ _getCellClasses(column, index) { return { 'cell': true, 'cell--actions': column.type === 'actions', 'cell--align-center': column.align === 'center', 'cell--align-right': column.align === 'right', 'cell--sticky-left': column.sticky === 'left', 'cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'cell--sticky-right': column.sticky === 'right', 'cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns inline styles for a table cell: * - Width (from column config or default 150px) * - Min-width (if specified) * - Left/right offset for sticky columns (calculated from widths of preceding sticky columns) */ _getCellStyle(column, index) { const styles = {}; if (column.sticky === 'left') { let leftOffset = 0; for (let i = 0; i < index; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'left') { leftOffset += parseInt(col.width || '0', 10); } } styles.left = `${leftOffset}px`; } if (column.sticky === 'right') { let rightOffset = 0; for (let i = index + 1; i < this.getDisplayedColumns().length; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'right') { rightOffset += parseInt(col.width || '0', 10); } } styles.right = `${rightOffset}px`; } return styles; } /** * Renders the pagination controls: * - Previous page arrow (disabled on first page) * - Range text showing \"1-50 of 150\" format * - Next page arrow (disabled on last page) * * Hidden when there's no data or all data fits on one page. */ _renderPagination() { const start = (this._page - 1) * this._pageSize + 1; const end = Math.min(this._page * this._pageSize, this._totalItems); return html ` <div class=\"pagination\"> <span class=\"pagination-icon ${this._page === 1 ? 'pagination-icon--disabled' : ''}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${start}-${end} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page === this._totalPages ? 'pagination-icon--disabled' : ''}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `; } /** * Renders the header toolbar containing: * - Title (left) * - Search bar with view selector dropdown (center) * - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown * * Hidden when there's no title, no actions, and data fits on one page. */ _renderHeader() { if (!this._def.title && !this._def.actions?.length && this._totalPages <= 1) { return nothing; } return html ` <div class=\"header\"> <div class=\"title\">${this._def.title ?? ''}</div> ${this._def.dataSource?.mode === 'db' && !this._def.columns.some(col => col.searchable) ? html `<div class=\"search\"></div>` : html ` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${() => this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen ? 'open' : ''}\"> ${[...this._def.columns].filter(col => col.type !== 'actions').sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => html ` <div class=\"column-picker-item\" @click=${() => this._toggleColumn(col.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(col.id) ? 'checked' : ''}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${col.label ?? col.id}</span> </div> `)} </div> </div> ${this._def.actions?.length === 1 ? html ` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${() => this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> ` : this._def.actions?.length ? html ` <kr-button class=\"actions\" .options=${this._def.actions.map(a => ({ id: a.id, label: a.label }))} @option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })} > Actions </kr-button> ` : nothing} </div> </div> `; } /** Renders status message (loading, error, empty) */ _renderStatus() { if (this._dataState === 'loading' && this._data.length === 0) { return html `<div class=\"status\">Loading...</div>`; } if (this._dataState === 'error' && this._data.length === 0) { return html `<div class=\"status status--error\">Error loading data</div>`; } if (this._data.length === 0) { return html `<div class=\"status\">No data available</div>`; } return nothing; } /** Renders the scrollable data grid with column headers and rows. */ _renderTable() { return html ` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map((col, i) => html ` <div class=${classMap(this._getHeaderCellClasses(col, i))} style=${styleMap(this._getCellStyle(col, i))} data-column-id=${col.id} >${col.label ?? col.id}${col.resizable !== false ? html `<div class=\"header-cell__resize\" @mousedown=${(e) => this._handleResizeStart(e, col.id)} ></div>` : nothing}</div> `)} </div> ${this._data.map((row, rowIndex) => { const cells = this.getDisplayedColumns().map((col, i) => html ` <div class=${classMap(this._getCellClasses(col, i))} style=${styleMap(this._getCellStyle(col, i))} data-column-id=${col.id} > ${this._renderCellContent(col, row, rowIndex)} </div> `); if (this._def.rowHref) { return html ` <a href=${this._def.rowHref(row)} class=${classMap({ 'row': true, 'row--clickable': true, 'row--link': true })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</a> `; } return html ` <div class=${classMap({ 'row': true, 'row--clickable': !!this._def.rowClickable })} @mousedown=${() => this._handleRowMouseDown()} @click=${() => this._handleRowClick(row, rowIndex)} >${cells}</div> `; })} </div> </div> </div> `; } /** * Renders a data table with: * - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown) * - Scrollable grid with sticky header row and optional sticky left/right columns * - Loading, error message, or empty state when no data */ render() { if (!this._def.columns.length) { return html `<slot></slot>`; } return html ` ${this._renderHeader()} ${this._renderTable()} `; } }"
1737
1737
  }
1738
1738
  ],
1739
1739
  "exports": [
@@ -5840,18 +5840,12 @@
5840
5840
  },
5841
5841
  {
5842
5842
  "kind": "javascript-module",
5843
- "path": "src/form/select-field/select-field.ts",
5843
+ "path": "src/form/text-field/text-field.ts",
5844
5844
  "declarations": [
5845
5845
  {
5846
5846
  "kind": "class",
5847
- "description": "A select dropdown component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset.",
5848
- "name": "KRSelectField",
5849
- "slots": [
5850
- {
5851
- "description": "The kr-select-option elements",
5852
- "name": ""
5853
- }
5854
- ],
5847
+ "description": "A text field component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset.\n\nNative input and change events bubble up from the inner input element.",
5848
+ "name": "KRTextField",
5855
5849
  "members": [
5856
5850
  {
5857
5851
  "kind": "field",
@@ -5877,7 +5871,7 @@
5877
5871
  "text": "string"
5878
5872
  },
5879
5873
  "default": "''",
5880
- "description": "The select label text",
5874
+ "description": "The input label text",
5881
5875
  "attribute": "label"
5882
5876
  },
5883
5877
  {
@@ -5897,7 +5891,7 @@
5897
5891
  "text": "string"
5898
5892
  },
5899
5893
  "default": "''",
5900
- "description": "The currently selected value",
5894
+ "description": "The current value",
5901
5895
  "attribute": "value"
5902
5896
  },
5903
5897
  {
@@ -5906,19 +5900,19 @@
5906
5900
  "type": {
5907
5901
  "text": "string"
5908
5902
  },
5909
- "default": "'Select an option'",
5910
- "description": "Placeholder text when no option is selected",
5903
+ "default": "''",
5904
+ "description": "Placeholder text",
5911
5905
  "attribute": "placeholder"
5912
5906
  },
5913
5907
  {
5914
5908
  "kind": "field",
5915
- "name": "disabled",
5909
+ "name": "type",
5916
5910
  "type": {
5917
- "text": "boolean"
5911
+ "text": "'text' | 'email' | 'password' | 'tel' | 'url' | 'search'"
5918
5912
  },
5919
- "default": "false",
5920
- "description": "Whether the select is disabled",
5921
- "attribute": "disabled"
5913
+ "default": "'text'",
5914
+ "description": "Input type (text, email, password, tel, url, search)",
5915
+ "attribute": "type"
5922
5916
  },
5923
5917
  {
5924
5918
  "kind": "field",
@@ -5930,6 +5924,16 @@
5930
5924
  "description": "Whether the field is required",
5931
5925
  "attribute": "required"
5932
5926
  },
5927
+ {
5928
+ "kind": "field",
5929
+ "name": "disabled",
5930
+ "type": {
5931
+ "text": "boolean"
5932
+ },
5933
+ "default": "false",
5934
+ "description": "Whether the field is disabled",
5935
+ "attribute": "disabled"
5936
+ },
5933
5937
  {
5934
5938
  "kind": "field",
5935
5939
  "name": "readonly",
@@ -5942,31 +5946,58 @@
5942
5946
  },
5943
5947
  {
5944
5948
  "kind": "field",
5945
- "name": "hint",
5949
+ "name": "minlength",
5950
+ "type": {
5951
+ "text": "number | undefined"
5952
+ },
5953
+ "description": "Minimum length for the value",
5954
+ "attribute": "minlength"
5955
+ },
5956
+ {
5957
+ "kind": "field",
5958
+ "name": "maxlength",
5959
+ "type": {
5960
+ "text": "number | undefined"
5961
+ },
5962
+ "description": "Maximum length for the value",
5963
+ "attribute": "maxlength"
5964
+ },
5965
+ {
5966
+ "kind": "field",
5967
+ "name": "pattern",
5968
+ "type": {
5969
+ "text": "string | undefined"
5970
+ },
5971
+ "description": "Pattern for validation (regex)",
5972
+ "attribute": "pattern"
5973
+ },
5974
+ {
5975
+ "kind": "field",
5976
+ "name": "autocomplete",
5946
5977
  "type": {
5947
5978
  "text": "string"
5948
5979
  },
5949
5980
  "default": "''",
5950
- "description": "Helper text shown below the select",
5951
- "attribute": "hint"
5981
+ "description": "Autocomplete attribute value",
5982
+ "attribute": "autocomplete"
5952
5983
  },
5953
5984
  {
5954
5985
  "kind": "field",
5955
- "name": "_isOpen",
5986
+ "name": "hint",
5956
5987
  "type": {
5957
- "text": "boolean"
5988
+ "text": "string"
5958
5989
  },
5959
- "privacy": "private",
5960
- "default": "false"
5990
+ "default": "''",
5991
+ "description": "Helper text shown below the input",
5992
+ "attribute": "hint"
5961
5993
  },
5962
5994
  {
5963
5995
  "kind": "field",
5964
- "name": "_highlightedIndex",
5996
+ "name": "_input",
5965
5997
  "type": {
5966
- "text": "number"
5998
+ "text": "HTMLInputElement"
5967
5999
  },
5968
- "privacy": "private",
5969
- "default": "-1"
6000
+ "privacy": "private"
5970
6001
  },
5971
6002
  {
5972
6003
  "kind": "field",
@@ -5979,11 +6010,12 @@
5979
6010
  },
5980
6011
  {
5981
6012
  "kind": "field",
5982
- "name": "_triggerElement",
6013
+ "name": "_dirty",
5983
6014
  "type": {
5984
- "text": "HTMLButtonElement"
6015
+ "text": "boolean"
5985
6016
  },
5986
- "privacy": "private"
6017
+ "privacy": "private",
6018
+ "default": "false"
5987
6019
  },
5988
6020
  {
5989
6021
  "kind": "field",
@@ -6034,35 +6066,33 @@
6034
6066
  "name": "_handleInvalid",
6035
6067
  "privacy": "private"
6036
6068
  },
6037
- {
6038
- "kind": "field",
6039
- "name": "_handleOutsideClick",
6040
- "privacy": "private"
6041
- },
6042
- {
6043
- "kind": "field",
6044
- "name": "_handleKeyDown",
6045
- "privacy": "private"
6046
- },
6047
6069
  {
6048
6070
  "kind": "method",
6049
- "name": "_toggle",
6071
+ "name": "_updateValidity",
6050
6072
  "privacy": "private"
6051
6073
  },
6052
6074
  {
6053
6075
  "kind": "method",
6054
- "name": "_close",
6055
- "privacy": "private"
6076
+ "name": "_handleInput",
6077
+ "privacy": "private",
6078
+ "parameters": [
6079
+ {
6080
+ "name": "e",
6081
+ "type": {
6082
+ "text": "Event"
6083
+ }
6084
+ }
6085
+ ]
6056
6086
  },
6057
6087
  {
6058
6088
  "kind": "method",
6059
- "name": "_selectOption",
6089
+ "name": "_handleChange",
6060
6090
  "privacy": "private",
6061
6091
  "parameters": [
6062
6092
  {
6063
- "name": "option",
6093
+ "name": "e",
6064
6094
  "type": {
6065
- "text": "KRSelectOption"
6095
+ "text": "Event"
6066
6096
  }
6067
6097
  }
6068
6098
  ]
@@ -6072,11 +6102,6 @@
6072
6102
  "name": "_handleBlur",
6073
6103
  "privacy": "private"
6074
6104
  },
6075
- {
6076
- "kind": "method",
6077
- "name": "_updateValidity",
6078
- "privacy": "private"
6079
- },
6080
6105
  {
6081
6106
  "kind": "method",
6082
6107
  "name": "focus"
@@ -6084,14 +6109,10 @@
6084
6109
  {
6085
6110
  "kind": "method",
6086
6111
  "name": "blur"
6087
- }
6088
- ],
6089
- "events": [
6112
+ },
6090
6113
  {
6091
- "name": "change",
6092
- "type": {
6093
- "text": "Event"
6094
- }
6114
+ "kind": "method",
6115
+ "name": "select"
6095
6116
  }
6096
6117
  ],
6097
6118
  "attributes": [
@@ -6101,7 +6122,7 @@
6101
6122
  "text": "string"
6102
6123
  },
6103
6124
  "default": "''",
6104
- "description": "The select label text",
6125
+ "description": "The input label text",
6105
6126
  "fieldName": "label"
6106
6127
  },
6107
6128
  {
@@ -6119,7 +6140,7 @@
6119
6140
  "text": "string"
6120
6141
  },
6121
6142
  "default": "''",
6122
- "description": "The currently selected value",
6143
+ "description": "The current value",
6123
6144
  "fieldName": "value"
6124
6145
  },
6125
6146
  {
@@ -6127,18 +6148,18 @@
6127
6148
  "type": {
6128
6149
  "text": "string"
6129
6150
  },
6130
- "default": "'Select an option'",
6131
- "description": "Placeholder text when no option is selected",
6151
+ "default": "''",
6152
+ "description": "Placeholder text",
6132
6153
  "fieldName": "placeholder"
6133
6154
  },
6134
6155
  {
6135
- "name": "disabled",
6156
+ "name": "type",
6136
6157
  "type": {
6137
- "text": "boolean"
6158
+ "text": "'text' | 'email' | 'password' | 'tel' | 'url' | 'search'"
6138
6159
  },
6139
- "default": "false",
6140
- "description": "Whether the select is disabled",
6141
- "fieldName": "disabled"
6160
+ "default": "'text'",
6161
+ "description": "Input type (text, email, password, tel, url, search)",
6162
+ "fieldName": "type"
6142
6163
  },
6143
6164
  {
6144
6165
  "name": "required",
@@ -6149,6 +6170,15 @@
6149
6170
  "description": "Whether the field is required",
6150
6171
  "fieldName": "required"
6151
6172
  },
6173
+ {
6174
+ "name": "disabled",
6175
+ "type": {
6176
+ "text": "boolean"
6177
+ },
6178
+ "default": "false",
6179
+ "description": "Whether the field is disabled",
6180
+ "fieldName": "disabled"
6181
+ },
6152
6182
  {
6153
6183
  "name": "readonly",
6154
6184
  "type": {
@@ -6158,13 +6188,46 @@
6158
6188
  "description": "Whether the field is readonly",
6159
6189
  "fieldName": "readonly"
6160
6190
  },
6191
+ {
6192
+ "name": "minlength",
6193
+ "type": {
6194
+ "text": "number | undefined"
6195
+ },
6196
+ "description": "Minimum length for the value",
6197
+ "fieldName": "minlength"
6198
+ },
6199
+ {
6200
+ "name": "maxlength",
6201
+ "type": {
6202
+ "text": "number | undefined"
6203
+ },
6204
+ "description": "Maximum length for the value",
6205
+ "fieldName": "maxlength"
6206
+ },
6207
+ {
6208
+ "name": "pattern",
6209
+ "type": {
6210
+ "text": "string | undefined"
6211
+ },
6212
+ "description": "Pattern for validation (regex)",
6213
+ "fieldName": "pattern"
6214
+ },
6215
+ {
6216
+ "name": "autocomplete",
6217
+ "type": {
6218
+ "text": "string"
6219
+ },
6220
+ "default": "''",
6221
+ "description": "Autocomplete attribute value",
6222
+ "fieldName": "autocomplete"
6223
+ },
6161
6224
  {
6162
6225
  "name": "hint",
6163
6226
  "type": {
6164
6227
  "text": "string"
6165
6228
  },
6166
6229
  "default": "''",
6167
- "description": "Helper text shown below the select",
6230
+ "description": "Helper text shown below the input",
6168
6231
  "fieldName": "hint"
6169
6232
  }
6170
6233
  ],
@@ -6172,129 +6235,43 @@
6172
6235
  "name": "LitElement",
6173
6236
  "package": "lit"
6174
6237
  },
6175
- "tagName": "kr-select-field",
6238
+ "tagName": "kr-text-field",
6176
6239
  "customElement": true
6177
6240
  }
6178
6241
  ],
6179
6242
  "exports": [
6180
6243
  {
6181
6244
  "kind": "js",
6182
- "name": "KRSelectField",
6245
+ "name": "KRTextField",
6183
6246
  "declaration": {
6184
- "name": "KRSelectField",
6185
- "module": "src/form/select-field/select-field.ts"
6247
+ "name": "KRTextField",
6248
+ "module": "src/form/text-field/text-field.ts"
6186
6249
  }
6187
6250
  },
6188
6251
  {
6189
6252
  "kind": "custom-element-definition",
6190
- "name": "kr-select-field",
6253
+ "name": "kr-text-field",
6191
6254
  "declaration": {
6192
- "name": "KRSelectField",
6193
- "module": "src/form/select-field/select-field.ts"
6255
+ "name": "KRTextField",
6256
+ "module": "src/form/text-field/text-field.ts"
6194
6257
  }
6195
6258
  }
6196
6259
  ]
6197
6260
  },
6198
6261
  {
6199
6262
  "kind": "javascript-module",
6200
- "path": "src/form/select-field/select-option.ts",
6263
+ "path": "src/form/select-field/select-field.ts",
6201
6264
  "declarations": [
6202
6265
  {
6203
6266
  "kind": "class",
6204
- "description": "An option for the kr-select-field component.",
6205
- "name": "KRSelectOption",
6267
+ "description": "A select dropdown component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset.",
6268
+ "name": "KRSelectField",
6206
6269
  "slots": [
6207
6270
  {
6208
- "description": "The option label content",
6271
+ "description": "The kr-select-option elements",
6209
6272
  "name": ""
6210
6273
  }
6211
6274
  ],
6212
- "members": [
6213
- {
6214
- "kind": "field",
6215
- "name": "value",
6216
- "type": {
6217
- "text": "string"
6218
- },
6219
- "default": "''",
6220
- "description": "The option value",
6221
- "attribute": "value"
6222
- },
6223
- {
6224
- "kind": "field",
6225
- "name": "disabled",
6226
- "type": {
6227
- "text": "boolean"
6228
- },
6229
- "default": "false",
6230
- "description": "Whether the option is disabled",
6231
- "attribute": "disabled"
6232
- },
6233
- {
6234
- "kind": "field",
6235
- "name": "label",
6236
- "type": {
6237
- "text": "string"
6238
- },
6239
- "description": "Gets the label text from the slot",
6240
- "readonly": true
6241
- }
6242
- ],
6243
- "attributes": [
6244
- {
6245
- "name": "value",
6246
- "type": {
6247
- "text": "string"
6248
- },
6249
- "default": "''",
6250
- "description": "The option value",
6251
- "fieldName": "value"
6252
- },
6253
- {
6254
- "name": "disabled",
6255
- "type": {
6256
- "text": "boolean"
6257
- },
6258
- "default": "false",
6259
- "description": "Whether the option is disabled",
6260
- "fieldName": "disabled"
6261
- }
6262
- ],
6263
- "superclass": {
6264
- "name": "LitElement",
6265
- "package": "lit"
6266
- },
6267
- "tagName": "kr-select-option",
6268
- "customElement": true
6269
- }
6270
- ],
6271
- "exports": [
6272
- {
6273
- "kind": "js",
6274
- "name": "KRSelectOption",
6275
- "declaration": {
6276
- "name": "KRSelectOption",
6277
- "module": "src/form/select-field/select-option.ts"
6278
- }
6279
- },
6280
- {
6281
- "kind": "custom-element-definition",
6282
- "name": "kr-select-option",
6283
- "declaration": {
6284
- "name": "KRSelectOption",
6285
- "module": "src/form/select-field/select-option.ts"
6286
- }
6287
- }
6288
- ]
6289
- },
6290
- {
6291
- "kind": "javascript-module",
6292
- "path": "src/form/text-field/text-field.ts",
6293
- "declarations": [
6294
- {
6295
- "kind": "class",
6296
- "description": "A text field component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset.\n\nNative input and change events bubble up from the inner input element.",
6297
- "name": "KRTextField",
6298
6275
  "members": [
6299
6276
  {
6300
6277
  "kind": "field",
@@ -6320,7 +6297,7 @@
6320
6297
  "text": "string"
6321
6298
  },
6322
6299
  "default": "''",
6323
- "description": "The input label text",
6300
+ "description": "The select label text",
6324
6301
  "attribute": "label"
6325
6302
  },
6326
6303
  {
@@ -6340,7 +6317,7 @@
6340
6317
  "text": "string"
6341
6318
  },
6342
6319
  "default": "''",
6343
- "description": "The current value",
6320
+ "description": "The currently selected value",
6344
6321
  "attribute": "value"
6345
6322
  },
6346
6323
  {
@@ -6349,19 +6326,19 @@
6349
6326
  "type": {
6350
6327
  "text": "string"
6351
6328
  },
6352
- "default": "''",
6353
- "description": "Placeholder text",
6329
+ "default": "'Select an option'",
6330
+ "description": "Placeholder text when no option is selected",
6354
6331
  "attribute": "placeholder"
6355
6332
  },
6356
6333
  {
6357
6334
  "kind": "field",
6358
- "name": "type",
6335
+ "name": "disabled",
6359
6336
  "type": {
6360
- "text": "'text' | 'email' | 'password' | 'tel' | 'url' | 'search'"
6337
+ "text": "boolean"
6361
6338
  },
6362
- "default": "'text'",
6363
- "description": "Input type (text, email, password, tel, url, search)",
6364
- "attribute": "type"
6339
+ "default": "false",
6340
+ "description": "Whether the select is disabled",
6341
+ "attribute": "disabled"
6365
6342
  },
6366
6343
  {
6367
6344
  "kind": "field",
@@ -6373,16 +6350,6 @@
6373
6350
  "description": "Whether the field is required",
6374
6351
  "attribute": "required"
6375
6352
  },
6376
- {
6377
- "kind": "field",
6378
- "name": "disabled",
6379
- "type": {
6380
- "text": "boolean"
6381
- },
6382
- "default": "false",
6383
- "description": "Whether the field is disabled",
6384
- "attribute": "disabled"
6385
- },
6386
6353
  {
6387
6354
  "kind": "field",
6388
6355
  "name": "readonly",
@@ -6395,58 +6362,31 @@
6395
6362
  },
6396
6363
  {
6397
6364
  "kind": "field",
6398
- "name": "minlength",
6399
- "type": {
6400
- "text": "number | undefined"
6401
- },
6402
- "description": "Minimum length for the value",
6403
- "attribute": "minlength"
6404
- },
6405
- {
6406
- "kind": "field",
6407
- "name": "maxlength",
6408
- "type": {
6409
- "text": "number | undefined"
6410
- },
6411
- "description": "Maximum length for the value",
6412
- "attribute": "maxlength"
6413
- },
6414
- {
6415
- "kind": "field",
6416
- "name": "pattern",
6417
- "type": {
6418
- "text": "string | undefined"
6419
- },
6420
- "description": "Pattern for validation (regex)",
6421
- "attribute": "pattern"
6422
- },
6423
- {
6424
- "kind": "field",
6425
- "name": "autocomplete",
6365
+ "name": "hint",
6426
6366
  "type": {
6427
6367
  "text": "string"
6428
6368
  },
6429
6369
  "default": "''",
6430
- "description": "Autocomplete attribute value",
6431
- "attribute": "autocomplete"
6370
+ "description": "Helper text shown below the select",
6371
+ "attribute": "hint"
6432
6372
  },
6433
6373
  {
6434
6374
  "kind": "field",
6435
- "name": "hint",
6375
+ "name": "_isOpen",
6436
6376
  "type": {
6437
- "text": "string"
6377
+ "text": "boolean"
6438
6378
  },
6439
- "default": "''",
6440
- "description": "Helper text shown below the input",
6441
- "attribute": "hint"
6379
+ "privacy": "private",
6380
+ "default": "false"
6442
6381
  },
6443
6382
  {
6444
6383
  "kind": "field",
6445
- "name": "_input",
6384
+ "name": "_highlightedIndex",
6446
6385
  "type": {
6447
- "text": "HTMLInputElement"
6386
+ "text": "number"
6448
6387
  },
6449
- "privacy": "private"
6388
+ "privacy": "private",
6389
+ "default": "-1"
6450
6390
  },
6451
6391
  {
6452
6392
  "kind": "field",
@@ -6459,12 +6399,11 @@
6459
6399
  },
6460
6400
  {
6461
6401
  "kind": "field",
6462
- "name": "_dirty",
6402
+ "name": "_triggerElement",
6463
6403
  "type": {
6464
- "text": "boolean"
6404
+ "text": "HTMLButtonElement"
6465
6405
  },
6466
- "privacy": "private",
6467
- "default": "false"
6406
+ "privacy": "private"
6468
6407
  },
6469
6408
  {
6470
6409
  "kind": "field",
@@ -6515,33 +6454,35 @@
6515
6454
  "name": "_handleInvalid",
6516
6455
  "privacy": "private"
6517
6456
  },
6457
+ {
6458
+ "kind": "field",
6459
+ "name": "_handleOutsideClick",
6460
+ "privacy": "private"
6461
+ },
6462
+ {
6463
+ "kind": "field",
6464
+ "name": "_handleKeyDown",
6465
+ "privacy": "private"
6466
+ },
6518
6467
  {
6519
6468
  "kind": "method",
6520
- "name": "_updateValidity",
6469
+ "name": "_toggle",
6521
6470
  "privacy": "private"
6522
6471
  },
6523
6472
  {
6524
6473
  "kind": "method",
6525
- "name": "_handleInput",
6526
- "privacy": "private",
6527
- "parameters": [
6528
- {
6529
- "name": "e",
6530
- "type": {
6531
- "text": "Event"
6532
- }
6533
- }
6534
- ]
6474
+ "name": "_close",
6475
+ "privacy": "private"
6535
6476
  },
6536
6477
  {
6537
6478
  "kind": "method",
6538
- "name": "_handleChange",
6479
+ "name": "_selectOption",
6539
6480
  "privacy": "private",
6540
6481
  "parameters": [
6541
6482
  {
6542
- "name": "e",
6483
+ "name": "option",
6543
6484
  "type": {
6544
- "text": "Event"
6485
+ "text": "KRSelectOption"
6545
6486
  }
6546
6487
  }
6547
6488
  ]
@@ -6553,15 +6494,24 @@
6553
6494
  },
6554
6495
  {
6555
6496
  "kind": "method",
6556
- "name": "focus"
6497
+ "name": "_updateValidity",
6498
+ "privacy": "private"
6557
6499
  },
6558
6500
  {
6559
6501
  "kind": "method",
6560
- "name": "blur"
6502
+ "name": "focus"
6561
6503
  },
6562
6504
  {
6563
6505
  "kind": "method",
6564
- "name": "select"
6506
+ "name": "blur"
6507
+ }
6508
+ ],
6509
+ "events": [
6510
+ {
6511
+ "name": "change",
6512
+ "type": {
6513
+ "text": "Event"
6514
+ }
6565
6515
  }
6566
6516
  ],
6567
6517
  "attributes": [
@@ -6571,7 +6521,7 @@
6571
6521
  "text": "string"
6572
6522
  },
6573
6523
  "default": "''",
6574
- "description": "The input label text",
6524
+ "description": "The select label text",
6575
6525
  "fieldName": "label"
6576
6526
  },
6577
6527
  {
@@ -6589,7 +6539,7 @@
6589
6539
  "text": "string"
6590
6540
  },
6591
6541
  "default": "''",
6592
- "description": "The current value",
6542
+ "description": "The currently selected value",
6593
6543
  "fieldName": "value"
6594
6544
  },
6595
6545
  {
@@ -6597,18 +6547,18 @@
6597
6547
  "type": {
6598
6548
  "text": "string"
6599
6549
  },
6600
- "default": "''",
6601
- "description": "Placeholder text",
6550
+ "default": "'Select an option'",
6551
+ "description": "Placeholder text when no option is selected",
6602
6552
  "fieldName": "placeholder"
6603
6553
  },
6604
6554
  {
6605
- "name": "type",
6555
+ "name": "disabled",
6606
6556
  "type": {
6607
- "text": "'text' | 'email' | 'password' | 'tel' | 'url' | 'search'"
6557
+ "text": "boolean"
6608
6558
  },
6609
- "default": "'text'",
6610
- "description": "Input type (text, email, password, tel, url, search)",
6611
- "fieldName": "type"
6559
+ "default": "false",
6560
+ "description": "Whether the select is disabled",
6561
+ "fieldName": "disabled"
6612
6562
  },
6613
6563
  {
6614
6564
  "name": "required",
@@ -6619,15 +6569,6 @@
6619
6569
  "description": "Whether the field is required",
6620
6570
  "fieldName": "required"
6621
6571
  },
6622
- {
6623
- "name": "disabled",
6624
- "type": {
6625
- "text": "boolean"
6626
- },
6627
- "default": "false",
6628
- "description": "Whether the field is disabled",
6629
- "fieldName": "disabled"
6630
- },
6631
6572
  {
6632
6573
  "name": "readonly",
6633
6574
  "type": {
@@ -6638,71 +6579,130 @@
6638
6579
  "fieldName": "readonly"
6639
6580
  },
6640
6581
  {
6641
- "name": "minlength",
6582
+ "name": "hint",
6642
6583
  "type": {
6643
- "text": "number | undefined"
6584
+ "text": "string"
6644
6585
  },
6645
- "description": "Minimum length for the value",
6646
- "fieldName": "minlength"
6647
- },
6586
+ "default": "''",
6587
+ "description": "Helper text shown below the select",
6588
+ "fieldName": "hint"
6589
+ }
6590
+ ],
6591
+ "superclass": {
6592
+ "name": "LitElement",
6593
+ "package": "lit"
6594
+ },
6595
+ "tagName": "kr-select-field",
6596
+ "customElement": true
6597
+ }
6598
+ ],
6599
+ "exports": [
6600
+ {
6601
+ "kind": "js",
6602
+ "name": "KRSelectField",
6603
+ "declaration": {
6604
+ "name": "KRSelectField",
6605
+ "module": "src/form/select-field/select-field.ts"
6606
+ }
6607
+ },
6608
+ {
6609
+ "kind": "custom-element-definition",
6610
+ "name": "kr-select-field",
6611
+ "declaration": {
6612
+ "name": "KRSelectField",
6613
+ "module": "src/form/select-field/select-field.ts"
6614
+ }
6615
+ }
6616
+ ]
6617
+ },
6618
+ {
6619
+ "kind": "javascript-module",
6620
+ "path": "src/form/select-field/select-option.ts",
6621
+ "declarations": [
6622
+ {
6623
+ "kind": "class",
6624
+ "description": "An option for the kr-select-field component.",
6625
+ "name": "KRSelectOption",
6626
+ "slots": [
6648
6627
  {
6649
- "name": "maxlength",
6628
+ "description": "The option label content",
6629
+ "name": ""
6630
+ }
6631
+ ],
6632
+ "members": [
6633
+ {
6634
+ "kind": "field",
6635
+ "name": "value",
6650
6636
  "type": {
6651
- "text": "number | undefined"
6637
+ "text": "string"
6652
6638
  },
6653
- "description": "Maximum length for the value",
6654
- "fieldName": "maxlength"
6639
+ "default": "''",
6640
+ "description": "The option value",
6641
+ "attribute": "value"
6655
6642
  },
6656
6643
  {
6657
- "name": "pattern",
6644
+ "kind": "field",
6645
+ "name": "disabled",
6658
6646
  "type": {
6659
- "text": "string | undefined"
6647
+ "text": "boolean"
6660
6648
  },
6661
- "description": "Pattern for validation (regex)",
6662
- "fieldName": "pattern"
6649
+ "default": "false",
6650
+ "description": "Whether the option is disabled",
6651
+ "attribute": "disabled"
6663
6652
  },
6664
6653
  {
6665
- "name": "autocomplete",
6654
+ "kind": "field",
6655
+ "name": "label",
6666
6656
  "type": {
6667
6657
  "text": "string"
6668
6658
  },
6669
- "default": "''",
6670
- "description": "Autocomplete attribute value",
6671
- "fieldName": "autocomplete"
6672
- },
6659
+ "description": "Gets the label text from the slot",
6660
+ "readonly": true
6661
+ }
6662
+ ],
6663
+ "attributes": [
6673
6664
  {
6674
- "name": "hint",
6665
+ "name": "value",
6675
6666
  "type": {
6676
6667
  "text": "string"
6677
6668
  },
6678
6669
  "default": "''",
6679
- "description": "Helper text shown below the input",
6680
- "fieldName": "hint"
6670
+ "description": "The option value",
6671
+ "fieldName": "value"
6672
+ },
6673
+ {
6674
+ "name": "disabled",
6675
+ "type": {
6676
+ "text": "boolean"
6677
+ },
6678
+ "default": "false",
6679
+ "description": "Whether the option is disabled",
6680
+ "fieldName": "disabled"
6681
6681
  }
6682
6682
  ],
6683
6683
  "superclass": {
6684
6684
  "name": "LitElement",
6685
6685
  "package": "lit"
6686
6686
  },
6687
- "tagName": "kr-text-field",
6687
+ "tagName": "kr-select-option",
6688
6688
  "customElement": true
6689
6689
  }
6690
6690
  ],
6691
6691
  "exports": [
6692
6692
  {
6693
6693
  "kind": "js",
6694
- "name": "KRTextField",
6694
+ "name": "KRSelectOption",
6695
6695
  "declaration": {
6696
- "name": "KRTextField",
6697
- "module": "src/form/text-field/text-field.ts"
6696
+ "name": "KRSelectOption",
6697
+ "module": "src/form/select-field/select-option.ts"
6698
6698
  }
6699
6699
  },
6700
6700
  {
6701
6701
  "kind": "custom-element-definition",
6702
- "name": "kr-text-field",
6702
+ "name": "kr-select-option",
6703
6703
  "declaration": {
6704
- "name": "KRTextField",
6705
- "module": "src/form/text-field/text-field.ts"
6704
+ "name": "KRSelectOption",
6705
+ "module": "src/form/select-field/select-option.ts"
6706
6706
  }
6707
6707
  }
6708
6708
  ]