@dropins/storefront-quick-order 0.0.1-alpha1 → 0.1.2-alpha2

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.
Files changed (45) hide show
  1. package/api/getStoreConfig/getStoreConfig.d.ts +22 -0
  2. package/api/getStoreConfig/graphql/getStoreConfig.graphql.d.ts +18 -0
  3. package/api/getStoreConfig/index.d.ts +18 -0
  4. package/api/index.d.ts +1 -0
  5. package/api/initialize/initialize.d.ts +1 -0
  6. package/api.js +1 -1
  7. package/api.js.map +1 -1
  8. package/chunks/QuickOrderDisabledOverlay.js +4 -0
  9. package/chunks/QuickOrderDisabledOverlay.js.map +1 -0
  10. package/chunks/initialize.js +10 -0
  11. package/chunks/initialize.js.map +1 -0
  12. package/components/QuickOrderDisabledOverlay/QuickOrderDisabledOverlay.d.ts +5 -0
  13. package/components/QuickOrderDisabledOverlay/index.d.ts +19 -0
  14. package/components/QuickOrderNotificationBanner/QuickOrderNotificationBanner.d.ts +5 -0
  15. package/components/QuickOrderNotificationBanner/index.d.ts +19 -0
  16. package/components/index.d.ts +2 -0
  17. package/containers/QuickOrderCsvUpload.js +2 -2
  18. package/containers/QuickOrderCsvUpload.js.map +1 -1
  19. package/containers/QuickOrderItems.js +1 -1
  20. package/containers/QuickOrderItems.js.map +1 -1
  21. package/containers/QuickOrderMultipleSku.js +1 -1
  22. package/containers/QuickOrderMultipleSku.js.map +1 -1
  23. package/hooks/index.d.ts +1 -0
  24. package/hooks/useQuickOrderItems.d.ts +1 -1
  25. package/hooks/useSearch.d.ts +27 -0
  26. package/i18n/en_US.json.d.ts +10 -2
  27. package/lib/fetch-error.d.ts +21 -0
  28. package/lib/index.d.ts +1 -0
  29. package/lib/isItemValid.d.ts +9 -0
  30. package/lib/network-error.d.ts +22 -0
  31. package/lib/searchKeyboardNavigation.d.ts +19 -12
  32. package/lib/validateOrderItems.d.ts +28 -0
  33. package/package.json +1 -1
  34. package/render.js +2 -3
  35. package/render.js.map +1 -1
  36. package/types/index.d.ts +2 -0
  37. package/types/quickOrderCsvUpload.types.d.ts +3 -2
  38. package/types/quickOrderDisabledOverlay.types.d.ts +22 -0
  39. package/types/quickOrderItems.types.d.ts +16 -4
  40. package/types/quickOrderMultipleSku.types.d.ts +1 -0
  41. package/types/quickOrderNotificationBanner.types.d.ts +33 -0
  42. package/chunks/CsvFileInput.js +0 -4
  43. package/chunks/CsvFileInput.js.map +0 -1
  44. package/chunks/Search.js +0 -4
  45. package/chunks/Search.js.map +0 -1
@@ -15,4 +15,32 @@ export declare const getOutOfStockItems: (items: OrderItem[]) => Array<{
15
15
  sku: string;
16
16
  name: string;
17
17
  }>;
18
+ /**
19
+ * Get items with missing required options
20
+ * @param items - Array of order items to check
21
+ * @returns Array of items missing required options
22
+ */
23
+ export declare const getItemsMissingOptions: (items: OrderItem[]) => Array<{
24
+ sku: string;
25
+ name: string;
26
+ }>;
27
+ /**
28
+ * Get items with incomplete data
29
+ * @param items - Array of order items to check
30
+ * @returns Array of items with incomplete data
31
+ */
32
+ export declare const getItemsWithIncompleteData: (items: OrderItem[]) => Array<{
33
+ sku: string;
34
+ name: string;
35
+ }>;
36
+ /**
37
+ * Get all items with validation errors
38
+ * @param items - Array of order items to check
39
+ * @returns Array of all items with validation errors and their SKUs
40
+ */
41
+ export declare const getInvalidItems: (items: OrderItem[]) => Array<{
42
+ sku: string;
43
+ name: string;
44
+ reason: string;
45
+ }>;
18
46
  //# sourceMappingURL=validateOrderItems.d.ts.map
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name": "@dropins/storefront-quick-order", "version": "0.0.1-alpha1", "@dropins/tools": "~1.6.0", "license": "SEE LICENSE IN LICENSE.md"}
1
+ {"name": "@dropins/storefront-quick-order", "version": "0.1.2-alpha2", "@dropins/tools": "~1.7.0", "license": "SEE LICENSE IN LICENSE.md"}
package/render.js CHANGED
@@ -1,6 +1,5 @@
1
1
  /*! Copyright 2026 Adobe
2
2
  All Rights Reserved. */
