@wavelengthusaf/web-components 1.10.0 → 1.13.0

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.
@@ -3183,7 +3183,7 @@ if (!customElements.get("wavelength-progress-bar")) {
3183
3183
  }
3184
3184
 
3185
3185
  // src/web-components/wavelength-input.template.html
3186
- var wavelength_input_template_default = '<style>\n :host {\n display: block;\n width: 100%;\n font-family: sans-serif;\n --wavelength-container-background: #f8f8f8;\n --wavelength-label-background: #ffffff;\n }\n\n .field-wrapper {\n position: relative;\n }\n\n .floating-label {\n position: absolute;\n top: -0.325rem;\n left: 12px;\n font-size: 0.75rem;\n line-height: 1;\n color: var(--wavelength-label-color, #666666);\n padding: 0 4px;\n z-index: 1;\n pointer-events: none;\n user-select: none;\n }\n\n .floating-label::before,\n .floating-label::after {\n content: "";\n position: absolute;\n left: 0;\n width: 100%;\n z-index: -1;\n }\n\n .floating-label::before {\n top: 0;\n height: 50%;\n background: var(--wavelength-container-background, white);\n }\n\n .floating-label::after {\n bottom: 0;\n height: 50%;\n background: var(--wavelength-label-background, #ffffff);\n }\n\n :host([disabled]) .floating-label::before {\n opacity: 0;\n }\n\n input {\n font-size: 16px;\n padding: 16.5px 14px;\n border: 1px solid var(--wavelength-border-color, #cccccc);\n border-radius: 8px;\n width: 100%;\n box-sizing: border-box;\n background-color: var(--wavelength-background, #ffffff);\n transition: border-color 0.2s ease;\n overflow: auto;\n font-family: inherit;\n }\n\n input:focus {\n outline: none;\n }\n\n input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n :host([disabled]) .floating-label::after {\n opacity: 0;\n cursor: not-allowed;\n }\n\n input::placeholder {\n color: #999999;\n }\n\n .helper-message {\n margin-top: 4px;\n font-size: 0.75rem;\n max-width: 100%;\n word-wrap: break-word;\n white-space: normal;\n overflow-wrap: break-word;\n color: #000000;\n padding-left: 14px;\n margin-left: 2px;\n user-select: none;\n }\n\n .required-marker {\n color: red;\n font-weight: lighter;\n font-size: 0.75rem;\n }\n\n .clear-button {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1.25 rem;\n color: #666666;\n cursor: pointer;\n opacity: 0.5;\n user-select: none;\n transition: opacity 0.2s ease;\n z-index: 2;\n display: none;\n line-height: 1;\n padding: 0 4px;\n }\n\n .clear-button:hover {\n opacity: 1;\n }\n\n :host([disabled]) .clear-button {\n display: none;\n }\n</style>\n<div class="field-wrapper">\n <label class="floating-label" id="floating-label"></label>\n <div class="input-wrapper"></div>\n <div class="clear-button" id="clear-button" title="Clear input">\u2715</div>\n</div>\n<div class="helper-message" id="helper"></div>\n';
3186
+ var wavelength_input_template_default = '<style>\n :host {\n display: block;\n width: 100%;\n font-family: sans-serif;\n --wavelength-container-background: #f8f8f8;\n --wavelength-label-background: #ffffff;\n }\n\n .field-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .input-wrapper {\n width: 100%;\n height: 100%;\n }\n\n .floating-label {\n position: absolute;\n top: -0.325rem;\n left: 12px;\n font-size: 0.75rem;\n line-height: 1;\n color: var(--wavelength-label-color, #666666);\n padding: 0 4px;\n z-index: 1;\n pointer-events: none;\n user-select: none;\n }\n\n .floating-label::before,\n .floating-label::after {\n content: "";\n position: absolute;\n left: 0;\n width: 100%;\n z-index: -1;\n }\n\n .floating-label::before {\n top: 0;\n height: 50%;\n background: var(--wavelength-container-background, white);\n }\n\n .floating-label::after {\n bottom: 0;\n height: 50%;\n background: var(--wavelength-label-background, #ffffff);\n }\n\n :host([disabled]) .floating-label::before {\n opacity: 0;\n }\n\n input {\n font-size: 16px;\n padding: 16.5px 14px;\n border: 1px solid var(--wavelength-border-color, #cccccc);\n border-radius: 8px;\n width: 100%;\n box-sizing: border-box;\n background-color: var(--wavelength-background, #ffffff);\n transition: border-color 0.2s ease;\n overflow: auto;\n font-family: inherit;\n }\n\n input:focus {\n outline: none;\n }\n\n input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n :host([disabled]) .floating-label::after {\n opacity: 0;\n cursor: not-allowed;\n }\n\n input::placeholder {\n color: #999999;\n }\n\n .helper-message {\n margin-top: 4px;\n font-size: 0.75rem;\n max-width: 100%;\n word-wrap: break-word;\n white-space: normal;\n overflow-wrap: break-word;\n color: #000000;\n padding-left: 14px;\n margin-left: 2px;\n user-select: none;\n }\n\n .required-marker {\n color: red;\n font-weight: lighter;\n font-size: 0.75rem;\n }\n\n .clear-button {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1.25 rem;\n color: #666666;\n cursor: pointer;\n opacity: 0.5;\n user-select: none;\n transition: opacity 0.2s ease;\n z-index: 2;\n display: none;\n line-height: 1;\n padding: 0 4px;\n }\n\n .clear-button:hover {\n opacity: 1;\n }\n\n :host([disabled]) .clear-button {\n display: none;\n }\n</style>\n<div class="field-wrapper">\n <label class="floating-label" id="floating-label"></label>\n <div class="input-wrapper"></div>\n <div class="clear-button" id="clear-button" title="Clear input">\u2715</div>\n</div>\n<div class="helper-message" id="helper"></div>\n';
3187
3187
 
3188
3188
  // src/web-components/wavelength-input.ts
3189
3189
  function getAncestor(el) {
@@ -3302,7 +3302,9 @@ var BaseWavelengthInput = class extends HTMLElement {
3302
3302
  "max-length",
3303
3303
  "required",
3304
3304
  "force-error",
3305
- "label"
3305
+ "label",
3306
+ "font-size",
3307
+ "font-family"
3306
3308
  ];
3307
3309
  }
3308
3310
  connectedCallback() {
@@ -3430,6 +3432,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3430
3432
  }
3431
3433
  this.helperEl.innerHTML = htmlMessage;
3432
3434
  this.helperEl.classList.add("error");
3435
+ this.helperEl.style.display = "block";
3433
3436
  this.inputEl.style.borderColor = "red";
3434
3437
  this.helperEl.style.color = "red";
3435
3438
  this.inputEl.setAttribute("aria-invalid", "true");
@@ -3442,6 +3445,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3442
3445
  this.helperEl.textContent = helperText;
3443
3446
  this.helperEl.classList.remove("error");
3444
3447
  this.helperEl.style.color = helperColor;
3448
+ this.helperEl.style.display = helperText ? "block" : "none";
3445
3449
  this.inputEl.style.borderColor = borderColor;
3446
3450
  this.inputEl.setAttribute("aria-invalid", "false");
3447
3451
  this.removeAttribute("data-error");
@@ -3519,6 +3523,12 @@ var BaseWavelengthInput = class extends HTMLElement {
3519
3523
  this.inputEl.style.padding = rawPadding;
3520
3524
  this.inputEl.style.height = this.getAttribute("height") || "";
3521
3525
  this.inputEl.style.borderRadius = this.getAttribute("border-radius") || "8px";
3526
+ if (this.hasAttribute("font-size")) {
3527
+ this.inputEl.style.fontSize = this.getAttribute("font-size");
3528
+ }
3529
+ if (this.hasAttribute("font-family")) {
3530
+ this.inputEl.style.fontFamily = this.getAttribute("font-family");
3531
+ }
3522
3532
  this.helperEl.style.width = helperWidth;
3523
3533
  this.helperEl.style.paddingLeft = `${leftPaddingPx}px`;
3524
3534
  }
@@ -3564,6 +3574,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3564
3574
  if (!hasError) {
3565
3575
  this.helperEl.textContent = helper;
3566
3576
  this.helperEl.style.color = helperColor;
3577
+ this.helperEl.style.display = helper ? "block" : "none";
3567
3578
  }
3568
3579
  }
