@propeller-commerce/propeller-v2-react-ui 0.26.0 → 0.27.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.
- package/CHANGELOG.md +59 -6
- package/dist/index.cjs +89 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +90 -30
- package/dist/index.js.map +1 -1
- package/dist/pure.cjs +23 -0
- package/dist/pure.cjs.map +1 -1
- package/dist/pure.js +23 -0
- package/dist/pure.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,59 @@ once it reaches 1.0. Until then (the `0.x` line) the public API may change
|
|
|
8
8
|
between minor versions; breaking changes are called out below and in
|
|
9
9
|
[MIGRATION.md](./MIGRATION.md).
|
|
10
10
|
|
|
11
|
+
## [0.27.0] - 2026-09-28
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **A quantity field could not be cleared and retyped.** The typed-input handler
|
|
16
|
+
only committed a value once it was at or above the minimum, so with a minimum
|
|
17
|
+
of 2, backspacing to empty or typing "1" was ignored and the previous number
|
|
18
|
+
stayed stuck in the box. The field now accepts any keystroke while editing and
|
|
19
|
+
resolves to a valid quantity on blur. (PWP-970)
|
|
20
|
+
|
|
21
|
+
- **Incrementing an off-grid quantity kept it off-grid.** `increment()` added the
|
|
22
|
+
step without first snapping to the `min + n*step` grid, so a quantity that was
|
|
23
|
+
already off it never returned. Both steppers now snap first. (PWP-970)
|
|
24
|
+
|
|
25
|
+
- **Quick order ignored the order step.** Its quantity input was hardcoded to
|
|
26
|
+
`step={1}` and nothing snapped, while bulk paste and spreadsheet upload are the
|
|
27
|
+
primary ordering route for a wholesale account. `QuickOrderMatch` now carries
|
|
28
|
+
`step` alongside `minQuantity`, and typed quantities snap to it. (PWP-970)
|
|
29
|
+
|
|
30
|
+
- **`OrderItemCard` accepted a misconfiguration in silence.** It ships from the
|
|
31
|
+
RSC-safe `/pure` entry and reads no context, so the host must supply `language`
|
|
32
|
+
and `configuration.urls` — but both are optional, nothing warned, and the
|
|
33
|
+
failure only showed as a wrong-language name or a link that dropped the locale
|
|
34
|
+
prefix two clicks later. A development-only warning now names each omission
|
|
35
|
+
once. `titleLinkable` defaults to true, so the link case applies unless a host
|
|
36
|
+
opts out. (PWP-972)
|
|
37
|
+
|
|
38
|
+
## [0.26.1] - 2026-09-28
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- **A quoted-price product could still be added to the cart from a grid.**
|
|
43
|
+
0.26.0 guarded the PRICE on `ProductCard` but not the ACTION beside it, so a
|
|
44
|
+
listing showed "Price on request" next to a working quantity stepper and
|
|
45
|
+
add-to-cart button — and the line went in at 0. The card now offers
|
|
46
|
+
"Request a price", linking to the product page that owns the quote flow;
|
|
47
|
+
`FavoriteListItem` suppresses add-to-cart for these products outright. The
|
|
48
|
+
check sits before the injected-component branch, so a host-supplied control
|
|
49
|
+
is gated too.
|
|
50
|
+
|
|
51
|
+
- **Popovers inherited the host header’s text colour.** The search input, the
|
|
52
|
+
autosuggest dropdown, the cart sidebar and the cart popover each set their own
|
|
53
|
+
background but not their own text colour, so a shop with a dark header — which
|
|
54
|
+
has to colour that bar to style the triggers inside it — got white text on
|
|
55
|
+
their light surfaces. They are DOM children of those triggers, so the colour
|
|
56
|
+
cascaded straight in. Each now sets `text-foreground` explicitly, as
|
|
57
|
+
`AccountIconAndMenu` already did.
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- `RequestPriceButton` uses a price-tag icon rather than a quote bubble, which
|
|
62
|
+
read as a comment action.
|
|
63
|
+
|
|
11
64
|
## [0.26.0] - 2026-09-28
|
|
12
65
|
|
|
13
66
|
### Added
|
|
@@ -42,15 +95,15 @@ between minor versions; breaking changes are called out below and in
|
|
|
42
95
|
`priceOnRequest` renders in its place, and a card for such a product may
|
|
43
96
|
carry no price object at all. Existing callers are unaffected.
|
|
44
97
|
|
|
45
|
-
- **The PDP gates add-to-cart
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
98
|
+
- **The PDP gates add-to-cart on `orderable` before the display mode.** A
|
|
99
|
+
non-orderable product gets neither control, a quoted one gets the request
|
|
100
|
+
button, and an anonymous visitor gets the log-in action rather than a list they
|
|
101
|
+
cannot be quoted from.
|
|
49
102
|
|
|
50
103
|
- **Quick order excludes quoted products.** A bulk upload reports the code as
|
|
51
104
|
unresolved instead of adding a line priced at 0; picking one from the
|
|
52
|
-
typeahead clears the row with a notice.
|
|
53
|
-
|
|
105
|
+
typeahead clears the row with a notice. Bulk flows have nowhere to show a
|
|
106
|
+
price and would submit the line at 0.
|
|
54
107
|
|
|
55
108
|
## [0.25.0] - 2026-09-25
|
|
56
109
|
|
package/dist/index.cjs
CHANGED
|
@@ -2634,6 +2634,7 @@ function toMatch(item, language) {
|
|
|
2634
2634
|
const netPrice = displayItem?.price?.net ?? 0;
|
|
2635
2635
|
const grossPrice = displayItem?.price?.gross ?? 0;
|
|
2636
2636
|
const minQuantity = Math.max(1, displayItem?.minimumQuantity ?? 1);
|
|
2637
|
+
const step = Math.max(1, displayItem?.unit ?? 1);
|
|
2637
2638
|
const imageUrl = isCluster ? propellerV2CoreUi.getClusterImageUrl(item) : propellerV2CoreUi.getProductImageUrl(item);
|
|
2638
2639
|
return {
|
|
2639
2640
|
productId,
|
|
@@ -2643,6 +2644,7 @@ function toMatch(item, language) {
|
|
|
2643
2644
|
netPrice,
|
|
2644
2645
|
grossPrice,
|
|
2645
2646
|
minQuantity,
|
|
2647
|
+
step,
|
|
2646
2648
|
imageUrl,
|
|
2647
2649
|
priceOnRequest: isPriceOnRequest(item)
|
|
2648
2650
|
};
|
|
@@ -4779,6 +4781,7 @@ function AddToCart(rawProps) {
|
|
|
4779
4781
|
onCartCreated: props.onCartCreated
|
|
4780
4782
|
});
|
|
4781
4783
|
const [quantity, setQuantity] = React6.useState(() => getMinQuantity(props.product));
|
|
4784
|
+
const [quantityDraft, setQuantityDraft] = React6.useState(null);
|
|
4782
4785
|
const [toastMessage, setToastMessage] = React6.useState(() => "");
|
|
4783
4786
|
const [toastType, setToastType] = React6.useState(() => "");
|
|
4784
4787
|
const [toastVisible, setToastVisible] = React6.useState(() => false);
|
|
@@ -4801,16 +4804,42 @@ function AddToCart(rawProps) {
|
|
|
4801
4804
|
function dismissToast() {
|
|
4802
4805
|
setToastVisible(false);
|
|
4803
4806
|
}
|
|
4807
|
+
function snapQuantity(value) {
|
|
4808
|
+
const min = getMinQuantity(props.product);
|
|
4809
|
+
const step = getStep(props.product);
|
|
4810
|
+
if (value <= min) return min;
|
|
4811
|
+
return Math.round((value - min) / step) * step + min;
|
|
4812
|
+
}
|
|
4804
4813
|
function increment() {
|
|
4805
|
-
|
|
4814
|
+
setQuantityDraft(null);
|
|
4815
|
+
const snapped = snapQuantity(quantity);
|
|
4816
|
+
setQuantity(snapped === quantity ? quantity + getStep(props.product) : snapped);
|
|
4806
4817
|
}
|
|
4807
4818
|
function decrement() {
|
|
4808
4819
|
const min = getMinQuantity(props.product);
|
|
4809
4820
|
const step = getStep(props.product);
|
|
4821
|
+
setQuantityDraft(null);
|
|
4822
|
+
const snapped = snapQuantity(quantity);
|
|
4823
|
+
if (snapped !== quantity) {
|
|
4824
|
+
setQuantity(snapped);
|
|
4825
|
+
return;
|
|
4826
|
+
}
|
|
4810
4827
|
if (quantity - step >= min) {
|
|
4811
4828
|
setQuantity(quantity - step);
|
|
4812
4829
|
}
|
|
4813
4830
|
}
|
|
4831
|
+
function handleQuantityInput(raw) {
|
|
4832
|
+
setQuantityDraft(raw);
|
|
4833
|
+
const val = parseInt(raw, 10);
|
|
4834
|
+
if (!isNaN(val) && val >= getMinQuantity(props.product)) {
|
|
4835
|
+
setQuantity(snapQuantity(val));
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
function handleQuantityBlur() {
|
|
4839
|
+
const val = parseInt(quantityDraft ?? "", 10);
|
|
4840
|
+
setQuantity(isNaN(val) ? getMinQuantity(props.product) : snapQuantity(val));
|
|
4841
|
+
setQuantityDraft(null);
|
|
4842
|
+
}
|
|
4814
4843
|
function getModalImageUrl() {
|
|
4815
4844
|
if (addedCartItem) {
|
|
4816
4845
|
const img = addedCartItem.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url;
|
|
@@ -4940,15 +4969,9 @@ function AddToCart(rawProps) {
|
|
|
4940
4969
|
className: "propeller-add-to-cart__quantity flex-1 md:flex-none md:w-12 text-center text-sm bg-transparent border-none focus:ring-0 focus:outline-none h-full [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
|
|
4941
4970
|
min: getMinQuantity(props.product),
|
|
4942
4971
|
step: getStep(props.product),
|
|
4943
|
-
value: quantity,
|
|
4944
|
-
onChange: (e) =>
|
|
4945
|
-
|
|
4946
|
-
const min = getMinQuantity(props.product);
|
|
4947
|
-
const step = getStep(props.product);
|
|
4948
|
-
if (!isNaN(val) && val >= min) {
|
|
4949
|
-
setQuantity(Math.round((val - min) / step) * step + min);
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4972
|
+
value: quantityDraft ?? quantity,
|
|
4973
|
+
onChange: (e) => handleQuantityInput(e.target.value),
|
|
4974
|
+
onBlur: handleQuantityBlur
|
|
4952
4975
|
}
|
|
4953
4976
|
),
|
|
4954
4977
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4973,15 +4996,9 @@ function AddToCart(rawProps) {
|
|
|
4973
4996
|
className: "propeller-add-to-cart__quantity w-full md:w-16 h-10 text-center text-sm border border-input rounded-control focus:ring-2 focus:ring-secondary focus:border-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
|
|
4974
4997
|
min: getMinQuantity(props.product),
|
|
4975
4998
|
step: getStep(props.product),
|
|
4976
|
-
value: quantity,
|
|
4977
|
-
onChange: (e) =>
|
|
4978
|
-
|
|
4979
|
-
const min = getMinQuantity(props.product);
|
|
4980
|
-
const step = getStep(props.product);
|
|
4981
|
-
if (!isNaN(val) && val >= min) {
|
|
4982
|
-
setQuantity(Math.round((val - min) / step) * step + min);
|
|
4983
|
-
}
|
|
4984
|
-
}
|
|
4999
|
+
value: quantityDraft ?? quantity,
|
|
5000
|
+
onChange: (e) => handleQuantityInput(e.target.value),
|
|
5001
|
+
onBlur: handleQuantityBlur
|
|
4985
5002
|
}
|
|
4986
5003
|
) : null,
|
|
4987
5004
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -7658,7 +7675,7 @@ function CartIconAndSidebar(rawProps) {
|
|
|
7658
7675
|
]
|
|
7659
7676
|
}
|
|
7660
7677
|
),
|
|
7661
|
-
props.showTotals && isHovered && totalItems > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__popover absolute top-full right-0 mt-1 z-40 bg-popover border border-border rounded-container shadow-lg px-3 py-2 min-w-[140px] text-sm whitespace-nowrap", children: [
|
|
7678
|
+
props.showTotals && isHovered && totalItems > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__popover absolute top-full right-0 mt-1 z-40 bg-popover text-foreground border border-border rounded-container shadow-lg px-3 py-2 min-w-[140px] text-sm whitespace-nowrap", children: [
|
|
7662
7679
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between gap-4", children: [
|
|
7663
7680
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__popover-label text-muted-foreground", children: totalLabel("totalLabel") }),
|
|
7664
7681
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__popover-total font-semibold text-foreground", children: totalPrice })
|
|
@@ -7686,7 +7703,7 @@ function CartIconAndSidebar(rawProps) {
|
|
|
7686
7703
|
"aria-modal": "true",
|
|
7687
7704
|
"aria-label": sidebarTitle,
|
|
7688
7705
|
"data-open": sidebarOpen ? "true" : "false",
|
|
7689
|
-
className: cn(`propeller-cart-icon__sidebar fixed inset-y-0 right-0 z-[70] w-full max-w-md bg-card shadow-2xl transform transition-transform duration-300 ease-in-out border-l border-border${sidebarOpen ? " translate-x-0" : " translate-x-full"}${props.sidebarClassName ? " " + props.sidebarClassName : ""}`),
|
|
7706
|
+
className: cn(`propeller-cart-icon__sidebar fixed inset-y-0 right-0 z-[70] w-full max-w-md bg-card text-foreground shadow-2xl transform transition-transform duration-300 ease-in-out border-l border-border${sidebarOpen ? " translate-x-0" : " translate-x-full"}${props.sidebarClassName ? " " + props.sidebarClassName : ""}`),
|
|
7690
7707
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-full", children: isMounted ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7691
7708
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__sidebar-header flex items-center justify-between px-5 py-4 border-b border-border", children: [
|
|
7692
7709
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -9347,7 +9364,7 @@ function ProductCardPrice(props) {
|
|
|
9347
9364
|
) });
|
|
9348
9365
|
}
|
|
9349
9366
|
function ProductCardAddToCart(props) {
|
|
9350
|
-
const { product, resolved } = useProductCard();
|
|
9367
|
+
const { product, derived, resolved, handleProductClick } = useProductCard();
|
|
9351
9368
|
if (propellerV2CoreUi.isContentHidden(resolved.portalMode, resolved.user, resolved.isAuthenticated)) {
|
|
9352
9369
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9353
9370
|
LoginToOrderButton_default,
|
|
@@ -9358,6 +9375,19 @@ function ProductCardAddToCart(props) {
|
|
|
9358
9375
|
}
|
|
9359
9376
|
);
|
|
9360
9377
|
}
|
|
9378
|
+
if (isPriceOnRequest(product)) {
|
|
9379
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9380
|
+
"a",
|
|
9381
|
+
{
|
|
9382
|
+
href: derived.productUrl,
|
|
9383
|
+
onClick: handleProductClick,
|
|
9384
|
+
className: cn(
|
|
9385
|
+
`propeller-product-card__view-product inline-flex h-10 w-full items-center justify-center rounded-control bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 ${props.className || ""}`
|
|
9386
|
+
),
|
|
9387
|
+
children: propellerV2CoreUi.getLabel(resolved.priceLabels, "requestPrice", "Request a price")
|
|
9388
|
+
}
|
|
9389
|
+
);
|
|
9390
|
+
}
|
|
9361
9391
|
const InjectedAddToCart = resolved.addToCartComponent;
|
|
9362
9392
|
if (InjectedAddToCart) {
|
|
9363
9393
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -11913,7 +11943,7 @@ function FavoriteListItemActions(props) {
|
|
|
11913
11943
|
className: props.className ?? "propeller-favorite-list-item__actions flex items-center gap-2 flex-shrink-0",
|
|
11914
11944
|
onClick: (e) => e.stopPropagation(),
|
|
11915
11945
|
children: [
|
|
11916
|
-
resolved.allowAddToCart !== false && isProduct && !!resolved.graphqlClient ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11946
|
+
resolved.allowAddToCart !== false && isProduct && !!resolved.graphqlClient && !isPriceOnRequest(product) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11917
11947
|
AddToCart_default,
|
|
11918
11948
|
{
|
|
11919
11949
|
className: "flex items-center gap-2",
|
|
@@ -13890,6 +13920,28 @@ function OrderActions(rawProps) {
|
|
|
13890
13920
|
);
|
|
13891
13921
|
}
|
|
13892
13922
|
var OrderActions_default = OrderActions;
|
|
13923
|
+
var warnedOnce = /* @__PURE__ */ new Set();
|
|
13924
|
+
function warnOnce(key, message) {
|
|
13925
|
+
if (warnedOnce.has(key)) return;
|
|
13926
|
+
warnedOnce.add(key);
|
|
13927
|
+
console.warn(message);
|
|
13928
|
+
}
|
|
13929
|
+
function warnMissingProps(props) {
|
|
13930
|
+
if (process.env.NODE_ENV === "production") return;
|
|
13931
|
+
if (!props.language) {
|
|
13932
|
+
warnOnce(
|
|
13933
|
+
"language",
|
|
13934
|
+
"[OrderItemCard] No `language` prop: product names resolve in the default catalogue language, whatever page they are on. This component reads no context (it ships from the RSC-safe /pure entry), so the host must pass it."
|
|
13935
|
+
);
|
|
13936
|
+
}
|
|
13937
|
+
const linkable = props.titleLinkable !== void 0 ? props.titleLinkable : true;
|
|
13938
|
+
if (linkable && !props.configuration?.urls) {
|
|
13939
|
+
warnOnce(
|
|
13940
|
+
"urls",
|
|
13941
|
+
"[OrderItemCard] Title is linkable but no `configuration.urls` was passed: links fall back to a literal /product/:id/:slug and lose the locale prefix. Pass the url builders from the host, or set titleLinkable={false}."
|
|
13942
|
+
);
|
|
13943
|
+
}
|
|
13944
|
+
}
|
|
13893
13945
|
function getProductName3(orderItem, language) {
|
|
13894
13946
|
return propellerV2CoreUi.getLocalizedValue(orderItem?.product?.names, language, "") || orderItem?.name || "Unknown Product";
|
|
13895
13947
|
}
|
|
@@ -13913,6 +13965,7 @@ function getProductUrl(orderItem, language, urls) {
|
|
|
13913
13965
|
function OrderItemCard(props) {
|
|
13914
13966
|
const item = props.orderItem;
|
|
13915
13967
|
const isChildItem = props.isChildItem || false;
|
|
13968
|
+
warnMissingProps(props);
|
|
13916
13969
|
const titleLinkable = props.titleLinkable !== void 0 ? props.titleLinkable : true;
|
|
13917
13970
|
const showImage = isChildItem ? false : props.showImage !== void 0 ? props.showImage : true;
|
|
13918
13971
|
const showSku = isChildItem ? false : props.showSku !== void 0 ? props.showSku : true;
|
|
@@ -14676,7 +14729,7 @@ function RequestPriceButton(props) {
|
|
|
14676
14729
|
if (props.onRequestPrice) props.onRequestPrice();
|
|
14677
14730
|
},
|
|
14678
14731
|
children: [
|
|
14679
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
14732
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Tag, { className: "propeller-request-price__icon w-4 h-4", "aria-hidden": "true" }),
|
|
14680
14733
|
label
|
|
14681
14734
|
]
|
|
14682
14735
|
}
|
|
@@ -14684,6 +14737,10 @@ function RequestPriceButton(props) {
|
|
|
14684
14737
|
}
|
|
14685
14738
|
var RequestPriceButton_default = RequestPriceButton;
|
|
14686
14739
|
var ROW_SEQ = 0;
|
|
14740
|
+
function snapToStep(value, min, step) {
|
|
14741
|
+
if (!Number.isFinite(value) || value <= min) return min;
|
|
14742
|
+
return Math.round((value - min) / (step || 1)) * (step || 1) + min;
|
|
14743
|
+
}
|
|
14687
14744
|
function blankRow() {
|
|
14688
14745
|
ROW_SEQ += 1;
|
|
14689
14746
|
return {
|
|
@@ -14695,6 +14752,7 @@ function blankRow() {
|
|
|
14695
14752
|
grossPrice: 0,
|
|
14696
14753
|
quantity: 1,
|
|
14697
14754
|
minQuantity: 1,
|
|
14755
|
+
step: 1,
|
|
14698
14756
|
matches: [],
|
|
14699
14757
|
searching: false,
|
|
14700
14758
|
searched: false
|
|
@@ -14788,6 +14846,7 @@ function QuickOrderInner(props) {
|
|
|
14788
14846
|
grossPrice: match.grossPrice,
|
|
14789
14847
|
quantity: match.minQuantity,
|
|
14790
14848
|
minQuantity: match.minQuantity,
|
|
14849
|
+
step: match.step,
|
|
14791
14850
|
matches: [],
|
|
14792
14851
|
searching: false,
|
|
14793
14852
|
searched: false
|
|
@@ -14800,7 +14859,7 @@ function QuickOrderInner(props) {
|
|
|
14800
14859
|
const n = parseInt(raw, 10);
|
|
14801
14860
|
setRows(
|
|
14802
14861
|
(prev) => prev.map(
|
|
14803
|
-
(r) => r.key === key ? { ...r, quantity:
|
|
14862
|
+
(r) => r.key === key ? { ...r, quantity: snapToStep(n, r.minQuantity, r.step) } : r
|
|
14804
14863
|
)
|
|
14805
14864
|
);
|
|
14806
14865
|
},
|
|
@@ -14853,7 +14912,8 @@ function QuickOrderInner(props) {
|
|
|
14853
14912
|
netPrice: exact.netPrice,
|
|
14854
14913
|
grossPrice: exact.grossPrice,
|
|
14855
14914
|
quantity: Math.max(exact.minQuantity, line.quantity),
|
|
14856
|
-
minQuantity: exact.minQuantity
|
|
14915
|
+
minQuantity: exact.minQuantity,
|
|
14916
|
+
step: exact.step
|
|
14857
14917
|
});
|
|
14858
14918
|
}
|
|
14859
14919
|
if (resolved.length) {
|
|
@@ -14984,7 +15044,7 @@ function QuickOrderInner(props) {
|
|
|
14984
15044
|
{
|
|
14985
15045
|
type: "number",
|
|
14986
15046
|
min: r.minQuantity,
|
|
14987
|
-
step: 1,
|
|
15047
|
+
step: r.step || 1,
|
|
14988
15048
|
value: r.productId ? r.quantity : "",
|
|
14989
15049
|
disabled: !r.productId,
|
|
14990
15050
|
onChange: (e) => setQuantity(r.key, e.target.value),
|
|
@@ -19352,7 +19412,7 @@ function SearchBar(rawProps) {
|
|
|
19352
19412
|
// boilerplate's dark header band happened to make work: on a
|
|
19353
19413
|
// light header `bg-white/95 border-white/20` rendered as an
|
|
19354
19414
|
// invisible input.
|
|
19355
|
-
"propeller-search-bar__input w-full pl-10 pr-10 py-2 bg-card border border-input rounded-container focus:outline-none focus:ring-2 focus:ring-secondary placeholder:text-muted-foreground",
|
|
19415
|
+
"propeller-search-bar__input w-full pl-10 pr-10 py-2 bg-card text-foreground border border-input rounded-container focus:outline-none focus:ring-2 focus:ring-secondary placeholder:text-muted-foreground",
|
|
19356
19416
|
props.inputClassName
|
|
19357
19417
|
),
|
|
19358
19418
|
placeholder: props.placeholder || "Search products...",
|
|
@@ -19362,7 +19422,7 @@ function SearchBar(rawProps) {
|
|
|
19362
19422
|
),
|
|
19363
19423
|
searchLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-search-bar__spinner-wrapper absolute right-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-search-bar__spinner animate-spin rounded-full h-5 w-5 border-b-2 border-primary" }) }) : null
|
|
19364
19424
|
] }) }),
|
|
19365
|
-
showDropdown ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-search-bar__dropdown absolute top-full left-0 right-0 mt-2 bg-card rounded-container shadow-xl border border-border z-50 flex flex-col max-h-96", children: [
|
|
19425
|
+
showDropdown ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-search-bar__dropdown absolute top-full left-0 right-0 mt-2 bg-card text-foreground rounded-container shadow-xl border border-border z-50 flex flex-col max-h-96", children: [
|
|
19366
19426
|
results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
19367
19427
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-search-bar__results flex-1 overflow-y-auto", children: results?.map((result, index) => {
|
|
19368
19428
|
const ResultTag = props.getResultHref ? "a" : "div";
|