3
- (function(i,t){try{if(typeof document<"u"){const r=document.createElement("style"),a=t.styleId;for(const e in t.attributes)r.setAttribute(e,t.attributes[e]);r.setAttribute("data-dropin",a),r.appendChild(document.createTextNode(i));const o=document.querySelector('style[data-dropin="sdk"]');if(o)o.after(r);else{const e=document.querySelector('link[rel="stylesheet"], style');e?e.before(r):document.head.append(r)}}}catch(r){console.error("dropin-styles (injectCodeFunction)",r)}})(`.b2b-quick-order-quick-order-multiple-sku{display:flex;flex-direction:column;gap:var(--grid-1-gutters)}.b2b-quick-order-sku-list-input__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing);margin-bottom:var(--spacing-small)}.b2b-quick-order-sku-list-input__textarea{margin-bottom:var(--spacing-xsmall)}.b2b-quick-order-sku-list-input__message{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);margin-bottom:var(--spacing-xsmall);text-align:left}.b2b-quick-order-form-quick-order-items-list{width:100%}.b2b-quick-order-form-quick-order-items-list__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing);margin-bottom:var(--spacing-small)}.b2b-quick-order-form-quick-order-items-list__empty{color:var(--color-neutral-600);font:var(--type-body-1-font);letter-spacing:var(--type-body-1-letter-spacing);text-align:center;padding:var(--spacing-large)}.b2b-quick-order-form-quick-order-items-list__actions{display:flex;justify-content:flex-start;margin-top:var(--spacing-medium)}.b2b-quick-order-form-quick-order-items-list__warning{background-color:var(--color-warning-200, #fef3cd);border:1px solid var(--color-warning-500, #ff9800);border-radius:var(--shape-border-radius-2);padding:var(--spacing-medium);margin-bottom:var(--spacing-medium)}.b2b-quick-order-form-quick-order-items-list__warning-title{color:var(--color-warning-800, #e65100);font:var(--type-body-1-strong-font);letter-spacing:var(--type-body-1-strong-letter-spacing);margin-bottom:var(--spacing-xsmall)}.b2b-quick-order-form-quick-order-items-list__warning-description{color:var(--color-warning-700, #f57c00);font:var(--type-body-2-font);letter-spacing:var(--type-body-2-letter-spacing)}.b2b-quick-order-form-quick-order-items-list .dropin-divider--secondary{border-width:var(--shape-border-width-3);margin-top:0}@media screen and (max-width: 1285px){.b2b-quick-order-form-quick-order-items-list .dropin-divider--secondary{display:none}}.b2b-quick-order-form-quick-order-items__item-form{min-height:170px}.b2b-quick-order-form-quick-order-items__item-form .dropin-accordion-section__content-container{margin-bottom:0}.b2b-quick-order-form-quick-order-items__item-form:last-child{margin-bottom:var(--spacing-medium)}.b2b-quick-order-list-item__accordion .dropin-accordion-section__title{color:var(--color-neutral-800);font:var(--type-body-2-default-font);letter-spacing:var(--type-body-2-default-letter-spacing)}.b2b-quick-order-items__error{color:var(--color-alert-800);font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing)}.b2b-quick-order-form-quick-order-items__item-search{margin-bottom:var(--spacing-big)}.b2b-quick-order-items__configurable-error{color:var(--color-alert-500);font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing)}.b2b-quick-order-search{position:relative;width:100%}.b2b-quick-order-search__input{width:100%}.b2b-quick-order-search__results{position:absolute;top:100%;left:0;right:0;background-color:var(--color-neutral-50);border:var(--shape-border-width-1) solid var(--color-neutral-300);border-radius:var(--spacing-xxsmall);margin-top:var(--spacing-xxsmall);max-height:300px;overflow-y:auto;z-index:10;box-shadow:0 2px 8px #0000001a}.b2b-quick-order-search__result-item{padding:var(--spacing-xsmall) var(--spacing-small);cursor:pointer;transition:background-color .2s}.b2b-quick-order-search__result-item:hover,.b2b-quick-order-search__result-item--active{background-color:var(--color-neutral-100)}.b2b-quick-order-search__result-item:focus{outline:2px solid var(--color-brand-500);outline-offset:-2px}.b2b-quick-order-search__result-item:not(:last-child){border-bottom:var(--shape-border-width-1) solid var(--color-neutral-200)}.b2b-quick-order-search__empty-state{position:absolute;top:100%;left:0;right:0;z-index:10;text-align:center;background-color:var(--color-neutral-50);border:var(--shape-border-width-1) solid var(--color-neutral-300);border-radius:var(--shape-border-radius-1);margin-top:var(--spacing-xxsmall);padding:var(--spacing-small);color:var(--color-neutral-600);box-shadow:0 2px 8px #0000001a}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}
4
- .b2b-quick-order-csv-file-input{display:flex;flex-direction:column;gap:var(--grid-1-gutters)}.b2b-quick-order-csv-file-input__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing)}.b2b-quick-order-csv-file-input__helper{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);text-align:left}.b2b-quick-order-csv-file-input__download-link{color:var(--color-informational-800);text-decoration:underline;background:none;border:none;padding:0;cursor:pointer;font-size:inherit}.b2b-quick-order-csv-file-input__download-link:hover{color:var(--color-informational-500)}.b2b-quick-order-csv-file-input__input{margin-top:var(--spacing-xsmall);width:max-content}.b2b-quick-order-csv-file-input__input--loading{cursor:not-allowed;opacity:.3}.b2b-quick-order-csv-file-input__file-name{font:var(--type-body-2-default-font);letter-spacing:var(--type-body-2-default-letter-spacing)}.b2b-quick-order-csv-file-input__error{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);padding-top:var(--spacing-xsmall);text-align:left;color:var(--color-alert-800)}`,{styleId:"b2b-quick-order"});
5
- import{jsx as o}from"@dropins/tools/preact-jsx-runtime.js";import{Render as n}from"@dropins/tools/lib.js";import{useState as s,useEffect as l}from"@dropins/tools/preact-hooks.js";import{UIProvider as d}from"@dropins/tools/components.js";import{events as u}from"@dropins/tools/event-bus.js";const c={Search:{placeholder:"Search by SKU...",ariaLabel:"Search for products by SKU",emptyState:"No results found",resultsAvailable:"results available",resultAvailable:"result available",srInstructions:"Use arrow keys or Tab to navigate, Enter or Space to select, Escape to close."},SkuListInput:{title:"Add Products by SKU",helperText:"Use commas or paragraphs to separate SKUs.",textArea:{label:"Enter Multiple SKUs",placeholder:"Enter SKUs here..."},button:"Add to List"},CsvFileInput:{title:"Add from File",helperText:'File must be in .csv format and include "SKU" and "QTY" columns ',downloadSample:"Download sample",inputLabel:"Choose File",selectedFile:"Selected file",uploadCSVErrors:{invalidFile:"Invalid CSV file",emptyFile:"File is empty",missingColumns:'Must contain "SKU" and "QTY" columns',extraColumns:'Must contain only "SKU" and "QTY" columns',maxRowsExceeded:"File exceeds maximum of {maxRows} rows",skuRequired:"Row {rowNumber}: SKU is required",invalidQuantity:"Row {rowNumber}: QTY must be a positive integer",noValidData:"File contains no valid data rows",onlyCSV:"Only CSV files are allowed",failedToRead:"Failed to read file",failedToParse:"Failed to parse CSV file"}},QuickOrderItem:{title:"Enter SKU or search by Product Name",quantity:"Quantity: ",price:"Price: ",sku:"SKU",remove:"Remove",removeItem:"Remove item",showOptions:"Show additional options",hideOptions:"Hide additional options",additionalOptions:"Additional options",noAdditionalOptions:"No additional options available",emptyList:"No products in the list",loading:"Loading...",productNotFound:"Product not found",productNotFoundDescription:"The product with SKU {sku} could not be found",configurableProductError:"Configuration required",configurableProductErrorDescription:"Configurable products aren’t supported here. Use the correct component for products with options. ",configurableOptionsWarning:"Product configuration required",configurableOptionsWarningDescription:"Please select all required product options before adding to cart",productOptions:"Product Options",outOfStock:"Out of Stock",addAllToCart:"Add to Cart"}},p={QuickOrder:c},m={default:p},f=({children:t})=>{const[r,i]=s("en_US");return l(()=>{const e=u.on("locale",a=>{i(a)},{eager:!0});return()=>{e==null||e.off()}},[]),o(d,{lang:r,langDefinitions:m,children:t})},U=new n(o(f,{}));export{U as render};
3
+ (function(i,o){try{if(typeof document<"u"){const r=document.createElement("style"),a=o.styleId;for(const e in o.attributes)r.setAttribute(e,o.attributes[e]);r.setAttribute("data-dropin",a),r.appendChild(document.createTextNode(i));const t=document.querySelector('style[data-dropin="sdk"]');if(t)t.after(r);else{const e=document.querySelector('link[rel="stylesheet"], style');e?e.before(r):document.head.append(r)}}}catch(r){console.error("dropin-styles (injectCodeFunction)",r)}})(".b2b-quick-order-quick-order-multiple-sku{display:flex;flex-direction:column;gap:var(--grid-1-gutters)}.b2b-quick-order-sku-list-input__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing);margin-bottom:var(--spacing-small)}.b2b-quick-order-sku-list-input__textarea{margin-bottom:var(--spacing-xsmall)}.b2b-quick-order-sku-list-input__message{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);margin-bottom:var(--spacing-xsmall);text-align:left}.b2b-quick-order-csv-file-input{display:flex;flex-direction:column;gap:var(--grid-1-gutters)}.b2b-quick-order-csv-file-input__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing)}.b2b-quick-order-csv-file-input__helper{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);text-align:left}.b2b-quick-order-csv-file-input__download-link{color:var(--color-informational-800);text-decoration:underline;background:none;border:none;padding:0;cursor:pointer;font-size:inherit}.b2b-quick-order-csv-file-input__download-link:hover{color:var(--color-informational-500)}.b2b-quick-order-csv-file-input__input-wrapper{margin-top:var(--spacing-xsmall);width:max-content}.b2b-quick-order-csv-file-input__input{width:100%}.b2b-quick-order-csv-file-input__input-wrapper--disabled button,.b2b-quick-order-csv-file-input__input-wrapper--disabled label,.b2b-quick-order-csv-file-input__input-wrapper--disabled .dropin-button{background:var(--color-neutral-300) 0 0% no-repeat padding-box!important;color:var(--color-neutral-500)!important;fill:var(--color-neutral-300)!important;pointer-events:none;-webkit-user-select:none;user-select:none;cursor:not-allowed!important}.b2b-quick-order-csv-file-input__input:has(input:disabled) button,.b2b-quick-order-csv-file-input__input:has(input:disabled) label{background:var(--color-neutral-300) 0 0% no-repeat padding-box;color:var(--color-neutral-500);fill:var(--color-neutral-300);pointer-events:none;-webkit-user-select:none;user-select:none;cursor:not-allowed}.b2b-quick-order-csv-file-input__input--loading{cursor:not-allowed;opacity:.3}.b2b-quick-order-csv-file-input__file-name{font:var(--type-body-2-default-font);letter-spacing:var(--type-body-2-default-letter-spacing)}.b2b-quick-order-csv-file-input__error{font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing);padding-top:var(--spacing-xsmall);text-align:left;color:var(--color-alert-800)}.b2b-quick-order-form-quick-order-items-list{width:100%}.b2b-quick-order-form-quick-order-items-list__title{color:var(--color-neutral-800);font:var(--type-headline-2-font);letter-spacing:var(--type-headline-2-letter-spacing);margin-bottom:var(--spacing-small)}.b2b-quick-order-form-quick-order-items-list__empty{color:var(--color-neutral-600);font:var(--type-body-1-font);letter-spacing:var(--type-body-1-letter-spacing);text-align:center;padding:var(--spacing-large)}.b2b-quick-order-form-quick-order-items-list__actions{display:flex;justify-content:flex-start;margin-top:var(--spacing-medium)}.b2b-quick-order-form-quick-order-items-list__warning{background-color:var(--color-warning-200, #fef3cd);border:1px solid var(--color-warning-500, #ff9800);border-radius:var(--shape-border-radius-2);padding:var(--spacing-medium);margin-bottom:var(--spacing-medium)}.b2b-quick-order-form-quick-order-items-list__warning-title{color:var(--color-warning-800, #e65100);font:var(--type-body-1-strong-font);letter-spacing:var(--type-body-1-strong-letter-spacing);margin-bottom:var(--spacing-xsmall)}.b2b-quick-order-form-quick-order-items-list__warning-description{color:var(--color-warning-700, #f57c00);font:var(--type-body-2-font);letter-spacing:var(--type-body-2-letter-spacing)}.b2b-quick-order-form-quick-order-items-list .dropin-divider--secondary{border-width:var(--shape-border-width-3);margin-top:0}@media screen and (max-width: 1285px){.b2b-quick-order-form-quick-order-items-list .dropin-divider--secondary{display:none}}.b2b-quick-order-form-quick-order-items-list__actions--disabled{background-color:red}.b2b-quick-order-form-quick-order-items__item-form{min-height:170px}.b2b-quick-order-form-quick-order-items__item-form .dropin-accordion-section__content-container{margin-bottom:0}.b2b-quick-order-form-quick-order-items__item-form:last-child{margin-bottom:var(--spacing-medium)}.b2b-quick-order-list-item__accordion .dropin-accordion-section__title{color:var(--color-neutral-800);font:var(--type-body-2-default-font);letter-spacing:var(--type-body-2-default-letter-spacing)}.b2b-quick-order-items__error{color:var(--color-alert-800);font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing)}.b2b-quick-order-form-quick-order-items__item-search{margin-bottom:var(--spacing-big)}.b2b-quick-order-items__configurable-error{color:var(--color-alert-500);font:var(--type-details-caption-2-font);letter-spacing:var(--type-details-caption-2-letter-spacing)}.b2b-quick-order-search{position:relative;width:100%}.b2b-quick-order-search__input{width:100%}.b2b-quick-order-search__results{position:absolute;top:100%;left:0;right:0;background-color:var(--color-neutral-50);border:var(--shape-border-width-1) solid var(--color-neutral-300);border-radius:var(--spacing-xxsmall);margin-top:var(--spacing-xxsmall);max-height:300px;overflow-y:auto;z-index:10;box-shadow:0 2px 8px #0000001a}.b2b-quick-order-search__result-item{padding:var(--spacing-xsmall) var(--spacing-small);cursor:pointer;transition:background-color .2s,outline .2s}.b2b-quick-order-search__result-item:hover{background-color:var(--color-neutral-100)}.b2b-quick-order-search__result-item--active,.b2b-quick-order-search__result-item[aria-selected=true]{background-color:var(--color-neutral-100);outline:2px solid var(--color-brand-500);outline-offset:-2px}.b2b-quick-order-search__result-item:not(:last-child){border-bottom:var(--shape-border-width-1) solid var(--color-neutral-200)}.b2b-quick-order-search__empty-state{position:absolute;top:100%;left:0;right:0;z-index:10;text-align:center;background-color:var(--color-neutral-50);border:var(--shape-border-width-1) solid var(--color-neutral-300);border-radius:var(--shape-border-radius-1);margin-top:var(--spacing-xxsmall);padding:var(--spacing-small);color:var(--color-neutral-600);box-shadow:0 2px 8px #0000001a}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.b2b-quick-order-notification-banner{margin-bottom:20px}.b2b-quick-order-notification-banner .dropin-alert-banner__message{max-width:500px}.b2b-quick-order-notification-banner--warning .dropin-alert-banner{background-color:var(--color-warning-500)}.b2b-quick-order-notification-banner--success .dropin-alert-banner{background-color:var(--color-positive-500)}.b2b-quick-order-notification-banner--neutral .dropin-alert-banner{background-color:var(--color-neutral-600)}.b2b-quick-order-notification-banner--brand .dropin-alert-banner{background-color:var(--color-brand-500)}.b2b-quick-order-disabled-overlay{position:relative}.b2b-quick-order-disabled-overlay__blur{position:absolute;top:0;right:0;bottom:0;left:0;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background-color:#ffffffb3;z-index:1}.b2b-quick-order-disabled-overlay__message{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:2;font-size:16px;font-weight:500;color:#666;text-align:center;padding:20px}",{styleId:"b2b-quick-order"});
4
+ import{jsx as o}from"@dropins/tools/preact-jsx-runtime.js";import{Render as n}from"@dropins/tools/lib.js";import{useState as d,useEffect as s}from"@dropins/tools/preact-hooks.js";import{UIProvider as l}from"@dropins/tools/components.js";import{events as u}from"@dropins/tools/event-bus.js";const c={Search:{placeholder:"Search by SKU...",ariaLabel:"Search for products by SKU",emptyState:"No results found",resultsAvailable:"results available",resultAvailable:"result available",srInstructions:"Use arrow keys or Tab to navigate, Enter or Space to select, Escape to close."},SkuListInput:{title:"Add Products by SKU",helperText:"Use commas or paragraphs to separate SKUs.",textArea:{label:"Enter Multiple SKUs",placeholder:"Enter SKUs here..."},button:"Add to List"},CsvFileInput:{title:"Add from File",helperText:'File must be in .csv format and include "SKU" and "QTY" columns ',downloadSample:"Download sample",inputLabel:"Choose File",selectedFile:"Selected file",uploadCSVErrors:{invalidFile:"Invalid CSV file",emptyFile:"File is empty",missingColumns:'Must contain "SKU" and "QTY" columns',extraColumns:'Must contain only "SKU" and "QTY" columns',maxRowsExceeded:"File exceeds maximum of {maxRows} rows",skuRequired:"Row {rowNumber}: SKU is required",invalidQuantity:"Row {rowNumber}: QTY must be a positive integer",noValidData:"File contains no valid data rows",onlyCSV:"Only CSV files are allowed",failedToRead:"Failed to read file",failedToParse:"Failed to parse CSV file"}},QuickOrderItem:{title:"Enter SKU or search by Product Name",quantity:"Quantity: ",price:"Price: ",sku:"SKU",remove:"Remove",removeItem:"Remove item",showOptions:"Show additional options",hideOptions:"Hide additional options",additionalOptions:"Additional options",noAdditionalOptions:"No additional options available",emptyList:"No products in the list",loading:"Loading...",productNotFound:"Product not found",productNotFoundDescription:"The product with SKU {sku} could not be found",configurableProductError:"Configuration required",configurableProductErrorDescription:"Use ProductOptions Slot in QuickOrderItems container to enable configurable product options.",configurableOptionsWarning:"Product configuration required",configurableOptionsWarningDescription:"Please select all required product options before adding to cart",productOptions:"Product Options",outOfStock:"Out of Stock",addAllToCart:"Add to Cart",disabledMessage:"Quick Order feature disabled",notification:{validationError:"Product(s) require(s) your attention",backendError:"An error occurred while adding products to the cart",success:"{count} product(s) successfully added to the cart",partialSuccess:"{count} of {total} products were added to the cart. Some products could not be added",unexpectedError:"An unexpected error has occurred"}}},p={QuickOrder:c},m={default:p},f=({children:t})=>{const[r,i]=d("en_US");return s(()=>{const e=u.on("locale",a=>{i(a)},{eager:!0});return()=>{e==null||e.off()}},[]),o(l,{lang:r,langDefinitions:m,children:t})},U=new n(o(f,{}));export{U as render};
6
5
  //# sourceMappingURL=render.js.map