3569
3580
  _applyAccessibility() {
@@ -3588,7 +3599,10 @@ var BaseWavelengthInput = class extends HTMLElement {
3588
3599
  this.inputEl.name = newValue || "";
3589
3600
  break;
3590
3601
  case "label":
3602
+ case "font-size":
3603
+ case "font-family":
3591
3604
  this._applyContent();
3605
+ this._applyLayout();
3592
3606
  break;
3593
3607
  case "helper-message":
3594
3608
  this._applyValidationHint();
@@ -6345,6 +6359,432 @@ if (!customElements.get("wavelength-menu")) {
6345
6359
  customElements.define("wavelength-menu", WavelengthMenu);
6346
6360
  }
6347
6361
 
6362
+ // src/web-components/wavelength-pagination.template.html
6363
+ var wavelength_pagination_template_default = '<style>\n :host {\n display: block;\n --local-font: var(--font, "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);\n font-family: var(--local-font);\n }\n\n .pagination-list,\n .pagination-list * {\n font-family: inherit;\n font-size: var(--font-size, 16px);\n color: var(--text-color, black);\n }\n\n .pagination-list {\n display: flex;\n list-style: none;\n padding: var(--padding, 10px);\n margin: 0;\n align-items: center;\n }\n\n .page-item {\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s ease;\n user-select: none;\n background-color: var(--background-color, white);\n }\n\n .page-item.disabled,\n .page-item.disabled * {\n cursor: default;\n background-color: var(--background-color, white);\n color: var(--disabled-color, #ccc);\n border-color: var(--disabled-color, #ccc);\n }\n\n /* --- BASIC VARIANT --- */\n .pagination-list.basic {\n gap: 15px;\n }\n\n .pagination-list.basic .page-info {\n margin-right: 10px;\n font-weight: 500;\n }\n\n .pagination-list.basic .page-item {\n width: 32px;\n height: 32px;\n border: var(--border, none);\n border-radius: var(--border-radius, 50%);\n }\n\n .pagination-list.basic .page-item:not(.disabled):hover {\n filter: brightness(0.95);\n }\n\n /* --- COMMON VARIANT --- */\n .pagination-list.common {\n gap: 8px;\n }\n\n .pagination-list.common .page-item {\n width: 40px;\n height: 40px;\n border: var(--border, none);\n border-radius: var(--border-radius, 50%);\n }\n\n .pagination-list.common .page-item.active,\n .pagination-list.common .page-item.active * {\n background-color: var(--active-color, #49baf7);\n color: var(--active-text-color, #fff);\n border-color: var(--active-color, #49baf7);\n }\n\n .pagination-list.common .page-item:not(.disabled):not(.active):hover {\n filter: brightness(0.95);\n transform: scale(1.1);\n }\n</style>\n<nav aria-label="pagination">\n <ul class="pagination-list"></ul>\n</nav>\n';
6364
+
6365
+ // src/web-components/wavelength-pagination.ts
6366
+ var WavelengthPagination = class extends HTMLElement {
6367
+ constructor() {
6368
+ super();
6369
+ this.styleAttributes = ["variant", "text-color", "font", "font-size", "border", "border-radius", "padding", "active-color", "active-text-color", "background-color", "disabled-color"];
6370
+ this.renderAttributes = ["variant", "total-pages", "current-page"];
6371
+ this.shadow = this.attachShadow({ mode: "open" });
6372
+ this.shadow.innerHTML = wavelength_pagination_template_default;
6373
+ }
6374
+ static get observedAttributes() {
6375
+ return [
6376
+ "variant",
6377
+ "text-color",
6378
+ "font",
6379
+ "font-size",
6380
+ "border",
6381
+ "border-radius",
6382
+ "padding",
6383
+ "total-pages",
6384
+ "current-page",
6385
+ "active-color",
6386
+ "active-text-color",
6387
+ "background-color",
6388
+ "disabled-color"
6389
+ ];
6390
+ }
6391
+ get totalPages() {
6392
+ const parsed = Number.parseInt(this.getAttribute("total-pages") || "1", 10);
6393
+ return isNaN(parsed) ? 1 : parsed;
6394
+ }
6395
+ set totalPages(val) {
6396
+ this.setAttribute("total-pages", val.toString());
6397
+ }
6398
+ get currentPage() {
6399
+ const parsed = Number.parseInt(this.getAttribute("current-page") || "1", 10);
6400
+ return isNaN(parsed) ? 1 : parsed;
6401
+ }
6402
+ set currentPage(val) {
6403
+ this.setAttribute("current-page", val.toString());
6404
+ }
6405
+ connectedCallback() {
6406
+ this._clearAndRender();
6407
+ this._syncStyles();
6408
+ }
6409
+ attributeChangedCallback(name, oldValue, newValue) {
6410
+ if (oldValue === newValue) return;
6411
+ if (this.styleAttributes.includes(name)) {
6412
+ this.style.setProperty(`--${name}`, newValue);
6413
+ }
6414
+ if (this.renderAttributes.includes(name)) {
6415
+ this._clearAndRender();
6416
+ }
6417
+ }
6418
+ _clearAndRender() {
6419
+ const list = this.shadow.querySelector(".pagination-list");
6420
+ if (!list) return;
6421
+ const variant = this.getAttribute("variant") || "basic";
6422
+ list.innerHTML = "";
6423
+ list.className = `pagination-list ${variant}`;
6424
+ this._renderByVariant(list, variant);
6425
+ }
6426
+ _renderByVariant(container, variant) {
6427
+ if (variant === "basic") {
6428
+ this._renderBasic(container);
6429
+ } else {
6430
+ this._renderCommon(container);
6431
+ }
6432
+ }
6433
+ _renderBasic(container) {
6434
+ const { singlePrevSvg, singleNextSvg } = this._getIcons();
6435
+ const textInfo = document.createElement("span");
6436
+ textInfo.className = "page-info";
6437
+ textInfo.textContent = `Page ${this.currentPage} of ${this.totalPages}`;
6438
+ container.appendChild(textInfo);
6439
+ const prevBtn = this._createButton(singlePrevSvg, () => this._changePage(this.currentPage - 1), this.currentPage === 1);
6440
+ const nextBtn = this._createButton(singleNextSvg, () => this._changePage(this.currentPage + 1), this.currentPage === this.totalPages);
6441
+ container.appendChild(prevBtn);
6442
+ container.appendChild(nextBtn);
6443
+ }
6444
+ _getIcons() {
6445
+ const doubleArrowPath = `M185.27637,135.6062q-.36694.4466-.77393.85608c-.00732.00745-.01318.01575-.021.02307l-72,72a12.0001,12.0001,0,0,1-16.97071-16.9707L147.02539,140H31.99609a12,12,0,0,1,0-24h115.0293L95.51074,64.48535a12.0001,12.0001,0,0,1,16.97071-16.9707l72,72c.00781.00732.01367.01562.021.02307q.40723.409.77393.85608c.11425.1394.21386.28662.32129.42993.12744.17.25927.33643.37744.51318.11474.17115.21386.34888.31836.5243.09619.1604.19677.31726.28515.48242.09619.17944.17725.36389.26368.547.08105.17188.1665.34083.23974.51685.07373.17847.1333.36084.19824.54187.06787.18836.14014.37415.19825.56677.05468.18116.09472.36524.14111.54834.04932.19641.10449.39038.144.59034.042.21167.0669.42553.09766.63867.0249.17431.05762.3457.07519.52221a12.07306,12.07306,0,0,1,0,2.36866c-.01757.17651-.05029.3479-.07519.52221-.03076.21314-.05567.427-.09766.63867-.03955.2-.09472.39393-.144.59034-.04639.1831-.08643.36718-.14111.54834-.0586.19287-.13086.3789-.19825.56762-.06494.18067-.12451.36255-.19824.54078-.07324.17651-.15918.34558-.24023.5177-.08594.18286-.16748.36718-.26319.54638-.08838.16516-.189.322-.28515.48242-.1045.17542-.20362.35315-.31836.5243-.11817.17675-.25.34314-.37744.51318C185.49023,135.31958,185.39062,135.4668,185.27637,135.6062ZM216,28a12,12,0,0,0-12,12V216a12,12,0,0,0,24,0V40A12,12,0,0,0,216,28Z`;
6446
+ const singleArrowPath = `M426.6 755.2L375 703.6l193.1-193.2L375 317.3l51.6-51.6 244.7 244.7z`;
6447
+ const iconStyle = `width: 24px; height: 24px;`;
6448
+ return {
6449
+ nextSvg: `<svg fill="currentColor" viewBox="0 0 256 256" id="Flat" xmlns="http://www.w3.org/2000/svg" style="${iconStyle}"><g id="SVGRepo_iconCarrier"> <path d="${doubleArrowPath}"></path> </g></svg>`,
6450
+ prevSvg: `<svg fill="currentColor" viewBox="0 0 256 256" id="Flat" xmlns="http://www.w3.org/2000/svg" style="${iconStyle} transform: scaleX(-1);"><g id="SVGRepo_iconCarrier"> <path d="${doubleArrowPath}"></path> </g></svg>`,
6451
+ singleNextSvg: `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" style="${iconStyle}"><g id="SVGRepo_iconCarrier"><path d="${singleArrowPath}" fill="currentColor"></path></g></svg>`,
6452
+ singlePrevSvg: `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" style="${iconStyle} transform: scaleX(-1);"><g id="SVGRepo_iconCarrier"><path d="${singleArrowPath}" fill="currentColor"></path></g></svg>`
6453
+ };
6454
+ }
6455
+ _renderCommon(container) {
6456
+ const { nextSvg, prevSvg, singleNextSvg, singlePrevSvg } = this._getIcons();
6457
+ container.appendChild(this._createButton(prevSvg, () => this._changePage(1), this.currentPage === 1));
6458
+ container.appendChild(this._createButton(singlePrevSvg, () => this._changePage(this.currentPage - 1), this.currentPage === 1));
6459
+ let startPage = Math.max(1, this.currentPage - 3);
6460
+ const endPage = Math.min(this.totalPages, startPage + 6);
6461
+ if (endPage - startPage < 6) {
6462
+ startPage = Math.max(1, endPage - 6);
6463
+ }
6464
+ for (let i = startPage; i <= endPage; i++) {
6465
+ const btn = this._createButton(i.toString(), () => this._changePage(i), false);
6466
+ if (i === this.currentPage) btn.classList.add("active");
6467
+ container.appendChild(btn);
6468
+ }
6469
+ container.appendChild(this._createButton(singleNextSvg, () => this._changePage(this.currentPage + 1), this.currentPage === this.totalPages, false, "Next Page"));
6470
+ container.appendChild(this._createButton(nextSvg, () => this._changePage(this.totalPages), this.currentPage === this.totalPages, false, "Last Page"));
6471
+ }
6472
+ _createButton(content, onClick, disabled, isActive = false, ariaLabel) {
6473
+ const li = document.createElement("li");
6474
+ li.className = "page-item";
6475
+ const btn = document.createElement("button");
6476
+ btn.style.all = "unset";
6477
+ btn.style.width = "100%";
6478
+ btn.style.height = "100%";
6479
+ btn.style.display = "flex";
6480
+ btn.style.alignItems = "center";
6481
+ btn.style.justifyContent = "center";
6482
+ btn.style.cursor = disabled ? "default" : "pointer";
6483
+ if (ariaLabel) btn.setAttribute("aria-label", ariaLabel);
6484
+ if (isActive) btn.setAttribute("aria-current", "page");
6485
+ btn.disabled = disabled;
6486
+ if (!disabled) {
6487
+ btn.onclick = onClick;
6488
+ }
6489
+ if (isActive) li.classList.add("active");
6490
+ if (disabled) li.classList.add("disabled");
6491
+ if (content.includes("<svg")) {
6492
+ btn.innerHTML = content;
6493
+ } else {
6494
+ btn.textContent = content;
6495
+ }
6496
+ li.appendChild(btn);
6497
+ return li;
6498
+ }
6499
+ _changePage(newPage) {
6500
+ if (newPage < 1 || newPage > this.totalPages) return;
6501
+ this.setAttribute("current-page", newPage.toString());
6502
+ this.dispatchEvent(
6503
+ new CustomEvent("page-change", {
6504
+ detail: { page: newPage },
6505
+ bubbles: true,
6506
+ composed: true
6507
+ })
6508
+ );
6509
+ }
6510
+ _syncStyles() {
6511
+ this.styleAttributes.forEach((attr) => {
6512
+ const value = this.getAttribute(attr);
6513
+ if (value) {
6514
+ this.style.setProperty(`--${attr}`, value);
6515
+ }
6516
+ });
6517
+ }
6518
+ };
6519
+ if (!customElements.get("wavelength-pagination")) {
6520
+ customElements.define("wavelength-pagination", WavelengthPagination);
6521
+ }
6522
+
6523
+ // src/web-components/wavelength-search.template.html
6524
+ var wavelength_search_template_default = '<style>\n :host {\n display: block;\n --width: 200px;\n --height: 32px;\n --border-width: 1px;\n --mode: automatic;\n --font-size: 14px;\n --border-radius: 50px;\n --border-color: #000;\n --background-color: #fff;\n --hover-color: #007bff;\n --placeholder-color: #999;\n --placeholder-font: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;\n --input-color: #000;\n --input-font: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;\n }\n\n :host([height="small"]) {\n --height: 32px;\n }\n\n :host([height="medium"]) {\n --height: 48px;\n }\n\n :host([height="large"]) {\n --height: 64px;\n }\n\n .flex-container {\n display: block;\n flex-direction: column;\n width: fit-content;\n height: fit-content;\n position: relative;\n }\n\n .searchbar-wrapper {\n display: flex;\n flex-direction: row;\n align-items: center;\n border-radius: var(--border-radius);\n border: var(--border-width) solid var(--border-color);\n background-color: var(--background-color);\n width: var(--width);\n height: var(--height);\n margin: 1px;\n }\n\n .searchbar-wrapper:hover {\n border-color: var(--hover-color);\n }\n\n .searchbar-wrapper:focus-within {\n border-width: calc(var(--border-width) + 1px);\n border-color: var(--hover-color);\n margin: 0px;\n }\n\n :host([icon-pos="end"]) .searchbar-wrapper {\n flex-direction: row-reverse;\n }\n\n .search-button {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 10px;\n padding: 0;\n transition: background-color 0.2s;\n }\n\n .search-button:hover {\n background-color: rgba(0, 0, 0, 0.05);\n }\n\n .search-icon {\n width: var(--font-size);\n height: var(--font-size);\n fill: currentColor;\n }\n\n .input-container {\n position: relative;\n flex-grow: 1;\n display: flex;\n align-items: center;\n height: 100%;\n }\n\n .animated-placeholder {\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--placeholder-color);\n font-family: var(--placeholder-font);\n font-size: var(--font-size);\n pointer-events: none;\n transition: all 0.2s ease;\n background-color: transparent;\n padding: 0 4px;\n border-radius: 4px;\n z-index: 5;\n }\n\n .input-container.focused .animated-placeholder,\n .input-container.has-value .animated-placeholder {\n top: -12px;\n font-size: calc(var(--font-size) * 0.75);\n color: var(--placeholder-color);\n background-color: transparent;\n }\n\n .dropdown {\n position: absolute;\n font-size: var(--font-size);\n font-family: var(--input-font);\n top: calc(100% + 4px);\n left: 0;\n max-height: 200px;\n width: 100%;\n background: white;\n border: 1px solid transparent;\n border-radius: 4px;\n display: none;\n z-index: 10;\n overflow-y: auto;\n overflow-x: hidden;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n }\n\n .dropdown-item {\n padding: 8px 14px;\n cursor: pointer;\n border-left: 3px solid transparent;\n transition:\n background-color 0.1s,\n border-color 0.1s;\n }\n .dropdown-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n }\n .dropdown-item.highlighted {\n background-color: rgba(0, 0, 0, 0.08);\n border-left-color: var(--hover-color);\n }\n\n wavelength-input {\n flex-grow: 1;\n width: 100%;\n height: 100%;\n }\n</style>\n\n<div class="flex-container">\n <div class="searchbar-wrapper">\n <button class="search-button search-icon">\n <svg\n version="1.1"\n id="_x32_"\n xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink"\n viewBox="0 0 512 512"\n xml:space="preserve"\n fill="#000000"\n style="width: 100%; height: 100%"\n >\n <g id="SVGRepo_bgCarrier" stroke-width="0"></g>\n <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>\n <g id="SVGRepo_iconCarrier">\n <style type="text/css">\n .st0 {\n fill: #000000;\n }\n </style>\n <g>\n <path\n class="st0"\n d="M312.069,53.445c-71.26-71.26-187.194-71.26-258.454,0c-71.261,71.26-71.261,187.206,0,258.466 c71.26,71.26,187.194,71.26,258.454,0S383.329,124.705,312.069,53.445z M286.694,286.536 c-57.351,57.34-150.353,57.34-207.704-0.011s-57.351-150.353,0-207.693c57.351-57.351,150.342-57.351,207.693,0 S344.045,229.174,286.694,286.536z"\n ></path>\n <path\n class="st0"\n d="M101.911,112.531c-29.357,37.725-31.801,89.631-7.321,129.702c1.877,3.087,5.902,4.048,8.978,2.182 c3.065-1.888,4.037-5.903,2.16-8.978c-21.666-35.456-19.506-81.538,6.469-114.876c2.226-2.837,1.713-6.938-1.135-9.154 C108.227,109.193,104.125,109.695,101.911,112.531z"\n ></path>\n <path\n class="st0"\n d="M498.544,447.722l-132.637-129.2c-7.255-7.07-18.84-6.982-26.008,0.174l-21.033,21.033 c-7.156,7.156-7.234,18.742-0.153,25.986l129.19,132.636c14.346,17.324,35.542,18.35,51.917,1.964 C516.216,483.951,515.857,462.068,498.544,447.722z"\n ></path>\n </g>\n </g>\n </svg>\n </button>\n <div class="input-container" id="inputContainer">\n <label class="animated-placeholder" id="animatedPlaceholder">Search...</label>\n <wavelength-input\n focus-color="transparent"\n background-color="transparent"\n border-color="transparent"\n label=""\n id="searchInput"\n placeholder=""\n validation-type="onBlur"\n min-length="0"\n clearable\n height="100%"\n padding="0 10px"\n ></wavelength-input>\n <div id="dropdown" class="dropdown"></div>\n </div>\n </div>\n</div>\n';
6525
+
6526
+ // src/web-components/wavelength-search.ts
6527
+ var WavelengthSearch = class extends HTMLElement {
6528
+ constructor() {
6529
+ super();
6530
+ this.options = [];
6531
+ this.highlightedIndex = -1;
6532
+ this.styleAttributes = [
6533
+ "width",
6534
+ "height",
6535
+ "font-size",
6536
+ "border-width",
6537
+ "border-radius",
6538
+ "border-color",
6539
+ "background-color",
6540
+ "hover-color",
6541
+ "placeholder-color",
6542
+ "placeholder-font",
6543
+ "input-color",
6544
+ "input-font"
6545
+ ];
6546
+ this.handleFocusIn = () => {
6547
+ this.inputContainer.classList.add("focused");
6548
+ };
6549
+ this.handleFocusOut = () => {
6550
+ this.inputContainer.classList.remove("focused");
6551
+ };
6552
+ this.handleInputChange = (e) => {
6553
+ const mode = this.getAttribute("mode") || "automatic";
6554
+ const value = e.detail.value;
6555
+ if (value) {
6556
+ this.inputContainer.classList.add("has-value");
6557
+ } else {
6558
+ this.inputContainer.classList.remove("has-value");
6559
+ }
6560
+ if (mode === "automatic") {
6561
+ if (this.searchTimeout) {
6562
+ clearTimeout(this.searchTimeout);
6563
+ }
6564
+ this.searchTimeout = setTimeout(() => {
6565
+ this.handleSearch(value);
6566
+ }, 300);
6567
+ }
6568
+ };
6569
+ this.handleKeydown = (e) => {
6570
+ const isDropdownVisible = this.dropdown.style.display === "block";
6571
+ const items = this.dropdown.querySelectorAll(".dropdown-item");
6572
+ if (e.key === "ArrowDown") {
6573
+ e.preventDefault();
6574
+ if (!isDropdownVisible) {
6575
+ this.handleSearch(this.input.value);
6576
+ } else if (items.length > 0) {
6577
+ this.highlightedIndex = (this.highlightedIndex + 1) % items.length;
6578
+ this.updateHighlight(items);
6579
+ }
6580
+ } else if (e.key === "ArrowUp") {
6581
+ e.preventDefault();
6582
+ if (isDropdownVisible && items.length > 0) {
6583
+ this.highlightedIndex = this.highlightedIndex <= 0 ? items.length - 1 : this.highlightedIndex - 1;
6584
+ this.updateHighlight(items);
6585
+ }
6586
+ } else if (e.key === "Escape" || e.key === "Tab") {
6587
+ this.dropdown.style.display = "none";
6588
+ this.highlightedIndex = -1;
6589
+ if (e.key === "Escape") {
6590
+ this.input.focus();
6591
+ }
6592
+ } else if (e.key === "Enter") {
6593
+ if (isDropdownVisible && this.highlightedIndex >= 0 && this.highlightedIndex < items.length) {
6594
+ e.preventDefault();
6595
+ this.selectOption(items[this.highlightedIndex].textContent || "");
6596
+ } else {
6597
+ const value = this.input.value;
6598
+ this.dispatchEvent(new CustomEvent("wavelength-search-submit", { detail: { value }, bubbles: true, composed: true }));
6599
+ this.handleSearch(value);
6600
+ }
6601
+ }
6602
+ };
6603
+ this.handleSearchIconClick = () => {
6604
+ const value = this.input.value;
6605
+ this.dispatchEvent(new CustomEvent("wavelength-search-submit", { detail: { value }, bubbles: true, composed: true }));
6606
+ this.handleSearch(value);
6607
+ };
6608
+ this.handleDocumentClick = (e) => {
6609
+ if (!this.contains(e.target)) {
6610
+ this.dropdown.style.display = "none";
6611
+ this.highlightedIndex = -1;
6612
+ }
6613
+ };
6614
+ this.shadow = this.attachShadow({ mode: "open" });
6615
+ this.shadow.innerHTML = wavelength_search_template_default;
6616
+ }
6617
+ static get observedAttributes() {
6618
+ return [
6619
+ "width",
6620
+ "height",
6621
+ "mode",
6622
+ "font-size",
6623
+ "border-width",
6624
+ "border-radius",
6625
+ "border-color",
6626
+ "background-color",
6627
+ "hover-color",
6628
+ "options",
6629
+ "placeholder",
6630
+ "icon-pos",
6631
+ "placeholder-color",
6632
+ "placeholder-font",
6633
+ "input-color",
6634
+ "input-font"
6635
+ ];
6636
+ }
6637
+ connectedCallback() {
6638
+ this._syncStyles();
6639
+ this.input = this.shadow.getElementById("searchInput");
6640
+ this.dropdown = this.shadow.getElementById("dropdown");
6641
+ this.inputContainer = this.shadow.getElementById("inputContainer");
6642
+ this.animatedPlaceholder = this.shadow.getElementById("animatedPlaceholder");
6643
+ if (!this.hasAttribute("icon-pos")) {
6644
+ this.setAttribute("icon-pos", "end");
6645
+ }
6646
+ if (!this.hasAttribute("height")) {
6647
+ this.setAttribute("height", "small");
6648
+ }
6649
+ const placeholder = this.getAttribute("placeholder") || "Search...";
6650
+ this.animatedPlaceholder.textContent = placeholder;
6651
+ const searchIcon = this.shadow.querySelector(".search-icon");
6652
+ this.input.addEventListener("focusin", this.handleFocusIn);
6653
+ this.input.addEventListener("focusout", this.handleFocusOut);
6654
+ this.input.addEventListener("inputChange", this.handleInputChange);
6655
+ this.input.addEventListener("keydown", this.handleKeydown);
6656
+ if (searchIcon) {
6657
+ searchIcon.addEventListener("click", this.handleSearchIconClick);
6658
+ }
6659
+ document.addEventListener("click", this.handleDocumentClick);
6660
+ }
6661
+ disconnectedCallback() {
6662
+ this.input.removeEventListener("focusin", this.handleFocusIn);
6663
+ this.input.removeEventListener("focusout", this.handleFocusOut);
6664
+ this.input.removeEventListener("inputChange", this.handleInputChange);
6665
+ this.input.removeEventListener("keydown", this.handleKeydown);
6666
+ const searchIcon = this.shadow.querySelector(".search-icon");
6667
+ if (searchIcon) {
6668
+ searchIcon.removeEventListener("click", this.handleSearchIconClick);
6669
+ }
6670
+ document.removeEventListener("click", this.handleDocumentClick);
6671
+ }
6672
+ attributeChangedCallback(name, oldValue, newValue) {
6673
+ if (oldValue === newValue) return;
6674
+ if (this.styleAttributes.includes(name)) {
6675
+ if (name === "height") {
6676
+ if (["small", "medium", "large"].includes(newValue || "")) {
6677
+ this.style.removeProperty("--height");
6678
+ } else if (newValue !== null) {
6679
+ this.style.setProperty("--height", newValue);
6680
+ } else {
6681
+ this.style.removeProperty("--height");
6682
+ }
6683
+ } else {
6684
+ if (newValue !== null) {
6685
+ this.style.setProperty(`--${name}`, newValue);
6686
+ } else {
6687
+ this.style.removeProperty(`--${name}`);
6688
+ }
6689
+ }
6690
+ }
6691
+ if (name === "options" && newValue) {
6692
+ try {
6693
+ this.options = JSON.parse(newValue);
6694
+ } catch (e) {
6695
+ this.options = newValue.split(",").map((s) => s.trim());
6696
+ }
6697
+ } else if (name === "placeholder" && this.animatedPlaceholder) {
6698
+ this.animatedPlaceholder.textContent = newValue || "Search...";
6699
+ } else if (name === "font-size" && this.input) {
6700
+ this.input.setAttribute("font-size", newValue || "");
6701
+ } else if (name === "input-color" && this.input) {
6702
+ this.input.setAttribute("text-color", newValue || "");
6703
+ } else if (name === "input-font" && this.input) {
6704
+ this.input.setAttribute("font-family", newValue || "");
6705
+ }
6706
+ }
6707
+ handleSearch(query) {
6708
+ if (this.searchTimeout) {
6709
+ clearTimeout(this.searchTimeout);
6710
+ this.searchTimeout = null;
6711
+ }
6712
+ if (!query) {
6713
+ this.dropdown.style.display = "none";
6714
+ return;
6715
+ }
6716
+ const results = this.options.filter((option) => option.toLowerCase().includes(query.toLowerCase()));
6717
+ this.highlightedIndex = -1;
6718
+ this.renderDropdown(results);
6719
+ }
6720
+ renderDropdown(results) {
6721
+ if (results.length === 0) {
6722
+ this.dropdown.style.display = "none";
6723
+ return;
6724
+ }
6725
+ this.dropdown.innerHTML = results.map((r) => `<div class="dropdown-item">${r}</div>`).join("");
6726
+ this.dropdown.style.display = "block";
6727
+ const items = this.dropdown.querySelectorAll(".dropdown-item");
6728
+ items.forEach((item, index) => {
6729
+ item.addEventListener("click", () => {
6730
+ this.selectOption(item.textContent || "");
6731
+ });
6732
+ item.addEventListener("mouseenter", () => {
6733
+ this.highlightedIndex = index;
6734
+ this.updateHighlight(items);
6735
+ });
6736
+ });
6737
+ this.updateHighlight(items);
6738
+ }
6739
+ selectOption(value) {
6740
+ this.input.value = value;
6741
+ this.dropdown.style.display = "none";
6742
+ this.highlightedIndex = -1;
6743
+ this.dispatchEvent(new CustomEvent("wavelength-search-select", { detail: { value }, bubbles: true, composed: true }));
6744
+ }
6745
+ // ---- Getters and Setters API ---- //
6746
+ get value() {
6747
+ return this.input.value;
6748
+ }
6749
+ set value(val) {
6750
+ this.input.value = val;
6751
+ }
6752
+ get optionsList() {
6753
+ return this.options;
6754
+ }
6755
+ set optionsList(val) {
6756
+ if (val) {
6757
+ this.options = val;
6758
+ this.setAttribute("options", JSON.stringify(val));
6759
+ }
6760
+ }
6761
+ _syncStyles() {
6762
+ this.styleAttributes.forEach((attr) => {
6763
+ const value = this.getAttribute(attr);
6764
+ if (value) {
6765
+ if (attr === "height" && ["small", "medium", "large"].includes(value)) {
6766
+ } else {
6767
+ this.style.setProperty(`--${attr}`, value);
6768
+ }
6769
+ }
6770
+ });
6771
+ }
6772
+ updateHighlight(items) {
6773
+ items.forEach((item, index) => {
6774
+ const isHighlighted = index === this.highlightedIndex;
6775
+ item.classList.toggle("highlighted", isHighlighted);
6776
+ if (isHighlighted) {
6777
+ item.scrollIntoView({ block: "nearest" });
6778
+ }
6779
+ });
6780
+ }
6781
+ };
6782
+ if (!customElements.get("wavelength-search")) {
6783
+ customElements.define("wavelength-search", WavelengthSearch);
6784
+ }
6785
+
6786
+
6787
+
6348
6788
 
6349
6789
 
6350
6790
 
@@ -6367,7 +6807,7 @@ if (!customElements.get("wavelength-menu")) {
6367
6807
 
6368
6808
 
6369
6809
 
6370
- exports.BaseWavelengthInput = BaseWavelengthInput; exports.BaseWavelengthMultiSelectAutocomplete = BaseWavelengthMultiSelectAutocomplete; exports.ChildDataTable = ChildDataTable; exports.SampleComponent = SampleComponent; exports.WavelengthBanner = WavelengthBanner; exports.WavelengthButton = WavelengthButton; exports.WavelengthCheckbox = WavelengthCheckbox; exports.WavelengthDatePicker = WavelengthDatePicker; exports.WavelengthDropdown = WavelengthDropdown; exports.WavelengthFileDropZone = WavelengthFileDropZone; exports.WavelengthForm = WavelengthForm; exports.WavelengthInput = WavelengthInput; exports.WavelengthManyPlanes = WavelengthManyPlanes; exports.WavelengthMenu = WavelengthMenu; exports.WavelengthMultiSelectAutocomplete = WavelengthMultiSelectAutocomplete; exports.WavelengthNavBar = WavelengthNavBar; exports.WavelengthNotificationPanel = WavelengthNotificationPanel; exports.WavelengthPlaneTrail = WavelengthPlaneTrail; exports.WavelengthProgressBar = WavelengthProgressBar; exports.WavelengthSnackbar = WavelengthSnackbar; exports.WavelengthTitleBar = WavelengthTitleBar; exports.WavelengthToolTip = WavelengthToolTip;
6810
+ exports.BaseWavelengthInput = BaseWavelengthInput; exports.BaseWavelengthMultiSelectAutocomplete = BaseWavelengthMultiSelectAutocomplete; exports.ChildDataTable = ChildDataTable; exports.SampleComponent = SampleComponent; exports.WavelengthBanner = WavelengthBanner; exports.WavelengthButton = WavelengthButton; exports.WavelengthCheckbox = WavelengthCheckbox; exports.WavelengthDatePicker = WavelengthDatePicker; exports.WavelengthDropdown = WavelengthDropdown; exports.WavelengthFileDropZone = WavelengthFileDropZone; exports.WavelengthForm = WavelengthForm; exports.WavelengthInput = WavelengthInput; exports.WavelengthManyPlanes = WavelengthManyPlanes; exports.WavelengthMenu = WavelengthMenu; exports.WavelengthMultiSelectAutocomplete = WavelengthMultiSelectAutocomplete; exports.WavelengthNavBar = WavelengthNavBar; exports.WavelengthNotificationPanel = WavelengthNotificationPanel; exports.WavelengthPagination = WavelengthPagination; exports.WavelengthPlaneTrail = WavelengthPlaneTrail; exports.WavelengthProgressBar = WavelengthProgressBar; exports.WavelengthSearch = WavelengthSearch; exports.WavelengthSnackbar = WavelengthSnackbar; exports.WavelengthTitleBar = WavelengthTitleBar; exports.WavelengthToolTip = WavelengthToolTip;
6371
6811
  /*! Bundled license information:
6372
6812
 
6373
6813
  react/cjs/react.production.min.js:
@@ -2286,4 +2286,58 @@ declare class WavelengthMenu extends HTMLElement {
2286
2286
  private _dispatchSelectEvent;
2287
2287
  }
2288
2288
 
2289
- export { BaseWavelengthInput, BaseWavelengthMultiSelectAutocomplete, type CheckboxElements, ChildDataTable, SampleComponent, WavelengthBanner, WavelengthButton, WavelengthCheckbox, WavelengthDatePicker, WavelengthDropdown, WavelengthFileDropZone, WavelengthForm, WavelengthInput, WavelengthManyPlanes, WavelengthMenu, WavelengthMultiSelectAutocomplete, WavelengthNavBar, WavelengthNotificationPanel, WavelengthPlaneTrail, WavelengthProgressBar, WavelengthSnackbar, WavelengthTitleBar, WavelengthToolTip };
2289
+ declare class WavelengthPagination extends HTMLElement {
2290
+ static get observedAttributes(): string[];
2291
+ private shadow;
2292
+ private styleAttributes;
2293
+ private renderAttributes;
2294
+ constructor();
2295
+ get totalPages(): number;
2296
+ set totalPages(val: number);
2297
+ get currentPage(): number;
2298
+ set currentPage(val: number);
2299
+ connectedCallback(): void;
2300
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2301
+ private _clearAndRender;
2302
+ private _renderByVariant;
2303
+ private _renderBasic;
2304
+ private _getIcons;
2305
+ private _renderCommon;
2306
+ private _createButton;
2307
+ private _changePage;
2308
+ private _syncStyles;
2309
+ }
2310
+
2311
+ declare class WavelengthSearch extends HTMLElement {
2312
+ static get observedAttributes(): string[];
2313
+ private shadow;
2314
+ private input;
2315
+ private dropdown;
2316
+ private inputContainer;
2317
+ private animatedPlaceholder;
2318
+ private options;
2319
+ private highlightedIndex;
2320
+ private styleAttributes;
2321
+ constructor();
2322
+ connectedCallback(): void;
2323
+ disconnectedCallback(): void;
2324
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2325
+ private handleSearch;
2326
+ private renderDropdown;
2327
+ private selectOption;
2328
+ get value(): string;
2329
+ set value(val: string);
2330
+ get optionsList(): string[] | undefined;
2331
+ set optionsList(val: string[] | undefined);
2332
+ private _syncStyles;
2333
+ private handleFocusIn;
2334
+ private handleFocusOut;
2335
+ private searchTimeout;
2336
+ private handleInputChange;
2337
+ private handleKeydown;
2338
+ private updateHighlight;
2339
+ private handleSearchIconClick;
2340
+ private handleDocumentClick;
2341
+ }
2342
+
2343
+ export { BaseWavelengthInput, BaseWavelengthMultiSelectAutocomplete, type CheckboxElements, ChildDataTable, SampleComponent, WavelengthBanner, WavelengthButton, WavelengthCheckbox, WavelengthDatePicker, WavelengthDropdown, WavelengthFileDropZone, WavelengthForm, WavelengthInput, WavelengthManyPlanes, WavelengthMenu, WavelengthMultiSelectAutocomplete, WavelengthNavBar, WavelengthNotificationPanel, WavelengthPagination, WavelengthPlaneTrail, WavelengthProgressBar, WavelengthSearch, WavelengthSnackbar, WavelengthTitleBar, WavelengthToolTip };
@@ -2286,4 +2286,58 @@ declare class WavelengthMenu extends HTMLElement {
2286
2286
  private _dispatchSelectEvent;
2287
2287
  }
2288
2288
 
2289
- export { BaseWavelengthInput, BaseWavelengthMultiSelectAutocomplete, type CheckboxElements, ChildDataTable, SampleComponent, WavelengthBanner, WavelengthButton, WavelengthCheckbox, WavelengthDatePicker, WavelengthDropdown, WavelengthFileDropZone, WavelengthForm, WavelengthInput, WavelengthManyPlanes, WavelengthMenu, WavelengthMultiSelectAutocomplete, WavelengthNavBar, WavelengthNotificationPanel, WavelengthPlaneTrail, WavelengthProgressBar, WavelengthSnackbar, WavelengthTitleBar, WavelengthToolTip };
2289
+ declare class WavelengthPagination extends HTMLElement {
2290
+ static get observedAttributes(): string[];
2291
+ private shadow;
2292
+ private styleAttributes;
2293
+ private renderAttributes;
2294
+ constructor();
2295
+ get totalPages(): number;
2296
+ set totalPages(val: number);
2297
+ get currentPage(): number;
2298
+ set currentPage(val: number);
2299
+ connectedCallback(): void;
2300
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2301
+ private _clearAndRender;
2302
+ private _renderByVariant;
2303
+ private _renderBasic;
2304
+ private _getIcons;
2305
+ private _renderCommon;
2306
+ private _createButton;
2307
+ private _changePage;
2308
+ private _syncStyles;
2309
+ }
2310
+
2311
+ declare class WavelengthSearch extends HTMLElement {
2312
+ static get observedAttributes(): string[];
2313
+ private shadow;
2314
+ private input;
2315
+ private dropdown;
2316
+ private inputContainer;
2317
+ private animatedPlaceholder;
2318
+ private options;
2319
+ private highlightedIndex;
2320
+ private styleAttributes;
2321
+ constructor();
2322
+ connectedCallback(): void;
2323
+ disconnectedCallback(): void;
2324
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
2325
+ private handleSearch;
2326
+ private renderDropdown;
2327
+ private selectOption;
2328
+ get value(): string;
2329
+ set value(val: string);
2330
+ get optionsList(): string[] | undefined;
2331
+ set optionsList(val: string[] | undefined);
2332
+ private _syncStyles;
2333
+ private handleFocusIn;
2334
+ private handleFocusOut;
2335
+ private searchTimeout;
2336
+ private handleInputChange;
2337
+ private handleKeydown;
2338
+ private updateHighlight;
2339
+ private handleSearchIconClick;
2340
+ private handleDocumentClick;
2341
+ }
2342
+
2343
+ export { BaseWavelengthInput, BaseWavelengthMultiSelectAutocomplete, type CheckboxElements, ChildDataTable, SampleComponent, WavelengthBanner, WavelengthButton, WavelengthCheckbox, WavelengthDatePicker, WavelengthDropdown, WavelengthFileDropZone, WavelengthForm, WavelengthInput, WavelengthManyPlanes, WavelengthMenu, WavelengthMultiSelectAutocomplete, WavelengthNavBar, WavelengthNotificationPanel, WavelengthPagination, WavelengthPlaneTrail, WavelengthProgressBar, WavelengthSearch, WavelengthSnackbar, WavelengthTitleBar, WavelengthToolTip };
package/dist/esm/index.js CHANGED
@@ -3183,7 +3183,7 @@ if (!customElements.get("wavelength-progress-bar")) {
3183
3183
  }
3184
3184
 
3185
3185
  // src/web-components/wavelength-input.template.html
3186
- var wavelength_input_template_default = '<style>\n :host {\n display: block;\n width: 100%;\n font-family: sans-serif;\n --wavelength-container-background: #f8f8f8;\n --wavelength-label-background: #ffffff;\n }\n\n .field-wrapper {\n position: relative;\n }\n\n .floating-label {\n position: absolute;\n top: -0.325rem;\n left: 12px;\n font-size: 0.75rem;\n line-height: 1;\n color: var(--wavelength-label-color, #666666);\n padding: 0 4px;\n z-index: 1;\n pointer-events: none;\n user-select: none;\n }\n\n .floating-label::before,\n .floating-label::after {\n content: "";\n position: absolute;\n left: 0;\n width: 100%;\n z-index: -1;\n }\n\n .floating-label::before {\n top: 0;\n height: 50%;\n background: var(--wavelength-container-background, white);\n }\n\n .floating-label::after {\n bottom: 0;\n height: 50%;\n background: var(--wavelength-label-background, #ffffff);\n }\n\n :host([disabled]) .floating-label::before {\n opacity: 0;\n }\n\n input {\n font-size: 16px;\n padding: 16.5px 14px;\n border: 1px solid var(--wavelength-border-color, #cccccc);\n border-radius: 8px;\n width: 100%;\n box-sizing: border-box;\n background-color: var(--wavelength-background, #ffffff);\n transition: border-color 0.2s ease;\n overflow: auto;\n font-family: inherit;\n }\n\n input:focus {\n outline: none;\n }\n\n input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n :host([disabled]) .floating-label::after {\n opacity: 0;\n cursor: not-allowed;\n }\n\n input::placeholder {\n color: #999999;\n }\n\n .helper-message {\n margin-top: 4px;\n font-size: 0.75rem;\n max-width: 100%;\n word-wrap: break-word;\n white-space: normal;\n overflow-wrap: break-word;\n color: #000000;\n padding-left: 14px;\n margin-left: 2px;\n user-select: none;\n }\n\n .required-marker {\n color: red;\n font-weight: lighter;\n font-size: 0.75rem;\n }\n\n .clear-button {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1.25 rem;\n color: #666666;\n cursor: pointer;\n opacity: 0.5;\n user-select: none;\n transition: opacity 0.2s ease;\n z-index: 2;\n display: none;\n line-height: 1;\n padding: 0 4px;\n }\n\n .clear-button:hover {\n opacity: 1;\n }\n\n :host([disabled]) .clear-button {\n display: none;\n }\n</style>\n<div class="field-wrapper">\n <label class="floating-label" id="floating-label"></label>\n <div class="input-wrapper"></div>\n <div class="clear-button" id="clear-button" title="Clear input">\u2715</div>\n</div>\n<div class="helper-message" id="helper"></div>\n';
3186
+ var wavelength_input_template_default = '<style>\n :host {\n display: block;\n width: 100%;\n font-family: sans-serif;\n --wavelength-container-background: #f8f8f8;\n --wavelength-label-background: #ffffff;\n }\n\n .field-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .input-wrapper {\n width: 100%;\n height: 100%;\n }\n\n .floating-label {\n position: absolute;\n top: -0.325rem;\n left: 12px;\n font-size: 0.75rem;\n line-height: 1;\n color: var(--wavelength-label-color, #666666);\n padding: 0 4px;\n z-index: 1;\n pointer-events: none;\n user-select: none;\n }\n\n .floating-label::before,\n .floating-label::after {\n content: "";\n position: absolute;\n left: 0;\n width: 100%;\n z-index: -1;\n }\n\n .floating-label::before {\n top: 0;\n height: 50%;\n background: var(--wavelength-container-background, white);\n }\n\n .floating-label::after {\n bottom: 0;\n height: 50%;\n background: var(--wavelength-label-background, #ffffff);\n }\n\n :host([disabled]) .floating-label::before {\n opacity: 0;\n }\n\n input {\n font-size: 16px;\n padding: 16.5px 14px;\n border: 1px solid var(--wavelength-border-color, #cccccc);\n border-radius: 8px;\n width: 100%;\n box-sizing: border-box;\n background-color: var(--wavelength-background, #ffffff);\n transition: border-color 0.2s ease;\n overflow: auto;\n font-family: inherit;\n }\n\n input:focus {\n outline: none;\n }\n\n input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n :host([disabled]) .floating-label::after {\n opacity: 0;\n cursor: not-allowed;\n }\n\n input::placeholder {\n color: #999999;\n }\n\n .helper-message {\n margin-top: 4px;\n font-size: 0.75rem;\n max-width: 100%;\n word-wrap: break-word;\n white-space: normal;\n overflow-wrap: break-word;\n color: #000000;\n padding-left: 14px;\n margin-left: 2px;\n user-select: none;\n }\n\n .required-marker {\n color: red;\n font-weight: lighter;\n font-size: 0.75rem;\n }\n\n .clear-button {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1.25 rem;\n color: #666666;\n cursor: pointer;\n opacity: 0.5;\n user-select: none;\n transition: opacity 0.2s ease;\n z-index: 2;\n display: none;\n line-height: 1;\n padding: 0 4px;\n }\n\n .clear-button:hover {\n opacity: 1;\n }\n\n :host([disabled]) .clear-button {\n display: none;\n }\n</style>\n<div class="field-wrapper">\n <label class="floating-label" id="floating-label"></label>\n <div class="input-wrapper"></div>\n <div class="clear-button" id="clear-button" title="Clear input">\u2715</div>\n</div>\n<div class="helper-message" id="helper"></div>\n';
3187
3187
 
3188
3188
  // src/web-components/wavelength-input.ts
3189
3189
  function getAncestor(el) {
@@ -3302,7 +3302,9 @@ var BaseWavelengthInput = class extends HTMLElement {
3302
3302
  "max-length",
3303
3303
  "required",
3304
3304
  "force-error",
3305
- "label"
3305
+ "label",
3306
+ "font-size",
3307
+ "font-family"
3306
3308
  ];
3307
3309
  }
3308
3310
  connectedCallback() {
@@ -3430,6 +3432,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3430
3432
  }
3431
3433
  this.helperEl.innerHTML = htmlMessage;
3432
3434
  this.helperEl.classList.add("error");
3435
+ this.helperEl.style.display = "block";
3433
3436
  this.inputEl.style.borderColor = "red";
3434
3437
  this.helperEl.style.color = "red";
3435
3438
  this.inputEl.setAttribute("aria-invalid", "true");
@@ -3442,6 +3445,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3442
3445
  this.helperEl.textContent = helperText;
3443
3446
  this.helperEl.classList.remove("error");
3444
3447
  this.helperEl.style.color = helperColor;
3448
+ this.helperEl.style.display = helperText ? "block" : "none";
3445
3449
  this.inputEl.style.borderColor = borderColor;
3446
3450
  this.inputEl.setAttribute("aria-invalid", "false");
3447
3451
  this.removeAttribute("data-error");
@@ -3519,6 +3523,12 @@ var BaseWavelengthInput = class extends HTMLElement {
3519
3523
  this.inputEl.style.padding = rawPadding;
3520
3524
  this.inputEl.style.height = this.getAttribute("height") || "";
3521
3525
  this.inputEl.style.borderRadius = this.getAttribute("border-radius") || "8px";
3526
+ if (this.hasAttribute("font-size")) {
3527
+ this.inputEl.style.fontSize = this.getAttribute("font-size");
3528
+ }
3529
+ if (this.hasAttribute("font-family")) {
3530
+ this.inputEl.style.fontFamily = this.getAttribute("font-family");
3531
+ }
3522
3532
  this.helperEl.style.width = helperWidth;
3523
3533
  this.helperEl.style.paddingLeft = `${leftPaddingPx}px`;
3524
3534
  }
@@ -3564,6 +3574,7 @@ var BaseWavelengthInput = class extends HTMLElement {
3564
3574
  if (!hasError) {
3565
3575
  this.helperEl.textContent = helper;
3566
3576
  this.helperEl.style.color = helperColor;
3577
+ this.helperEl.style.display = helper ? "block" : "none";
3567
3578
  }
3568
3579
  }
3569
3580
  _applyAccessibility() {
@@ -3588,7 +3599,10 @@ var BaseWavelengthInput = class extends HTMLElement {
3588
3599
  this.inputEl.name = newValue || "";
3589
3600
  break;
3590
3601
  case "label":
3602
+ case "font-size":
3603
+ case "font-family":
3591
3604
  this._applyContent();
3605
+ this._applyLayout();
3592
3606
  break;
3593
3607
  case "helper-message":
3594
3608
  this._applyValidationHint();
@@ -6344,6 +6358,430 @@ var WavelengthMenu = class extends HTMLElement {
6344
6358
  if (!customElements.get("wavelength-menu")) {
6345
6359
  customElements.define("wavelength-menu", WavelengthMenu);
6346
6360
  }
6361
+
6362
+ // src/web-components/wavelength-pagination.template.html
6363
+ var wavelength_pagination_template_default = '<style>\n :host {\n display: block;\n --local-font: var(--font, "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);\n font-family: var(--local-font);\n }\n\n .pagination-list,\n .pagination-list * {\n font-family: inherit;\n font-size: var(--font-size, 16px);\n color: var(--text-color, black);\n }\n\n .pagination-list {\n display: flex;\n list-style: none;\n padding: var(--padding, 10px);\n margin: 0;\n align-items: center;\n }\n\n .page-item {\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s ease;\n user-select: none;\n background-color: var(--background-color, white);\n }\n\n .page-item.disabled,\n .page-item.disabled * {\n cursor: default;\n background-color: var(--background-color, white);\n color: var(--disabled-color, #ccc);\n border-color: var(--disabled-color, #ccc);\n }\n\n /* --- BASIC VARIANT --- */\n .pagination-list.basic {\n gap: 15px;\n }\n\n .pagination-list.basic .page-info {\n margin-right: 10px;\n font-weight: 500;\n }\n\n .pagination-list.basic .page-item {\n width: 32px;\n height: 32px;\n border: var(--border, none);\n border-radius: var(--border-radius, 50%);\n }\n\n .pagination-list.basic .page-item:not(.disabled):hover {\n filter: brightness(0.95);\n }\n\n /* --- COMMON VARIANT --- */\n .pagination-list.common {\n gap: 8px;\n }\n\n .pagination-list.common .page-item {\n width: 40px;\n height: 40px;\n border: var(--border, none);\n border-radius: var(--border-radius, 50%);\n }\n\n .pagination-list.common .page-item.active,\n .pagination-list.common .page-item.active * {\n background-color: var(--active-color, #49baf7);\n color: var(--active-text-color, #fff);\n border-color: var(--active-color, #49baf7);\n }\n\n .pagination-list.common .page-item:not(.disabled):not(.active):hover {\n filter: brightness(0.95);\n transform: scale(1.1);\n }\n</style>\n<nav aria-label="pagination">\n <ul class="pagination-list"></ul>\n</nav>\n';
6364
+
6365
+ // src/web-components/wavelength-pagination.ts
6366
+ var WavelengthPagination = class extends HTMLElement {
6367
+ constructor() {
6368
+ super();
6369
+ this.styleAttributes = ["variant", "text-color", "font", "font-size", "border", "border-radius", "padding", "active-color", "active-text-color", "background-color", "disabled-color"];
6370
+ this.renderAttributes = ["variant", "total-pages", "current-page"];
6371
+ this.shadow = this.attachShadow({ mode: "open" });
6372
+ this.shadow.innerHTML = wavelength_pagination_template_default;
6373
+ }
6374
+ static get observedAttributes() {
6375
+ return [
6376
+ "variant",
6377
+ "text-color",
6378
+ "font",
6379
+ "font-size",
6380
+ "border",
6381
+ "border-radius",
6382
+ "padding",
6383
+ "total-pages",
6384
+ "current-page",
6385
+ "active-color",
6386
+ "active-text-color",
6387
+ "background-color",
6388
+ "disabled-color"
6389
+ ];
6390
+ }
6391
+ get totalPages() {
6392
+ const parsed = Number.parseInt(this.getAttribute("total-pages") || "1", 10);
6393
+ return isNaN(parsed) ? 1 : parsed;
6394
+ }
6395
+ set totalPages(val) {
6396
+ this.setAttribute("total-pages", val.toString());
6397
+ }
6398
+ get currentPage() {
6399
+ const parsed = Number.parseInt(this.getAttribute("current-page") || "1", 10);
6400
+ return isNaN(parsed) ? 1 : parsed;
6401
+ }
6402
+ set currentPage(val) {
6403
+ this.setAttribute("current-page", val.toString());
6404
+ }
6405
+ connectedCallback() {
6406
+ this._clearAndRender();
6407
+ this._syncStyles();
6408
+ }
6409
+ attributeChangedCallback(name, oldValue, newValue) {
6410
+ if (oldValue === newValue) return;
6411
+ if (this.styleAttributes.includes(name)) {
6412
+ this.style.setProperty(`--${name}`, newValue);
6413
+ }
6414
+ if (this.renderAttributes.includes(name)) {
6415
+ this._clearAndRender();
6416
+ }
6417
+ }
6418
+ _clearAndRender() {
6419
+ const list = this.shadow.querySelector(".pagination-list");
6420
+ if (!list) return;
6421
+ const variant = this.getAttribute("variant") || "basic";
6422
+ list.innerHTML = "";
6423
+ list.className = `pagination-list ${variant}`;
6424
+ this._renderByVariant(list, variant);
6425
+ }
6426
+ _renderByVariant(container, variant) {
6427
+ if (variant === "basic") {
6428
+ this._renderBasic(container);
6429
+ } else {
6430
+ this._renderCommon(container);
6431
+ }
6432
+ }
6433
+ _renderBasic(container) {
6434
+ const { singlePrevSvg, singleNextSvg } = this._getIcons();
6435
+ const textInfo = document.createElement("span");
6436
+ textInfo.className = "page-info";
6437
+ textInfo.textContent = `Page ${this.currentPage} of ${this.totalPages}`;
6438
+ container.appendChild(textInfo);
6439
+ const prevBtn = this._createButton(singlePrevSvg, () => this._changePage(this.currentPage - 1), this.currentPage === 1);
6440
+ const nextBtn = this._createButton(singleNextSvg, () => this._changePage(this.currentPage + 1), this.currentPage === this.totalPages);
6441
+ container.appendChild(prevBtn);
6442
+ container.appendChild(nextBtn);
6443
+ }
6444
+ _getIcons() {
6445
+ const doubleArrowPath = `M185.27637,135.6062q-.36694.4466-.77393.85608c-.00732.00745-.01318.01575-.021.02307l-72,72a12.0001,12.0001,0,0,1-16.97071-16.9707L147.02539,140H31.99609a12,12,0,0,1,0-24h115.0293L95.51074,64.48535a12.0001,12.0001,0,0,1,16.97071-16.9707l72,72c.00781.00732.01367.01562.021.02307q.40723.409.77393.85608c.11425.1394.21386.28662.32129.42993.12744.17.25927.33643.37744.51318.11474.17115.21386.34888.31836.5243.09619.1604.19677.31726.28515.48242.09619.17944.17725.36389.26368.547.08105.17188.1665.34083.23974.51685.07373.17847.1333.36084.19824.54187.06787.18836.14014.37415.19825.56677.05468.18116.09472.36524.14111.54834.04932.19641.10449.39038.144.59034.042.21167.0669.42553.09766.63867.0249.17431.05762.3457.07519.52221a12.07306,12.07306,0,0,1,0,2.36866c-.01757.17651-.05029.3479-.07519.52221-.03076.21314-.05567.427-.09766.63867-.03955.2-.09472.39393-.144.59034-.04639.1831-.08643.36718-.14111.54834-.0586.19287-.13086.3789-.19825.56762-.06494.18067-.12451.36255-.19824.54078-.07324.17651-.15918.34558-.24023.5177-.08594.18286-.16748.36718-.26319.54638-.08838.16516-.189.322-.28515.48242-.1045.17542-.20362.35315-.31836.5243-.11817.17675-.25.34314-.37744.51318C185.49023,135.31958,185.39062,135.4668,185.27637,135.6062ZM216,28a12,12,0,0,0-12,12V216a12,12,0,0,0,24,0V40A12,12,0,0,0,216,28Z`;
6446
+ const singleArrowPath = `M426.6 755.2L375 703.6l193.1-193.2L375 317.3l51.6-51.6 244.7 244.7z`;
6447
+ const iconStyle = `width: 24px; height: 24px;`;
6448
+ return {
6449
+ nextSvg: `<svg fill="currentColor" viewBox="0 0 256 256" id="Flat" xmlns="http://www.w3.org/2000/svg" style="${iconStyle}"><g id="SVGRepo_iconCarrier"> <path d="${doubleArrowPath}"></path> </g></svg>`,
6450
+ prevSvg: `<svg fill="currentColor" viewBox="0 0 256 256" id="Flat" xmlns="http://www.w3.org/2000/svg" style="${iconStyle} transform: scaleX(-1);"><g id="SVGRepo_iconCarrier"> <path d="${doubleArrowPath}"></path> </g></svg>`,
6451
+ singleNextSvg: `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" style="${iconStyle}"><g id="SVGRepo_iconCarrier"><path d="${singleArrowPath}" fill="currentColor"></path></g></svg>`,
6452
+ singlePrevSvg: `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" style="${iconStyle} transform: scaleX(-1);"><g id="SVGRepo_iconCarrier"><path d="${singleArrowPath}" fill="currentColor"></path></g></svg>`
6453
+ };
6454
+ }
6455
+ _renderCommon(container) {
6456
+ const { nextSvg, prevSvg, singleNextSvg, singlePrevSvg } = this._getIcons();
6457
+ container.appendChild(this._createButton(prevSvg, () => this._changePage(1), this.currentPage === 1));
6458
+ container.appendChild(this._createButton(singlePrevSvg, () => this._changePage(this.currentPage - 1), this.currentPage === 1));
6459
+ let startPage = Math.max(1, this.currentPage - 3);
6460
+ const endPage = Math.min(this.totalPages, startPage + 6);
6461
+ if (endPage - startPage < 6) {
6462
+ startPage = Math.max(1, endPage - 6);
6463
+ }
6464
+ for (let i = startPage; i <= endPage; i++) {
6465
+ const btn = this._createButton(i.toString(), () => this._changePage(i), false);
6466
+ if (i === this.currentPage) btn.classList.add("active");
6467
+ container.appendChild(btn);
6468
+ }
6469
+ container.appendChild(this._createButton(singleNextSvg, () => this._changePage(this.currentPage + 1), this.currentPage === this.totalPages, false, "Next Page"));
6470
+ container.appendChild(this._createButton(nextSvg, () => this._changePage(this.totalPages), this.currentPage === this.totalPages, false, "Last Page"));
6471
+ }
6472
+ _createButton(content, onClick, disabled, isActive = false, ariaLabel) {
6473
+ const li = document.createElement("li");
6474
+ li.className = "page-item";
6475
+ const btn = document.createElement("button");
6476
+ btn.style.all = "unset";
6477
+ btn.style.width = "100%";
6478
+ btn.style.height = "100%";
6479
+ btn.style.display = "flex";
6480
+ btn.style.alignItems = "center";
6481
+ btn.style.justifyContent = "center";
6482
+ btn.style.cursor = disabled ? "default" : "pointer";
6483
+ if (ariaLabel) btn.setAttribute("aria-label", ariaLabel);
6484
+ if (isActive) btn.setAttribute("aria-current", "page");
6485
+ btn.disabled = disabled;
6486
+ if (!disabled) {
6487
+ btn.onclick = onClick;
6488
+ }
6489
+ if (isActive) li.classList.add("active");
6490
+ if (disabled) li.classList.add("disabled");
6491
+ if (content.includes("<svg")) {
6492
+ btn.innerHTML = content;
6493
+ } else {
6494
+ btn.textContent = content;
6495
+ }
6496
+ li.appendChild(btn);
6497
+ return li;
6498
+ }
6499
+ _changePage(newPage) {
6500
+ if (newPage < 1 || newPage > this.totalPages) return;
6501
+ this.setAttribute("current-page", newPage.toString());
6502
+ this.dispatchEvent(
6503
+ new CustomEvent("page-change", {
6504
+ detail: { page: newPage },
6505
+ bubbles: true,
6506
+ composed: true
6507
+ })
6508
+ );
6509
+ }
6510
+ _syncStyles() {
6511
+ this.styleAttributes.forEach((attr) => {
6512
+ const value = this.getAttribute(attr);
6513
+ if (value) {
6514
+ this.style.setProperty(`--${attr}`, value);
6515
+ }
6516
+ });
6517
+ }
6518
+ };
6519
+ if (!customElements.get("wavelength-pagination")) {
6520
+ customElements.define("wavelength-pagination", WavelengthPagination);
6521
+ }
6522
+
6523
+ // src/web-components/wavelength-search.template.html
6524
+ var wavelength_search_template_default = '<style>\n :host {\n display: block;\n --width: 200px;\n --height: 32px;\n --border-width: 1px;\n --mode: automatic;\n --font-size: 14px;\n --border-radius: 50px;\n --border-color: #000;\n --background-color: #fff;\n --hover-color: #007bff;\n --placeholder-color: #999;\n --placeholder-font: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;\n --input-color: #000;\n --input-font: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;\n }\n\n :host([height="small"]) {\n --height: 32px;\n }\n\n :host([height="medium"]) {\n --height: 48px;\n }\n\n :host([height="large"]) {\n --height: 64px;\n }\n\n .flex-container {\n display: block;\n flex-direction: column;\n width: fit-content;\n height: fit-content;\n position: relative;\n }\n\n .searchbar-wrapper {\n display: flex;\n flex-direction: row;\n align-items: center;\n border-radius: var(--border-radius);\n border: var(--border-width) solid var(--border-color);\n background-color: var(--background-color);\n width: var(--width);\n height: var(--height);\n margin: 1px;\n }\n\n .searchbar-wrapper:hover {\n border-color: var(--hover-color);\n }\n\n .searchbar-wrapper:focus-within {\n border-width: calc(var(--border-width) + 1px);\n border-color: var(--hover-color);\n margin: 0px;\n }\n\n :host([icon-pos="end"]) .searchbar-wrapper {\n flex-direction: row-reverse;\n }\n\n .search-button {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 10px;\n padding: 0;\n transition: background-color 0.2s;\n }\n\n .search-button:hover {\n background-color: rgba(0, 0, 0, 0.05);\n }\n\n .search-icon {\n width: var(--font-size);\n height: var(--font-size);\n fill: currentColor;\n }\n\n .input-container {\n position: relative;\n flex-grow: 1;\n display: flex;\n align-items: center;\n height: 100%;\n }\n\n .animated-placeholder {\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--placeholder-color);\n font-family: var(--placeholder-font);\n font-size: var(--font-size);\n pointer-events: none;\n transition: all 0.2s ease;\n background-color: transparent;\n padding: 0 4px;\n border-radius: 4px;\n z-index: 5;\n }\n\n .input-container.focused .animated-placeholder,\n .input-container.has-value .animated-placeholder {\n top: -12px;\n font-size: calc(var(--font-size) * 0.75);\n color: var(--placeholder-color);\n background-color: transparent;\n }\n\n .dropdown {\n position: absolute;\n font-size: var(--font-size);\n font-family: var(--input-font);\n top: calc(100% + 4px);\n left: 0;\n max-height: 200px;\n width: 100%;\n background: white;\n border: 1px solid transparent;\n border-radius: 4px;\n display: none;\n z-index: 10;\n overflow-y: auto;\n overflow-x: hidden;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n }\n\n .dropdown-item {\n padding: 8px 14px;\n cursor: pointer;\n border-left: 3px solid transparent;\n transition:\n background-color 0.1s,\n border-color 0.1s;\n }\n .dropdown-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n }\n .dropdown-item.highlighted {\n background-color: rgba(0, 0, 0, 0.08);\n border-left-color: var(--hover-color);\n }\n\n wavelength-input {\n flex-grow: 1;\n width: 100%;\n height: 100%;\n }\n</style>\n\n<div class="flex-container">\n <div class="searchbar-wrapper">\n <button class="search-button search-icon">\n <svg\n version="1.1"\n id="_x32_"\n xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink"\n viewBox="0 0 512 512"\n xml:space="preserve"\n fill="#000000"\n style="width: 100%; height: 100%"\n >\n <g id="SVGRepo_bgCarrier" stroke-width="0"></g>\n <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>\n <g id="SVGRepo_iconCarrier">\n <style type="text/css">\n .st0 {\n fill: #000000;\n }\n </style>\n <g>\n <path\n class="st0"\n d="M312.069,53.445c-71.26-71.26-187.194-71.26-258.454,0c-71.261,71.26-71.261,187.206,0,258.466 c71.26,71.26,187.194,71.26,258.454,0S383.329,124.705,312.069,53.445z M286.694,286.536 c-57.351,57.34-150.353,57.34-207.704-0.011s-57.351-150.353,0-207.693c57.351-57.351,150.342-57.351,207.693,0 S344.045,229.174,286.694,286.536z"\n ></path>\n <path\n class="st0"\n d="M101.911,112.531c-29.357,37.725-31.801,89.631-7.321,129.702c1.877,3.087,5.902,4.048,8.978,2.182 c3.065-1.888,4.037-5.903,2.16-8.978c-21.666-35.456-19.506-81.538,6.469-114.876c2.226-2.837,1.713-6.938-1.135-9.154 C108.227,109.193,104.125,109.695,101.911,112.531z"\n ></path>\n <path\n class="st0"\n d="M498.544,447.722l-132.637-129.2c-7.255-7.07-18.84-6.982-26.008,0.174l-21.033,21.033 c-7.156,7.156-7.234,18.742-0.153,25.986l129.19,132.636c14.346,17.324,35.542,18.35,51.917,1.964 C516.216,483.951,515.857,462.068,498.544,447.722z"\n ></path>\n </g>\n </g>\n </svg>\n </button>\n <div class="input-container" id="inputContainer">\n <label class="animated-placeholder" id="animatedPlaceholder">Search...</label>\n <wavelength-input\n focus-color="transparent"\n background-color="transparent"\n border-color="transparent"\n label=""\n id="searchInput"\n placeholder=""\n validation-type="onBlur"\n min-length="0"\n clearable\n height="100%"\n padding="0 10px"\n ></wavelength-input>\n <div id="dropdown" class="dropdown"></div>\n </div>\n </div>\n</div>\n';
6525
+
6526
+ // src/web-components/wavelength-search.ts
6527
+ var WavelengthSearch = class extends HTMLElement {
6528
+ constructor() {
6529
+ super();
6530
+ this.options = [];
6531
+ this.highlightedIndex = -1;
6532
+ this.styleAttributes = [
6533
+ "width",
6534
+ "height",
6535
+ "font-size",
6536
+ "border-width",
6537
+ "border-radius",
6538
+ "border-color",
6539
+ "background-color",
6540
+ "hover-color",
6541
+ "placeholder-color",
6542
+ "placeholder-font",
6543
+ "input-color",
6544
+ "input-font"
6545
+ ];
6546
+ this.handleFocusIn = () => {
6547
+ this.inputContainer.classList.add("focused");
6548
+ };
6549
+ this.handleFocusOut = () => {
6550
+ this.inputContainer.classList.remove("focused");
6551
+ };
6552
+ this.handleInputChange = (e) => {
6553
+ const mode = this.getAttribute("mode") || "automatic";
6554
+ const value = e.detail.value;
6555
+ if (value) {
6556
+ this.inputContainer.classList.add("has-value");
6557
+ } else {
6558
+ this.inputContainer.classList.remove("has-value");
6559
+ }
6560
+ if (mode === "automatic") {
6561
+ if (this.searchTimeout) {
6562
+ clearTimeout(this.searchTimeout);
6563
+ }
6564
+ this.searchTimeout = setTimeout(() => {
6565
+ this.handleSearch(value);
6566
+ }, 300);
6567
+ }
6568
+ };
6569
+ this.handleKeydown = (e) => {
6570
+ const isDropdownVisible = this.dropdown.style.display === "block";
6571
+ const items = this.dropdown.querySelectorAll(".dropdown-item");
6572
+ if (e.key === "ArrowDown") {
6573
+ e.preventDefault();
6574
+ if (!isDropdownVisible) {
6575
+ this.handleSearch(this.input.value);
6576
+ } else if (items.length > 0) {
6577
+ this.highlightedIndex = (this.highlightedIndex + 1) % items.length;
6578
+ this.updateHighlight(items);
6579
+ }
6580
+ } else if (e.key === "ArrowUp") {
6581
+ e.preventDefault();
6582
+ if (isDropdownVisible && items.length > 0) {
6583
+ this.highlightedIndex = this.highlightedIndex <= 0 ? items.length - 1 : this.highlightedIndex - 1;
6584
+ this.updateHighlight(items);
6585
+ }
6586
+ } else if (e.key === "Escape" || e.key === "Tab") {
6587
+ this.dropdown.style.display = "none";
6588
+ this.highlightedIndex = -1;
6589
+ if (e.key === "Escape") {
6590
+ this.input.focus();
6591
+ }
6592
+ } else if (e.key === "Enter") {
6593
+ if (isDropdownVisible && this.highlightedIndex >= 0 && this.highlightedIndex < items.length) {
6594
+ e.preventDefault();
6595
+ this.selectOption(items[this.highlightedIndex].textContent || "");
6596
+ } else {
6597
+ const value = this.input.value;
6598
+ this.dispatchEvent(new CustomEvent("wavelength-search-submit", { detail: { value }, bubbles: true, composed: true }));
6599
+ this.handleSearch(value);
6600
+ }
6601
+ }
6602
+ };
6603
+ this.handleSearchIconClick = () => {
6604
+ const value = this.input.value;
6605
+ this.dispatchEvent(new CustomEvent("wavelength-search-submit", { detail: { value }, bubbles: true, composed: true }));
6606
+ this.handleSearch(value);
6607
+ };
6608
+ this.handleDocumentClick = (e) => {
6609
+ if (!this.contains(e.target)) {
6610
+ this.dropdown.style.display = "none";
6611
+ this.highlightedIndex = -1;
6612
+ }
6613
+ };
6614
+ this.shadow = this.attachShadow({ mode: "open" });
6615
+ this.shadow.innerHTML = wavelength_search_template_default;
6616
+ }
6617
+ static get observedAttributes() {
6618
+ return [
6619
+ "width",
6620
+ "height",
6621
+ "mode",
6622
+ "font-size",
6623
+ "border-width",
6624
+ "border-radius",
6625
+ "border-color",
6626
+ "background-color",
6627
+ "hover-color",
6628
+ "options",
6629
+ "placeholder",
6630
+ "icon-pos",
6631
+ "placeholder-color",
6632
+ "placeholder-font",
6633
+ "input-color",
6634
+ "input-font"
6635
+ ];
6636
+ }
6637
+ connectedCallback() {
6638
+ this._syncStyles();
6639
+ this.input = this.shadow.getElementById("searchInput");
6640
+ this.dropdown = this.shadow.getElementById("dropdown");
6641
+ this.inputContainer = this.shadow.getElementById("inputContainer");
6642
+ this.animatedPlaceholder = this.shadow.getElementById("animatedPlaceholder");
6643
+ if (!this.hasAttribute("icon-pos")) {
6644
+ this.setAttribute("icon-pos", "end");
6645
+ }
6646
+ if (!this.hasAttribute("height")) {
6647
+ this.setAttribute("height", "small");
6648
+ }
6649
+ const placeholder = this.getAttribute("placeholder") || "Search...";
6650
+ this.animatedPlaceholder.textContent = placeholder;
6651
+ const searchIcon = this.shadow.querySelector(".search-icon");
6652
+ this.input.addEventListener("focusin", this.handleFocusIn);
6653
+ this.input.addEventListener("focusout", this.handleFocusOut);
6654
+ this.input.addEventListener("inputChange", this.handleInputChange);
6655
+ this.input.addEventListener("keydown", this.handleKeydown);
6656
+ if (searchIcon) {
6657
+ searchIcon.addEventListener("click", this.handleSearchIconClick);
6658
+ }
6659
+ document.addEventListener("click", this.handleDocumentClick);
6660
+ }
6661
+ disconnectedCallback() {
6662
+ this.input.removeEventListener("focusin", this.handleFocusIn);
6663
+ this.input.removeEventListener("focusout", this.handleFocusOut);
6664
+ this.input.removeEventListener("inputChange", this.handleInputChange);
6665
+ this.input.removeEventListener("keydown", this.handleKeydown);
6666
+ const searchIcon = this.shadow.querySelector(".search-icon");
6667
+ if (searchIcon) {
6668
+ searchIcon.removeEventListener("click", this.handleSearchIconClick);
6669
+ }
6670
+ document.removeEventListener("click", this.handleDocumentClick);
6671
+ }
6672
+ attributeChangedCallback(name, oldValue, newValue) {
6673
+ if (oldValue === newValue) return;
6674
+ if (this.styleAttributes.includes(name)) {
6675
+ if (name === "height") {
6676
+ if (["small", "medium", "large"].includes(newValue || "")) {
6677
+ this.style.removeProperty("--height");
6678
+ } else if (newValue !== null) {
6679
+ this.style.setProperty("--height", newValue);
6680
+ } else {
6681
+ this.style.removeProperty("--height");
6682
+ }
6683
+ } else {
6684
+ if (newValue !== null) {
6685
+ this.style.setProperty(`--${name}`, newValue);
6686
+ } else {
6687
+ this.style.removeProperty(`--${name}`);
6688
+ }
6689
+ }
6690
+ }
6691
+ if (name === "options" && newValue) {
6692
+ try {
6693
+ this.options = JSON.parse(newValue);
6694
+ } catch (e) {
6695
+ this.options = newValue.split(",").map((s) => s.trim());
6696
+ }
6697
+ } else if (name === "placeholder" && this.animatedPlaceholder) {
6698
+ this.animatedPlaceholder.textContent = newValue || "Search...";
6699
+ } else if (name === "font-size" && this.input) {
6700
+ this.input.setAttribute("font-size", newValue || "");
6701
+ } else if (name === "input-color" && this.input) {
6702
+ this.input.setAttribute("text-color", newValue || "");
6703
+ } else if (name === "input-font" && this.input) {
6704
+ this.input.setAttribute("font-family", newValue || "");
6705
+ }
6706
+ }
6707
+ handleSearch(query) {
6708
+ if (this.searchTimeout) {
6709
+ clearTimeout(this.searchTimeout);
6710
+ this.searchTimeout = null;
6711
+ }
6712
+ if (!query) {
6713
+ this.dropdown.style.display = "none";
6714
+ return;
6715
+ }
6716
+ const results = this.options.filter((option) => option.toLowerCase().includes(query.toLowerCase()));
6717
+ this.highlightedIndex = -1;
6718
+ this.renderDropdown(results);
6719
+ }
6720
+ renderDropdown(results) {
6721
+ if (results.length === 0) {
6722
+ this.dropdown.style.display = "none";
6723
+ return;
6724
+ }
6725
+ this.dropdown.innerHTML = results.map((r) => `<div class="dropdown-item">${r}</div>`).join("");
6726
+ this.dropdown.style.display = "block";
6727
+ const items = this.dropdown.querySelectorAll(".dropdown-item");
6728
+ items.forEach((item, index) => {
6729
+ item.addEventListener("click", () => {
6730
+ this.selectOption(item.textContent || "");
6731
+ });
6732
+ item.addEventListener("mouseenter", () => {
6733
+ this.highlightedIndex = index;
6734
+ this.updateHighlight(items);
6735
+ });
6736
+ });
6737
+ this.updateHighlight(items);
6738
+ }
6739
+ selectOption(value) {
6740
+ this.input.value = value;
6741
+ this.dropdown.style.display = "none";
6742
+ this.highlightedIndex = -1;
6743
+ this.dispatchEvent(new CustomEvent("wavelength-search-select", { detail: { value }, bubbles: true, composed: true }));
6744
+ }
6745
+ // ---- Getters and Setters API ---- //
6746
+ get value() {
6747
+ return this.input.value;
6748
+ }
6749
+ set value(val) {
6750
+ this.input.value = val;
6751
+ }
6752
+ get optionsList() {
6753
+ return this.options;
6754
+ }
6755
+ set optionsList(val) {
6756
+ if (val) {
6757
+ this.options = val;
6758
+ this.setAttribute("options", JSON.stringify(val));
6759
+ }
6760
+ }
6761
+ _syncStyles() {
6762
+ this.styleAttributes.forEach((attr) => {
6763
+ const value = this.getAttribute(attr);
6764
+ if (value) {
6765
+ if (attr === "height" && ["small", "medium", "large"].includes(value)) {
6766
+ } else {
6767
+ this.style.setProperty(`--${attr}`, value);
6768
+ }
6769
+ }
6770
+ });
6771
+ }
6772
+ updateHighlight(items) {
6773
+ items.forEach((item, index) => {
6774
+ const isHighlighted = index === this.highlightedIndex;
6775
+ item.classList.toggle("highlighted", isHighlighted);
6776
+ if (isHighlighted) {
6777
+ item.scrollIntoView({ block: "nearest" });
6778
+ }
6779
+ });
6780
+ }
6781
+ };
6782
+ if (!customElements.get("wavelength-search")) {
6783
+ customElements.define("wavelength-search", WavelengthSearch);
6784
+ }
6347
6785
  export {
6348
6786
  BaseWavelengthInput,
6349
6787
  BaseWavelengthMultiSelectAutocomplete,
@@ -6362,8 +6800,10 @@ export {
6362
6800
  WavelengthMultiSelectAutocomplete,
6363
6801
  WavelengthNavBar,
6364
6802
  WavelengthNotificationPanel,
6803
+ WavelengthPagination,
6365
6804
  WavelengthPlaneTrail,
6366
6805
  WavelengthProgressBar,
6806
+ WavelengthSearch,
6367
6807
  WavelengthSnackbar,
6368
6808
  WavelengthTitleBar,
6369
6809
  WavelengthToolTip
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@wavelengthusaf/web-components",
3
3
  "author": "563 EWS - Wavelength",
4
4
  "license": "MIT",
5
- "version": "1.10.0",
5
+ "version": "1.13.0",
6
6
  "description": "Common component library used by Wavelength developers (NATIVE WEB COMPONENTS)",
7
7
  "main": "/dist/cjs/index.cjs",
8
8
  "module": "/dist/esm/index.js",