package/render.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sources":["/@dropins/storefront-quick-order/src/render/Provider.tsx","/@dropins/storefront-quick-order/src/render/render.tsx"],"sourcesContent":["import { FunctionComponent } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { UIProvider } from '@adobe-commerce/elsie/components';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { events } from '@adobe-commerce/event-bus';\n\nimport en_US from '../i18n/en_US.json';\n\n// Langs\nconst langDefinitions = {\n default: en_US,\n};\n\ninterface CartProviderProps {\n children?: any;\n}\n\nexport const Provider: FunctionComponent<CartProviderProps> = ({\n children,\n}) => {\n const [lang, setLang] = useState<Lang>('en_US');\n\n // Events\n useEffect(() => {\n const localeEvent = events.on(\n 'locale',\n (locale: string) => {\n setLang(locale as Lang);\n },\n { eager: true }\n );\n return () => {\n localeEvent?.off();\n };\n }, []);\n\n return (\n <UIProvider lang={lang} langDefinitions={langDefinitions}>\n {children}\n </UIProvider>\n );\n};\n","import { Render } from '@adobe-commerce/elsie/lib';\nimport { Provider } from './Provider';\n\nexport const render = new Render(<Provider />);\n"],"names":["langDefinitions","en_US","Provider","children","lang","setLang","useState","useEffect","localeEvent","events","locale","jsx","UIProvider","render","Render"],"mappings":"u4EASMA,EAAkB,CACtB,QAASC,CACX,EAMaC,EAAiD,CAAC,CAC7D,SAAAC,CACF,IAAM,CACJ,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAe,OAAO,EAG9C,OAAAC,EAAU,IAAM,CACd,MAAMC,EAAcC,EAAO,GACzB,SACCC,GAAmB,CAClBL,EAAQK,CAAc,CACxB,EACA,CAAE,MAAO,EAAA,CAAK,EAEhB,MAAO,IAAM,CACXF,GAAA,MAAAA,EAAa,KACf,CACF,EAAG,CAAA,CAAE,EAGHG,EAACC,EAAA,CAAW,KAAAR,EAAY,gBAAAJ,EACrB,SAAAG,CAAA,CACH,CAEJ,ECtCaU,EAAS,IAAIC,EAAOH,EAACT,IAAS,CAAE"}
1
+ {"version":3,"file":"render.js","sources":["/@dropins/storefront-quick-order/src/render/Provider.tsx","/@dropins/storefront-quick-order/src/render/render.tsx"],"sourcesContent":["import { FunctionComponent } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { UIProvider } from '@adobe-commerce/elsie/components';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { events } from '@adobe-commerce/event-bus';\n\nimport en_US from '../i18n/en_US.json';\n\n// Langs\nconst langDefinitions = {\n default: en_US,\n};\n\ninterface CartProviderProps {\n children?: any;\n}\n\nexport const Provider: FunctionComponent<CartProviderProps> = ({\n children,\n}) => {\n const [lang, setLang] = useState<Lang>('en_US');\n\n // Events\n useEffect(() => {\n const localeEvent = events.on(\n 'locale',\n (locale: string) => {\n setLang(locale as Lang);\n },\n { eager: true }\n );\n return () => {\n localeEvent?.off();\n };\n }, []);\n\n return (\n <UIProvider lang={lang} langDefinitions={langDefinitions}>\n {children}\n </UIProvider>\n );\n};\n","import { Render } from '@adobe-commerce/elsie/lib';\nimport { Provider } from './Provider';\n\nexport const render = new Render(<Provider />);\n"],"names":["langDefinitions","en_US","Provider","children","lang","setLang","useState","useEffect","localeEvent","events","locale","jsx","UIProvider","render","Render"],"mappings":"mwFASMA,EAAkB,CACtB,QAASC,CACX,EAMaC,EAAiD,CAAC,CAC7D,SAAAC,CACF,IAAM,CACJ,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAe,OAAO,EAG9C,OAAAC,EAAU,IAAM,CACd,MAAMC,EAAcC,EAAO,GACzB,SACCC,GAAmB,CAClBL,EAAQK,CAAc,CACxB,EACA,CAAE,MAAO,EAAA,CAAK,EAEhB,MAAO,IAAM,CACXF,GAAA,MAAAA,EAAa,KACf,CACF,EAAG,CAAA,CAAE,EAGHG,EAACC,EAAA,CAAW,KAAAR,EAAY,gBAAAJ,EACrB,SAAAG,CAAA,CACH,CAEJ,ECtCaU,EAAS,IAAIC,EAAOH,EAACT,IAAS,CAAE"}
package/types/index.d.ts CHANGED
@@ -18,4 +18,6 @@ export * from './quickOrderMultipleSku.types';
18
18
  export * from './quickOrderCsvUpload.types';
19
19
  export * from './quickOrderItems.types';
20
20
  export * from './search.types';
21
+ export * from './quickOrderNotificationBanner.types';
22
+ export * from './quickOrderDisabledOverlay.types';
21
23
  //# sourceMappingURL=index.d.ts.map
@@ -2,7 +2,7 @@ import { SubmitSkuValue } from './quickOrderMultipleSku.types';
2
2
 
3
3
  export interface QuickOrderCsvUploadProps {
4
4
  className?: string;
5
- routeSampleCSV?: string;
5
+ routeSampleCSV?: () => string;
6
6
  onFileUpload?: (values: SubmitSkuValue) => void;
7
7
  }
8
8
  export interface CsvFileInputProps {
@@ -12,9 +12,10 @@ export interface CsvFileInputProps {
12
12
  fileName: string | null;
13
13
  onDownloadSample: () => void;
14
14
  showSampleDownload: boolean;
15
+ disabled?: boolean;
15
16
  }
16
17
  export interface UseQuickOrderCsvUploadProps {
17
- routeSampleCSV?: string;
18
+ routeSampleCSV?: () => string;
18
19
  onFileUpload?: (values: SubmitSkuValue) => void;
19
20
  }
20
21
  export interface UseQuickOrderCsvUploadReturn {
@@ -0,0 +1,22 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export interface QuickOrderDisabledOverlayProps {
18
+ isDisabled: boolean;
19
+ message: string;
20
+ children: any;
21
+ }
22
+ //# sourceMappingURL=quickOrderDisabledOverlay.types.d.ts.map
@@ -3,6 +3,7 @@ import { SearchItem } from './search.types';
3
3
 
4
4
  export type AddAllToCartContext = {
5
5
  handleAddToCart: (() => void) | undefined;
6
+ clearItems: (() => void) | undefined;
6
7
  loading?: boolean;
7
8
  isDisabledButton?: boolean;
8
9
  };
@@ -18,8 +19,8 @@ export type QuickOrderItemSearchContext = {
18
19
  export type QuickOrderSearchAutocompleteItemContext<T extends SearchItem = SearchItem> = {
19
20
  item: T;
20
21
  index: number;
22
+ activeIndex: number;
21
23
  createItemClickHandler: (item: T) => () => void;
22
- createResultItemKeyDownHandler: (index: number, item: T) => (e: KeyboardEvent) => void;
23
24
  };
24
25
  export type ProductPriceContext = {
25
26
  item: OrderItem;
@@ -116,7 +117,7 @@ export interface QuickOrderItemsProps {
116
117
  }) => Promise<{
117
118
  items: OrderItem[];
118
119
  }>;
119
- onAddAllToCart?: (items: any[]) => void | Promise<void>;
120
+ handleAddToCart?: (items: any[], clearItems: () => void) => void | string | Promise<void | string>;
120
121
  searchFilter?: Array<{
121
122
  attribute: string;
122
123
  in: string[];
@@ -126,7 +127,7 @@ export interface QuickOrderItemsProps {
126
127
  ProductPrice?: SlotProps<ProductPriceContext>;
127
128
  ProductOptions?: SlotProps<ProductOptionsContext>;
128
129
  QuickOrderItemSearch?: SlotProps<QuickOrderItemSearchContext>;
129
- QuickOrderSearchAutocompleteItem?: SlotProps<QuickOrderSearchAutocompleteItemContext<SearchItem>>;
130
+ QuickOrderSearchAutocompleteItem?: SlotProps<QuickOrderSearchAutocompleteItemContext<OrderItem>>;
130
131
  };
131
132
  }
132
133
  export interface QuickOrderItemProps {
@@ -168,6 +169,7 @@ export interface QuickOrderItemsListProps {
168
169
  t: Record<string, string>;
169
170
  items: OrderItem[];
170
171
  onRemove: (sku: string) => void;
172
+ clearItems?: () => void;
171
173
  onUpdateQuantity?: (sku: string, quantity: number) => void;
172
174
  handleAddToCart?: () => void;
173
175
  isItemUpdating?: (sku: string) => boolean;
@@ -196,10 +198,20 @@ export interface UseQuickOrderItemsReturn {
196
198
  items: OrderItem[];
197
199
  loading: boolean;
198
200
  removeItem: (sku: string) => void;
201
+ clearItems: () => void;
199
202
  updateItemQuantity: (sku: string, quantity: number) => void;
200
- handleAddToCart: () => void;
203
+ addToCart: () => void;
201
204
  isItemUpdating: (sku: string) => boolean;
202
205
  isDisabledButton: boolean;
203
206
  setDisabledCartButton: (disabled: boolean) => void;
207
+ notification: {
208
+ type: 'validation' | 'partial-success' | 'success' | 'backend-error';
209
+ variant: 'success' | 'warning' | 'neutral' | 'brand';
210
+ message: string;
211
+ details?: string;
212
+ count?: number;
213
+ clickableSkus?: string[];
214
+ } | null;
215
+ dismissNotification: () => void;
204
216
  }
205
217
  //# sourceMappingURL=quickOrderItems.types.d.ts.map
@@ -21,6 +21,7 @@ export interface SkuListInputProps {
21
21
  onChange: (e: Event) => void;
22
22
  textAreaValue: string;
23
23
  loading: boolean;
24
+ disabled?: boolean;
24
25
  }
25
26
  export interface UseQuickOrderMultipleSkuProps extends Omit<QuickOrderMultipleSkuProps, 'className'> {
26
27
  }
@@ -0,0 +1,33 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export interface QuickOrderNotificationBannerProps {
18
+ notification: {
19
+ type: 'validation' | 'partial-success' | 'success' | 'backend-error';
20
+ variant: 'success' | 'warning' | 'neutral' | 'brand';
21
+ message: string;
22
+ details?: string;
23
+ count?: number;
24
+ clickableSkus?: string[];
25
+ } | null;
26
+ onDismiss: () => void;
27
+ onSkuClick?: (sku: string) => void;
28
+ validationErrorText: string;
29
+ backendErrorText: string;
30
+ successText: string;
31
+ partialSuccessText?: string;
32
+ }
33
+ //# sourceMappingURL=quickOrderNotificationBanner.types.d.ts.map
@@ -1,4 +0,0 @@
1
- /*! Copyright 2026 Adobe
2
- All Rights Reserved. */
3
- import{jsxs as t,jsx as i,Fragment as p}from"@dropins/tools/preact-jsx-runtime.js";import{memo as m,useCallback as b}from"@dropins/tools/preact-compat.js";import{InputFile as v}from"@dropins/tools/components.js";const f=({t:e,onFileUpload:l,error:s,fileName:a,onDownloadSample:c,showSampleDownload:d})=>{const o=b(u=>{var r;const n=(r=u.target.files)==null?void 0:r[0];n&&l(n)},[l]);return t("div",{className:"b2b-quick-order-csv-file-input",children:[i("div",{className:"b2b-quick-order-csv-file-input__title",children:e.title}),t("div",{className:"b2b-quick-order-csv-file-input__helper",children:[e.helperText,d&&i(p,{children:i("button",{type:"button",className:"b2b-quick-order-csv-file-input__download-link",onClick:c,"data-testid":"download-sample",children:e.downloadSample})})]}),i(v,{id:"quick-order-csv-file-input",label:e.inputLabel,className:"b2b-quick-order-csv-file-input__input",onChange:o,accept:".csv"}),a&&t("div",{className:"b2b-quick-order-csv-file-input__file-name","data-testid":"file-name",children:[e.selectedFile,": ",a]}),s&&i("div",{className:"b2b-quick-order-csv-file-input__error","data-testid":"error-message",role:"alert",children:s})]})},N=m(f);export{N as C};
4
- //# sourceMappingURL=CsvFileInput.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CsvFileInput.js","sources":["/@dropins/storefront-quick-order/src/components/CsvFileInput/CsvFileInput.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent, useCallback, memo } from 'preact/compat';\nimport { InputFile } from '@adobe-commerce/elsie/components';\nimport { CsvFileInputProps } from '@/b2b-quick-order/types/quickOrderCsvUpload.types';\nimport '@/b2b-quick-order/components/CsvFileInput/CsvFileInput.css';\n\nconst CsvFileInputComponent: FunctionComponent<CsvFileInputProps> = ({\n t,\n onFileUpload,\n error,\n fileName,\n onDownloadSample,\n showSampleDownload,\n}) => {\n const handleFileChange = useCallback(\n (e: Event) => {\n const target = e.target as HTMLInputElement;\n const file = target.files?.[0];\n if (file) {\n onFileUpload(file);\n }\n },\n [onFileUpload]\n );\n\n const inputClassName = 'b2b-quick-order-csv-file-input__input';\n\n return (\n <div className=\"b2b-quick-order-csv-file-input\">\n <div className=\"b2b-quick-order-csv-file-input__title\">{t.title}</div>\n\n <div className=\"b2b-quick-order-csv-file-input__helper\">\n {t.helperText}\n {showSampleDownload && (\n <>\n <button\n type=\"button\"\n className=\"b2b-quick-order-csv-file-input__download-link\"\n onClick={onDownloadSample}\n data-testid=\"download-sample\"\n >\n {t.downloadSample}\n </button>\n </>\n )}\n </div>\n\n <InputFile\n id={'quick-order-csv-file-input'}\n label={t.inputLabel}\n className={inputClassName}\n onChange={handleFileChange}\n accept={'.csv'}\n />\n\n {fileName && (\n <div\n className=\"b2b-quick-order-csv-file-input__file-name\"\n data-testid=\"file-name\"\n >\n {t.selectedFile}: {fileName}\n </div>\n )}\n\n {error && (\n <div\n className=\"b2b-quick-order-csv-file-input__error\"\n data-testid=\"error-message\"\n role=\"alert\"\n >\n {error}\n </div>\n )}\n </div>\n );\n};\n\nexport const CsvFileInput = memo(CsvFileInputComponent);\n"],"names":["CsvFileInputComponent","t","onFileUpload","error","fileName","onDownloadSample","showSampleDownload","handleFileChange","useCallback","e","file","_a","jsxs","jsx","Fragment","InputFile","CsvFileInput","memo"],"mappings":"oNAsBA,MAAMA,EAA8D,CAAC,CACnE,EAAAC,EACA,aAAAC,EACA,MAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,mBAAAC,CACF,IAAM,CACJ,MAAMC,EAAmBC,EACtBC,GAAa,OAEZ,MAAMC,GAAOC,EADEF,EAAE,OACG,QAAP,YAAAE,EAAe,GACxBD,GACFR,EAAaQ,CAAI,CAErB,EACA,CAACR,CAAY,CAAA,EAKf,OACEU,EAAC,MAAA,CAAI,UAAU,iCACb,SAAA,CAAAC,EAAC,MAAA,CAAI,UAAU,wCAAyC,SAAAZ,EAAE,MAAM,EAEhEW,EAAC,MAAA,CAAI,UAAU,yCACZ,SAAA,CAAAX,EAAE,WACFK,GACCO,EAAAC,EAAA,CACE,SAAAD,EAAC,SAAA,CACC,KAAK,SACL,UAAU,gDACV,QAASR,EACT,cAAY,kBAEX,SAAAJ,EAAE,cAAA,CAAA,CACL,CACF,CAAA,EAEJ,EAEAY,EAACE,EAAA,CACC,GAAI,6BACJ,MAAOd,EAAE,WACT,UAzBiB,wCA0BjB,SAAUM,EACV,OAAQ,MAAA,CAAA,EAGTH,GACCQ,EAAC,MAAA,CACC,UAAU,4CACV,cAAY,YAEX,SAAA,CAAAX,EAAE,aAAa,KAAGG,CAAA,CAAA,CAAA,EAItBD,GACCU,EAAC,MAAA,CACC,UAAU,wCACV,cAAY,gBACZ,KAAK,QAEJ,SAAAV,CAAA,CAAA,CACH,EAEJ,CAEJ,EAEaa,EAAeC,EAAKjB,CAAqB"}
package/chunks/Search.js DELETED
@@ -1,4 +0,0 @@
1
- /*! Copyright 2026 Adobe
2
- All Rights Reserved. */
3
- import{jsxs as $,jsx as s,Fragment as Z}from"@dropins/tools/preact-jsx-runtime.js";import{memo as j,useMemo as M,useCallback as D,useState as H,useRef as g,useEffect as z}from"@dropins/tools/preact-compat.js";import{CartList as U,Divider as C,Button as ee,CartItem as G,AccordionSection as re,Input as te}from"@dropins/tools/components.js";import{Slot as L}from"@dropins/tools/lib.js";import{useState as K,useRef as ae,useEffect as J,useMemo as se,useCallback as Q}from"@dropins/tools/preact-hooks.js";import{events as ce}from"@dropins/tools/event-bus.js";import"./CsvFileInput.js";const W=e=>e.reduce((r,a)=>{if(!a)return r;if(typeof a=="string"&&(r+=` ${a}`),Array.isArray(a)){const[h,b]=a;h&&b&&(r+=` ${h}`)}return r},"").trim(),ue=(e,t)=>{let r;return function(...a){clearTimeout(r),r=setTimeout(()=>e.apply(this,a),t)}},ne=[{attribute:"visibility",in:["Search","Catalog, Search"]}],oe=e=>{const{containerRef:t,itemSelected:r,initialValue:a,currentValue:h,onValueRestore:b,onClose:n}=e,m=document.activeElement;(t==null?void 0:t.contains(m))||(n(),!r&&a!==h&&b(a))},le=(e,t=150)=>window.setTimeout(()=>{oe(e)},t),I=e=>{e&&clearTimeout(e)},ie=(e,t,r)=>{const a=e<t-1?e+1:e;return{nextIndex:a,shouldFocusElement:r[a]||null,shouldPreventDefault:!0}},de=(e,t,r)=>{const a=e>0?e-1:-1;return{nextIndex:a,shouldFocusElement:a===-1?t:r[a],shouldPreventDefault:!0}},fe=(e,t,r)=>e>=0&&t[e]?(r(t[e]),!0):!1,he=(e,t,r,a)=>{r(e),a(),t&&"blur"in t&&typeof t.blur=="function"&&t.blur()},O=e=>{e&&"focus"in e&&typeof e.focus=="function"&&e.focus()},X=({productsSearch:e,initialSku:t,replaceItemSku:r,searchFilter:a=ne})=>{const[h,b]=K(t),[n,m]=K([]),[u,i]=K(!1),l=ae(!0);J(()=>()=>{l.current=!1},[]),J(()=>{u||b(t)},[t,u]);const N=se(()=>ue(async o=>{if(!o||!e){l.current&&m([]);return}try{const d=await e({phrase:o,filter:a});l.current&&m(d.items||[])}catch(d){console.error("Error searching products:",d),l.current&&m([])}},300),[e,a]),A=Q(o=>{const S=o.target.value;b(S),i(!0),N(S)},[N]),v=Q(()=>{b(""),m([]),i(!1)},[]),E=Q(o=>{const d={sku:o.sku,...o.variantSku&&{variantSku:o.variantSku},quantity:1,...r&&{replaceItemSku:r}};ce.emit("quick-order/add-items",[d]),v()},[r,v]);return{searchValue:h,searchResults:n,handleSearchChange:A,shouldShowResults:u,resetSearch:v,handleItemClick:E}},pe=({t:e,items:t,onRemove:r,onUpdateQuantity:a,slots:h,handleAddToCart:b,isItemUpdating:n,loading:m,isDisabledButton:u,productsSearch:i,searchFilter:l})=>{const{searchValue:N,searchResults:A,handleSearchChange:v,shouldShowResults:E,handleItemClick:o}=X({productsSearch:i,initialSku:"",searchFilter:l});return $("div",{className:W(["b2b-quick-order-form-quick-order-items-list"]),role:"region","aria-label":e.title,children:[s("div",{className:"b2b-quick-order-form-quick-order-items-list__title",children:e.title}),t.length>0&&$(Z,{children:[s(U,{role:"list",className:"b2b-quick-order-form-quick-order-items-list__list",children:t.map(d=>s(me,{item:d,t:e,onRemove:r,onUpdateQuantity:a,isUpdating:n==null?void 0:n(d.sku),loading:m,productsSearch:i,searchFilter:l,slots:h},d.sku))}),s(C,{variant:"secondary"})]}),s("div",{className:"b2b-quick-order-form-quick-order-items-list__global-search",children:s(Y,{t:e,onChange:v,items:A,value:N,shouldShowResults:E,onItemClick:o,className:"b2b-quick-order-form-quick-order-items-list__search",slots:h})}),t.length===0&&s("div",{className:"b2b-quick-order-form-quick-order-items-list__empty","data-testid":"empty-items",children:e.emptyList}),s(L,{slot:h==null?void 0:h.AddAllToCartButton,name:"AddAllToCartButton",context:{handleAddToCart:b,loading:m,isDisabledButton:u},"data-testid":"addAllToCart",children:s("div",{className:"b2b-quick-order-form-quick-order-items-list__actions",children:s(ee,{variant:"primary",onClick:b,"data-testid":"add-all-to-cart-button",disabled:m||u,children:e.addAllToCart})})})]})},De=j(pe),be=({item:e,t,onRemove:r,onUpdateQuantity:a,isUpdating:h,loading:b,productsSearch:n,searchFilter:m,slots:u})=>{var B,x;const i=`quick-order-item-${e.id||e.variantSku||e.sku}`,l=(e==null?void 0:e.variantSku)??(e==null?void 0:e.sku),{searchValue:N,searchResults:A,handleSearchChange:v,shouldShowResults:E,handleItemClick:o}=X({productsSearch:n,initialSku:l,replaceItemSku:e.sku,searchFilter:m}),d=`form-${e.id||l}`,S=e.inStock&&e.addToCartAllowed,y=e.options&&e.options.length>0,T=M(()=>y&&e.options.some(f=>f.required),[y,e.options]),_=M(()=>y&&e.options.some(f=>f.items&&f.items.some(w=>w.selected)),[y,e.options]),R=M(()=>T?e.options.every(f=>f.required?f.items&&f.items.some(w=>w.selected):!0):_,[T,_,e.options]),q=M(()=>{var f;return(f=e.images)==null?void 0:f.find(w=>{var c;return(c=w.roles)==null?void 0:c.includes("image")})},[e.images]),V=D(()=>{r==null||r(e.id||e.sku)},[r,e.id,e.sku]),F=D(f=>{a==null||a(e.sku,f);const w=document.forms[d];if(w){const c=w.querySelector('input[name="quantity"]');c&&(c.value=String(f))}},[a,e.sku,d]),P=s(L,{name:"QuickOrderItemSearch",slot:u==null?void 0:u.QuickOrderItemSearch,context:{item:e,scope:i,handleSearchChange:v,searchResults:A,searchValue:N,shouldShowResults:E,handleItemClick:o},children:s(Y,{t,onChange:v,items:A,value:N,shouldShowResults:E,className:"b2b-quick-order-form-quick-order-items__item-search",onItemClick:o,slots:u})});return!e.name&&!((B=e.images)!=null&&B.length)?$("form",{name:d,className:"b2b-quick-order-form-quick-order-items__item-form",onSubmit:f=>f.preventDefault(),children:[s("input",{type:"hidden",name:"sku",value:e.sku}),s("input",{type:"hidden",name:"quantity",value:e.quantity}),s("input",{type:"hidden",name:"valid",value:"false"}),s("input",{type:"hidden",name:"productType",value:""}),P,s(G,{sku:s("span",{children:e.sku}),title:s("span",{children:t.productNotFound}),quantity:e.quantity,alert:s("div",{className:"b2b-quick-order-items__error",children:(x=t.productNotFoundDescription)==null?void 0:x.replace("{sku}",e.sku)}),disabled:b,onRemove:V,ariaLabel:`${t.productNotFound} - ${e.sku}`})]},e.sku):$("form",{name:d,className:"b2b-quick-order-form-quick-order-items__item-form",onSubmit:f=>f.preventDefault(),children:[s("input",{type:"hidden",name:"sku",value:l}),s("input",{type:"hidden",name:"quantity",value:e.quantity}),s("input",{type:"hidden",name:"valid",value:S?"true":"false"}),s("input",{type:"hidden",name:"productType",value:e.productType||""}),P,s(G,{title:s("span",{children:e.name}),sku:s("span",{children:l}),image:q?s("img",{src:q.url,alt:q.label||e.name}):void 0,price:s(L,{name:"ProductPrice",slot:u==null?void 0:u.ProductPrice,context:{item:e,scope:i}}),quantity:e.quantity,alert:e.inStock===!1?s("div",{className:"b2b-quick-order-items__alert",children:t.outOfStock}):void 0,warning:y&&!R?s("div",{className:"b2b-quick-order-items__warning",children:t.configurableOptionsWarning}):void 0,footer:y?s(re,{title:t.productOptions,ariaLabelTitle:t.productOptions,defaultOpen:!R,className:"b2b-quick-order-list-item__accordion",actionIconPosition:"left",children:s(L,{name:"ProductOptions",slot:u==null?void 0:u.ProductOptions,context:{item:e,scope:i},children:s("div",{className:"b2b-quick-order-items__configurable-error",children:t.configurableProductErrorDescription})})}):void 0,updating:h,disabled:b,loading:b,onRemove:V,onQuantity:F,ariaLabel:`${e.name} - ${e.sku}`})]},l)},me=j(be),ke={cursor:"pointer"},ve={cursor:"default"},ye=({t:e,value:t,onChange:r,items:a,shouldShowResults:h=!0,className:b,onItemClick:n,slots:m})=>{const[u,i]=H(-1),[l,N]=H(""),[A,v]=H(!1),[E,o]=H(!1),d=g(`search-results-${Math.random().toString(36).substr(2,9)}`),S=g(null),y=g([]),T=g(null),_=g(null),R=!!t&&!E,q=h&&R&&a.length>0,V=h&&R&&a.length===0;z(()=>{i(-1)},[a]),z(()=>()=>{I(_.current)},[]);const F=D(c=>()=>{v(!0),o(!0),n==null||n(c),i(-1)},[n]),P=D(()=>{I(_.current),_.current=null,N(t||""),v(!1),o(!1)},[t]),B=D(()=>{_.current=le({containerRef:T.current,itemSelected:A,initialValue:l,currentValue:t||"",onValueRestore:c=>{r==null||r({target:{value:c}})},onClose:()=>{o(!0)}})},[A,l,t,r]),x=D(c=>{if(q)switch(c.key){case"ArrowDown":c.preventDefault(),i(k=>{const p=ie(k,a.length,y.current);return p.shouldFocusElement&&O(p.shouldFocusElement),p.nextIndex});break;case"ArrowUp":c.preventDefault(),i(k=>{const p=de(k,S.current,y.current);return p.shouldFocusElement&&O(p.shouldFocusElement),p.nextIndex});break;case"Tab":I(_.current),_.current=null,o(!0),r==null||r({target:{value:l}});break;case"Enter":{fe(u,a,p=>{v(!0),n==null||n(p),i(-1)})&&c.preventDefault();break}case"Escape":c.preventDefault(),he(l,S.current,k=>{r==null||r({target:{value:k}}),i(-1),o(!0)},()=>{o(!0)});break}},[q,a,u,n,r,l]),f=D(()=>{if(u>=0&&q)return`${d.current}-item-${u}`},[u,q]),w=D((c,k)=>p=>{switch(p.key){case"Enter":case" ":p.preventDefault(),v(!0),o(!0),n==null||n(k),i(-1),O(S.current);break;case"Escape":p.preventDefault(),i(-1),o(!0),r==null||r({target:{value:l}}),O(S.current);break;case"ArrowDown":p.preventDefault(),c<a.length-1&&(i(c+1),O(y.current[c+1]));break;case"ArrowUp":p.preventDefault(),c>0?(i(c-1),O(y.current[c-1])):(i(-1),O(S.current));break;case"Tab":I(_.current),_.current=null,o(!0),r==null||r({target:{value:l}});break}},[a,n,r,l]);return $("div",{ref:T,className:W(["b2b-quick-order-search",b]),children:[s(te,{ref:S,className:"b2b-quick-order-search__input",value:t,onChange:r,onFocus:P,onBlur:B,placeholder:e.searchPlaceholder,"aria-label":e.searchAriaLabel,role:"combobox","aria-autocomplete":"list","aria-expanded":q?!0:void 0,"aria-controls":q?d.current:void 0,"aria-activedescendant":f(),onKeyDown:x}),q&&s("div",{id:d.current,role:"listbox",className:"b2b-quick-order-search__results","aria-label":e.searchAriaLabel,children:a.map((c,k)=>s(L,{slot:m==null?void 0:m.QuickOrderSearchAutocompleteItem,name:"QuickOrderSearchAutocompleteItem",context:{item:c,index:k,createItemClickHandler:F,createResultItemKeyDownHandler:w},children:s("div",{id:`${d.current}-item-${k}`,ref:p=>y.current[k]=p,role:"option",tabIndex:0,"aria-selected":k===u,className:W(["b2b-quick-order-search__result-item",k===u&&"b2b-quick-order-search__result-item--active"]),onClick:F(c),onKeyDown:w(k,c),style:n?ke:ve,children:`${c.sku} ${c.name}`})},c.sku))}),V&&s("div",{className:"b2b-quick-order-search__empty-state",role:"status","aria-live":"polite",children:e.searchEmptyState}),q&&$("div",{className:"sr-only",role:"status","aria-live":"polite","aria-atomic":"true",children:[a.length," ",a.length===1?e.resultAvailable:e.resultsAvailable,"."," ",e.srInstructions]})]})},Y=j(ye);export{De as Q,W as c,ue as d};
4
- //# sourceMappingURL=Search.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Search.js","sources":["../../node_modules/@adobe-commerce/elsie/src/lib/classes.ts","../../node_modules/@adobe-commerce/elsie/src/lib/debounce.ts","/@dropins/storefront-quick-order/src/configs/search-filter.config.ts","/@dropins/storefront-quick-order/src/lib/searchBlurHandler.ts","/@dropins/storefront-quick-order/src/lib/searchKeyboardNavigation.ts","/@dropins/storefront-quick-order/src/hooks/useItemSearch.tsx","/@dropins/storefront-quick-order/src/components/QuickOrderItemsList/QuickOrderItemsList.tsx","/@dropins/storefront-quick-order/src/components/QuickOrderListItem/QuickOrderListItem.tsx","/@dropins/storefront-quick-order/src/components/Search/Search.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\n// @ts-ignore\nimport { JSXInternal } from 'preact/src/jsx';\n\ntype ClassName = string | JSXInternal.SignalLike<string | undefined>;\n\nexport const classes = (\n classes: Array<ClassName | [ClassName, boolean] | undefined>\n) => {\n const result = classes.reduce((result, item) => {\n if (!item) return result;\n\n if (typeof item === 'string') result += ` ${item}`;\n\n if (Array.isArray(item)) {\n const [className, isActive] = item;\n if (className && isActive) {\n result += ` ${className}`;\n }\n }\n\n return result;\n }, '') as string;\n\n return result.trim();\n};\n","/********************************************************************\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nexport const debounce = (fn: Function, ms: number) => {\n let timeoutId: ReturnType<typeof setTimeout>;\n return function (this: any, ...args: any[]) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn.apply(this, args), ms);\n };\n};\n","export const SEARCH_FILTER = [\n {\n attribute: 'visibility',\n in: ['Search', 'Catalog, Search'],\n },\n];\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nexport interface BlurHandlerOptions {\n containerRef: HTMLElement | null;\n itemSelected: boolean;\n initialValue: string;\n currentValue: string;\n onValueRestore: (value: string) => void;\n onClose: () => void;\n}\n\n/**\n * Handles blur logic for search component\n * Checks if focus moved outside component and restores initial value if needed\n */\nexport const handleSearchBlur = (options: BlurHandlerOptions): void => {\n const {\n containerRef,\n itemSelected,\n initialValue,\n currentValue,\n onValueRestore,\n onClose,\n } = options;\n\n const activeElement = document.activeElement;\n const isWithinComponent = containerRef?.contains(activeElement);\n\n if (!isWithinComponent) {\n onClose();\n\n if (!itemSelected && initialValue !== currentValue) {\n onValueRestore(initialValue);\n }\n }\n};\n\n/**\n * Creates a blur handler with timeout\n */\nexport const createBlurHandler = (\n options: BlurHandlerOptions,\n delay: number = 150\n): number => {\n return window.setTimeout(() => {\n handleSearchBlur(options);\n }, delay);\n};\n\n/**\n * Clears blur timeout if exists\n */\nexport const clearBlurTimeout = (timeoutRef: number | null): void => {\n if (timeoutRef) {\n clearTimeout(timeoutRef);\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nexport interface KeyboardNavigationResult {\n nextIndex: number;\n shouldFocusElement?: HTMLElement | null;\n shouldPreventDefault: boolean;\n}\n\n/**\n * Calculates next active index when ArrowDown is pressed\n */\nexport const handleArrowDown = (\n currentIndex: number,\n itemsLength: number,\n itemRefs: (HTMLElement | null)[]\n): KeyboardNavigationResult => {\n const nextIndex =\n currentIndex < itemsLength - 1 ? currentIndex + 1 : currentIndex;\n\n return {\n nextIndex,\n shouldFocusElement: itemRefs[nextIndex] || null,\n shouldPreventDefault: true,\n };\n};\n\n/**\n * Calculates next active index when ArrowUp is pressed\n */\nexport const handleArrowUp = (\n currentIndex: number,\n inputRef: HTMLElement | null,\n itemRefs: (HTMLElement | null)[]\n): KeyboardNavigationResult => {\n const nextIndex = currentIndex > 0 ? currentIndex - 1 : -1;\n\n return {\n nextIndex,\n shouldFocusElement: nextIndex === -1 ? inputRef : itemRefs[nextIndex],\n shouldPreventDefault: true,\n };\n};\n\n/**\n * Handles Enter key press on active item\n */\nexport const handleEnterKey = <T>(\n activeIndex: number,\n items: T[],\n onItemSelect: (item: T) => void\n): boolean => {\n if (activeIndex >= 0 && items[activeIndex]) {\n onItemSelect(items[activeIndex]);\n return true;\n }\n return false;\n};\n\n/**\n * Handles Escape key press\n */\nexport const handleEscapeKey = (\n initialValue: string,\n inputRef: HTMLElement | null,\n onValueRestore: (value: string) => void,\n onClose: () => void\n): void => {\n onValueRestore(initialValue);\n onClose();\n if (inputRef && 'blur' in inputRef && typeof inputRef.blur === 'function') {\n inputRef.blur();\n }\n};\n\n/**\n * Focuses an element if it exists and has focus method\n */\nexport const focusElement = (element: HTMLElement | null): void => {\n if (element && 'focus' in element && typeof element.focus === 'function') {\n element.focus();\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport {\n useCallback,\n useState,\n useMemo,\n useRef,\n useEffect,\n} from 'preact/hooks';\nimport { debounce } from '@adobe-commerce/elsie/lib/debounce';\nimport { OrderItem, UseItemSearchProps } from '@/b2b-quick-order/types';\nimport { events } from '@adobe-commerce/event-bus';\nimport { SEARCH_FILTER } from '@/b2b-quick-order/configs';\n\nexport const useItemSearch = ({\n productsSearch,\n initialSku,\n replaceItemSku,\n searchFilter = SEARCH_FILTER,\n}: UseItemSearchProps) => {\n const [searchValue, setSearchValue] = useState(initialSku);\n const [searchResults, setSearchResults] = useState<OrderItem[]>([]);\n const [isTouched, setIsTouched] = useState(false);\n\n // Track if component is mounted to prevent state updates after unmount\n const isMountedRef = useRef(true);\n\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // Update search value when initialSku changes (e.g., after merge)\n useEffect(() => {\n if (!isTouched) {\n setSearchValue(initialSku);\n }\n }, [initialSku, isTouched]);\n\n const debouncedSearch = useMemo(\n () =>\n debounce(async (searchTerm: string) => {\n if (!searchTerm || !productsSearch) {\n if (isMountedRef.current) {\n setSearchResults([]);\n }\n return;\n }\n\n try {\n const result = await productsSearch({\n phrase: searchTerm,\n filter: searchFilter,\n });\n if (isMountedRef.current) {\n setSearchResults(result.items || []);\n }\n } catch (error) {\n console.error('Error searching products:', error);\n if (isMountedRef.current) {\n setSearchResults([]);\n }\n }\n }, 300),\n [productsSearch, searchFilter]\n );\n\n const handleSearchChange = useCallback(\n (e: Event) => {\n const target = e.target as HTMLInputElement;\n const value = target.value;\n setSearchValue(value);\n setIsTouched(true);\n debouncedSearch(value);\n },\n [debouncedSearch]\n );\n\n const resetSearch = useCallback(() => {\n setSearchValue('');\n setSearchResults([]);\n setIsTouched(false);\n }, []);\n\n const handleItemClick = useCallback(\n (clickedItem: OrderItem) => {\n // Build item data for emission\n // Just send the data as-is from the search result\n // The deduplication logic will handle matching correctly\n const itemData = {\n sku: clickedItem.sku,\n ...(clickedItem.variantSku && { variantSku: clickedItem.variantSku }),\n quantity: 1,\n ...(replaceItemSku && { replaceItemSku }),\n };\n\n events.emit('quick-order/add-items', [itemData]);\n resetSearch();\n },\n [replaceItemSku, resetSearch]\n );\n\n return {\n searchValue,\n searchResults,\n handleSearchChange,\n shouldShowResults: isTouched,\n resetSearch,\n handleItemClick,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent, memo } from 'preact/compat';\nimport { Button, CartList, Divider } from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib/classes';\nimport { QuickOrderItemsListProps } from '@/b2b-quick-order/types';\nimport { Slot } from '@adobe-commerce/elsie/lib';\nimport { QuickOrderListItem, Search } from '@/b2b-quick-order/components';\nimport { useItemSearch } from '@/b2b-quick-order/hooks';\nimport '@/b2b-quick-order/components/QuickOrderItemsList/QuickOrderItemsList.css';\n\nconst QuickOrderItemsListComponent: FunctionComponent<\n QuickOrderItemsListProps\n> = ({\n t,\n items,\n onRemove,\n onUpdateQuantity,\n slots,\n handleAddToCart,\n isItemUpdating,\n loading,\n isDisabledButton,\n productsSearch,\n searchFilter,\n}) => {\n const {\n searchValue,\n searchResults,\n handleSearchChange,\n shouldShowResults,\n handleItemClick,\n } = useItemSearch({\n productsSearch,\n initialSku: '',\n searchFilter,\n });\n\n return (\n <div\n className={classes(['b2b-quick-order-form-quick-order-items-list'])}\n role=\"region\"\n aria-label={t.title}\n >\n <div className=\"b2b-quick-order-form-quick-order-items-list__title\">\n {t.title}\n </div>\n\n {items.length > 0 && (\n <>\n <CartList\n role=\"list\"\n className=\"b2b-quick-order-form-quick-order-items-list__list\"\n >\n {items.map((item) => (\n <QuickOrderListItem\n key={item.sku}\n item={item}\n t={t}\n onRemove={onRemove}\n onUpdateQuantity={onUpdateQuantity}\n isUpdating={isItemUpdating?.(item.sku)}\n loading={loading}\n productsSearch={productsSearch}\n searchFilter={searchFilter}\n slots={slots}\n />\n ))}\n </CartList>\n <Divider variant={'secondary'} />\n </>\n )}\n <div className=\"b2b-quick-order-form-quick-order-items-list__global-search\">\n <Search\n t={t}\n onChange={handleSearchChange}\n items={searchResults}\n value={searchValue}\n shouldShowResults={shouldShowResults}\n onItemClick={handleItemClick}\n className=\"b2b-quick-order-form-quick-order-items-list__search\"\n slots={slots}\n />\n </div>\n {items.length === 0 && (\n <div\n className=\"b2b-quick-order-form-quick-order-items-list__empty\"\n data-testid=\"empty-items\"\n >\n {t.emptyList}\n </div>\n )}\n <Slot\n slot={slots?.AddAllToCartButton}\n name=\"AddAllToCartButton\"\n context={{\n handleAddToCart,\n loading,\n isDisabledButton,\n }}\n data-testid=\"addAllToCart\"\n >\n <div className=\"b2b-quick-order-form-quick-order-items-list__actions\">\n <Button\n variant=\"primary\"\n onClick={handleAddToCart}\n data-testid=\"add-all-to-cart-button\"\n disabled={loading || isDisabledButton}\n >\n {t.addAllToCart}\n </Button>\n </div>\n </Slot>\n </div>\n );\n};\n\nexport const QuickOrderItemsList = memo(QuickOrderItemsListComponent);\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent, useMemo, useCallback, memo } from 'preact/compat';\nimport { CartItem, AccordionSection } from '@adobe-commerce/elsie/components';\nimport { Slot } from '@adobe-commerce/elsie/lib';\nimport { QuickOrderListItemProps } from '@/b2b-quick-order/types';\nimport { useItemSearch } from '@/b2b-quick-order/hooks';\nimport '@/b2b-quick-order/components/QuickOrderListItem/QuickOrderListItem.css';\nimport { Search } from '@/b2b-quick-order/components';\n\nconst QuickOrderListItemComponent: FunctionComponent<\n QuickOrderListItemProps\n> = ({\n item,\n t,\n onRemove,\n onUpdateQuantity,\n isUpdating,\n loading,\n productsSearch,\n searchFilter,\n slots,\n}) => {\n // Generate unique scope identifier Dropins - use item.id if available to distinguish multiple items with same sku\n const scope = `quick-order-item-${item.id || item.variantSku || item.sku}`;\n const currentSku = item?.variantSku ?? item?.sku;\n\n const {\n searchValue,\n searchResults,\n handleSearchChange,\n shouldShowResults,\n handleItemClick,\n } = useItemSearch({\n productsSearch,\n initialSku: currentSku,\n replaceItemSku: item.sku,\n searchFilter,\n });\n\n const formName = `form-${item.id || currentSku}`;\n const isValid = item.inStock && item.addToCartAllowed;\n const hasOptions = item.options && item.options.length > 0;\n\n const hasRequiredOptions = useMemo(\n () => hasOptions && item.options.some((option) => option.required),\n [hasOptions, item.options]\n );\n\n const hasSelectedOptions = useMemo(\n () =>\n hasOptions &&\n item.options.some(\n (option) =>\n option.items && option.items.some((optionItem) => optionItem.selected)\n ),\n [hasOptions, item.options]\n );\n\n // Check if all required options are selected\n const allRequiredOptionsSelected = useMemo(() => {\n if (hasRequiredOptions) {\n // If there are required options, check that all are selected\n return item.options.every((option) => {\n if (!option.required) return true;\n return (\n option.items && option.items.some((optionItem) => optionItem.selected)\n );\n });\n }\n // If no required options, return hasSelectedOptions\n return hasSelectedOptions;\n }, [hasRequiredOptions, hasSelectedOptions, item.options]);\n\n const mainImage = useMemo(\n () => item.images?.find((img) => img.roles?.includes('image')),\n [item.images]\n );\n\n // Memoize handlers\n const handleRemove = useCallback(() => {\n // Use item.id if available, otherwise fall back to sku\n onRemove?.(item.id || item.sku);\n }, [onRemove, item.id, item.sku]);\n\n const handleQuantityChange = useCallback(\n (newQty: number) => {\n onUpdateQuantity?.(item.sku, newQty);\n // Update hidden quantity field\n const form = document.forms[formName as any] as HTMLFormElement;\n if (form) {\n const qtyInput = form.querySelector(\n 'input[name=\"quantity\"]'\n ) as HTMLInputElement;\n if (qtyInput) qtyInput.value = String(newQty);\n }\n },\n [onUpdateQuantity, item.sku, formName]\n );\n\n const searchSlot = (\n <Slot\n name=\"QuickOrderItemSearch\"\n slot={slots?.QuickOrderItemSearch}\n context={{\n item,\n scope,\n handleSearchChange,\n searchResults,\n searchValue,\n shouldShowResults,\n handleItemClick,\n }}\n >\n <Search\n t={t}\n onChange={handleSearchChange}\n items={searchResults}\n value={searchValue}\n shouldShowResults={shouldShowResults}\n className=\"b2b-quick-order-form-quick-order-items__item-search\"\n onItemClick={handleItemClick}\n slots={slots}\n />\n </Slot>\n );\n\n if (!item.name && !item.images?.length) {\n return (\n <form\n key={item.sku}\n name={formName}\n className=\"b2b-quick-order-form-quick-order-items__item-form\"\n onSubmit={(e) => e.preventDefault()}\n >\n <input type=\"hidden\" name=\"sku\" value={item.sku} />\n <input type=\"hidden\" name=\"quantity\" value={item.quantity} />\n <input type=\"hidden\" name=\"valid\" value=\"false\" />\n <input type=\"hidden\" name=\"productType\" value=\"\" />\n {searchSlot}\n\n <CartItem\n sku={<span>{item.sku}</span>}\n title={<span>{t.productNotFound}</span>}\n quantity={item.quantity}\n alert={\n <div className=\"b2b-quick-order-items__error\">\n {t.productNotFoundDescription?.replace('{sku}', item.sku)}\n </div>\n }\n disabled={loading}\n onRemove={handleRemove}\n ariaLabel={`${t.productNotFound} - ${item.sku}`}\n />\n </form>\n );\n }\n\n return (\n <form\n key={currentSku}\n name={formName}\n className=\"b2b-quick-order-form-quick-order-items__item-form\"\n onSubmit={(e) => e.preventDefault()}\n >\n <input type=\"hidden\" name=\"sku\" value={currentSku} />\n <input type=\"hidden\" name=\"quantity\" value={item.quantity} />\n <input type=\"hidden\" name=\"valid\" value={isValid ? 'true' : 'false'} />\n <input type=\"hidden\" name=\"productType\" value={item.productType || ''} />\n {searchSlot}\n <CartItem\n title={<span>{item.name}</span>}\n sku={<span>{currentSku}</span>}\n image={\n mainImage ? (\n <img src={mainImage.url} alt={mainImage.label || item.name} />\n ) : undefined\n }\n price={\n <Slot\n name=\"ProductPrice\"\n slot={slots?.ProductPrice}\n context={{\n item,\n scope,\n }}\n />\n }\n quantity={item.quantity}\n alert={\n item.inStock === false ? (\n <div className=\"b2b-quick-order-items__alert\">{t.outOfStock}</div>\n ) : undefined\n }\n warning={\n hasOptions && !allRequiredOptionsSelected ? (\n <div className=\"b2b-quick-order-items__warning\">\n {t.configurableOptionsWarning}\n </div>\n ) : undefined\n }\n footer={\n hasOptions ? (\n <AccordionSection\n title={t.productOptions}\n ariaLabelTitle={t.productOptions}\n defaultOpen={!allRequiredOptionsSelected}\n className=\"b2b-quick-order-list-item__accordion\"\n actionIconPosition=\"left\"\n >\n <Slot\n name=\"ProductOptions\"\n slot={slots?.ProductOptions}\n context={{\n item,\n scope,\n }}\n >\n <div className=\"b2b-quick-order-items__configurable-error\">\n {t.configurableProductErrorDescription}\n </div>\n </Slot>\n </AccordionSection>\n ) : undefined\n }\n updating={isUpdating}\n disabled={loading}\n loading={loading}\n onRemove={handleRemove}\n onQuantity={handleQuantityChange}\n ariaLabel={`${item.name} - ${item.sku}`}\n />\n </form>\n );\n};\n\nexport const QuickOrderListItem = memo(QuickOrderListItemComponent);\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useCallback, useState, useRef, useEffect, memo } from 'preact/compat';\nimport { Input } from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib/classes';\nimport { SearchProps, SearchItem } from '@/b2b-quick-order/types/search.types';\nimport {\n createBlurHandler,\n clearBlurTimeout,\n handleArrowDown,\n handleArrowUp,\n handleEnterKey,\n handleEscapeKey,\n focusElement,\n} from '@/b2b-quick-order/lib';\nimport '@/b2b-quick-order/components/Search/Search.css';\nimport { Slot } from '@adobe-commerce/elsie/lib';\n\nconst cursorStyle = { cursor: 'pointer' as const };\nconst defaultCursorStyle = { cursor: 'default' as const };\n\nconst SearchComponent = <T extends SearchItem = SearchItem>({\n t,\n value,\n onChange,\n items,\n shouldShowResults = true,\n className,\n onItemClick,\n slots,\n}: SearchProps<T>) => {\n const [activeIndex, setActiveIndex] = useState(-1);\n const [initialValue, setInitialValue] = useState('');\n const [itemSelected, setItemSelected] = useState(false);\n const [isClosedManually, setIsClosedManually] = useState(false);\n\n const resultsId = useRef(\n `search-results-${Math.random().toString(36).substr(2, 9)}`\n );\n const inputRef = useRef<HTMLInputElement>(null);\n const itemRefs = useRef<(HTMLDivElement | null)[]>([]);\n const containerRef = useRef<HTMLDivElement>(null);\n const blurTimeoutRef = useRef<number | null>(null);\n\n const isOpen = Boolean(value) && !isClosedManually;\n const showResults = shouldShowResults && isOpen && items.length > 0;\n const showEmptyState = shouldShowResults && isOpen && items.length === 0;\n\n useEffect(() => {\n setActiveIndex(-1);\n // Don't reset isClosedManually here - only reset on focus\n // This prevents results from reopening after Tab\n }, [items]);\n\n useEffect(() => {\n return () => {\n clearBlurTimeout(blurTimeoutRef.current);\n };\n }, []);\n\n const createItemClickHandler = useCallback(\n (item: T) => () => {\n setItemSelected(true);\n setIsClosedManually(true);\n onItemClick?.(item);\n setActiveIndex(-1);\n },\n [onItemClick]\n );\n\n const handleFocus = useCallback(() => {\n clearBlurTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n setInitialValue(value || '');\n setItemSelected(false);\n setIsClosedManually(false);\n }, [value]);\n\n const handleBlur = useCallback(() => {\n blurTimeoutRef.current = createBlurHandler({\n containerRef: containerRef.current,\n itemSelected,\n initialValue,\n currentValue: value || '',\n onValueRestore: (restoredValue) => {\n onChange?.({ target: { value: restoredValue } } as any);\n },\n onClose: () => {\n setIsClosedManually(true);\n },\n });\n }, [itemSelected, initialValue, value, onChange]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (!showResults) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n setActiveIndex((prev) => {\n const result = handleArrowDown(\n prev,\n items.length,\n itemRefs.current\n );\n if (result.shouldFocusElement) {\n focusElement(result.shouldFocusElement);\n }\n return result.nextIndex;\n });\n break;\n case 'ArrowUp':\n e.preventDefault();\n setActiveIndex((prev) => {\n const result = handleArrowUp(\n prev,\n inputRef.current,\n itemRefs.current\n );\n if (result.shouldFocusElement) {\n focusElement(result.shouldFocusElement);\n }\n return result.nextIndex;\n });\n break;\n case 'Tab':\n // Close results and restore initial value when tabbing away from input\n clearBlurTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n setIsClosedManually(true);\n onChange?.({ target: { value: initialValue } } as any);\n break;\n case 'Enter': {\n const wasHandled = handleEnterKey(activeIndex, items, (item) => {\n setItemSelected(true);\n onItemClick?.(item);\n setActiveIndex(-1);\n });\n if (wasHandled) {\n e.preventDefault();\n }\n break;\n }\n case 'Escape':\n e.preventDefault();\n handleEscapeKey(\n initialValue,\n inputRef.current,\n (restoredValue) => {\n onChange?.({ target: { value: restoredValue } } as any);\n setActiveIndex(-1);\n setIsClosedManually(true);\n },\n () => {\n setIsClosedManually(true);\n }\n );\n break;\n }\n },\n [showResults, items, activeIndex, onItemClick, onChange, initialValue]\n );\n\n const getActiveDescendant = useCallback(() => {\n if (activeIndex >= 0 && showResults) {\n return `${resultsId.current}-item-${activeIndex}`;\n }\n return undefined;\n }, [activeIndex, showResults]);\n\n const createResultItemKeyDownHandler = useCallback(\n (index: number, item: T) => (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Enter':\n case ' ': // Space key\n e.preventDefault();\n setItemSelected(true);\n setIsClosedManually(true);\n onItemClick?.(item);\n setActiveIndex(-1);\n focusElement(inputRef.current);\n break;\n case 'Escape':\n e.preventDefault();\n setActiveIndex(-1);\n setIsClosedManually(true);\n onChange?.({ target: { value: initialValue } } as any);\n focusElement(inputRef.current);\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (index < items.length - 1) {\n setActiveIndex(index + 1);\n focusElement(itemRefs.current[index + 1]);\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (index > 0) {\n setActiveIndex(index - 1);\n focusElement(itemRefs.current[index - 1]);\n } else {\n setActiveIndex(-1);\n focusElement(inputRef.current);\n }\n break;\n case 'Tab':\n // Close results and restore initial value when tabbing away from result items\n clearBlurTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n setIsClosedManually(true);\n onChange?.({ target: { value: initialValue } } as any);\n break;\n }\n },\n [items, onItemClick, onChange, initialValue]\n );\n\n return (\n <div\n ref={containerRef}\n className={classes(['b2b-quick-order-search', className])}\n >\n <Input\n ref={inputRef}\n className=\"b2b-quick-order-search__input\"\n value={value}\n onChange={onChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={t.searchPlaceholder}\n aria-label={t.searchAriaLabel}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={showResults ? true : undefined}\n aria-controls={showResults ? resultsId.current : undefined}\n aria-activedescendant={getActiveDescendant()}\n onKeyDown={handleKeyDown}\n />\n\n {showResults && (\n <div\n id={resultsId.current}\n role=\"listbox\"\n className=\"b2b-quick-order-search__results\"\n aria-label={t.searchAriaLabel}\n >\n {items.map((item, index) => (\n <Slot\n key={item.sku}\n slot={slots?.QuickOrderSearchAutocompleteItem}\n name={'QuickOrderSearchAutocompleteItem'}\n context={{\n item,\n index,\n createItemClickHandler,\n createResultItemKeyDownHandler,\n }}\n >\n <div\n id={`${resultsId.current}-item-${index}`}\n ref={(el) => (itemRefs.current[index] = el)}\n role=\"option\"\n tabIndex={0}\n aria-selected={index === activeIndex}\n className={classes([\n 'b2b-quick-order-search__result-item',\n index === activeIndex &&\n 'b2b-quick-order-search__result-item--active',\n ])}\n onClick={createItemClickHandler(item)}\n onKeyDown={createResultItemKeyDownHandler(index, item)}\n style={onItemClick ? cursorStyle : defaultCursorStyle}\n >\n {`${item.sku} ${item.name}`}\n </div>\n </Slot>\n ))}\n </div>\n )}\n\n {showEmptyState && (\n <div\n className=\"b2b-quick-order-search__empty-state\"\n role=\"status\"\n aria-live=\"polite\"\n >\n {t.searchEmptyState}\n </div>\n )}\n\n {showResults && (\n <div\n className=\"sr-only\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {items.length}{' '}\n {items.length === 1 ? t.resultAvailable : t.resultsAvailable}.{' '}\n {t.srInstructions}\n </div>\n )}\n </div>\n );\n};\n\nexport const Search = memo(SearchComponent) as typeof SearchComponent;\n"],"names":["classes","result","item","className","isActive","debounce","fn","ms","timeoutId","args","SEARCH_FILTER","handleSearchBlur","options","containerRef","itemSelected","initialValue","currentValue","onValueRestore","onClose","activeElement","createBlurHandler","delay","clearBlurTimeout","timeoutRef","handleArrowDown","currentIndex","itemsLength","itemRefs","nextIndex","handleArrowUp","inputRef","handleEnterKey","activeIndex","items","onItemSelect","handleEscapeKey","focusElement","element","useItemSearch","productsSearch","initialSku","replaceItemSku","searchFilter","searchValue","setSearchValue","useState","searchResults","setSearchResults","isTouched","setIsTouched","isMountedRef","useRef","useEffect","debouncedSearch","useMemo","searchTerm","error","handleSearchChange","useCallback","e","value","resetSearch","handleItemClick","clickedItem","itemData","events","QuickOrderItemsListComponent","t","onRemove","onUpdateQuantity","slots","handleAddToCart","isItemUpdating","loading","isDisabledButton","shouldShowResults","jsxs","jsx","Fragment","CartList","QuickOrderListItem","Divider","Search","Slot","Button","QuickOrderItemsList","memo","QuickOrderListItemComponent","isUpdating","scope","currentSku","formName","isValid","hasOptions","hasRequiredOptions","option","hasSelectedOptions","optionItem","allRequiredOptionsSelected","mainImage","_a","img","handleRemove","handleQuantityChange","newQty","form","qtyInput","searchSlot","CartItem","_b","AccordionSection","cursorStyle","defaultCursorStyle","SearchComponent","onChange","onItemClick","setActiveIndex","setInitialValue","setItemSelected","isClosedManually","setIsClosedManually","resultsId","blurTimeoutRef","isOpen","showResults","showEmptyState","createItemClickHandler","handleFocus","handleBlur","restoredValue","handleKeyDown","prev","getActiveDescendant","createResultItemKeyDownHandler","index","Input","el"],"mappings":"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","x_google_ignoreList":[0,1]}