@propeller-commerce/propeller-v2-react-ui 0.14.0 → 0.15.1

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/dist/index.d.cts CHANGED
@@ -1396,11 +1396,13 @@ interface UseProductSearchOptions {
1396
1396
  /** Upper price bound filter. */
1397
1397
  priceFilterMax?: number;
1398
1398
  /**
1399
- * Stock buckets to filter by. Empty, unset, or both buckets sends no stock
1400
- * filter. Filtering happens server-side, so `itemsFound` and the page count
1399
+ * Stock selection to filter by. `'all'` or unset sends no stock filter.
1400
+ * Filtering happens server-side, so `itemsFound` and the page count
1401
1401
  * describe the filtered set.
1402
1402
  */
1403
- availability?: Availability[];
1403
+ availability?: Availability;
1404
+ /** Minimum stock quantity for the `'in-stock'` selection. */
1405
+ minStock?: number;
1404
1406
  /** Sort field; overrides the internal sort state when set. */
1405
1407
  sortField?: string;
1406
1408
  /** Sort direction (`'ASC'` / `'DESC'`); overrides internal state when set. */
@@ -4635,12 +4637,14 @@ interface GridFiltersProps {
4635
4637
  */
4636
4638
  showAvailabilityFilter?: boolean;
4637
4639
  /**
4638
- * Currently active availability buckets (URL-driven). Seeds the checkboxes
4639
- * on the first render so a restored filtered URL renders them ticked.
4640
+ * Currently active availability selection (URL-driven). Seeds the toggle
4641
+ * on the first render so a restored filtered URL renders it correctly.
4640
4642
  */
4641
- activeAvailability?: Availability[];
4642
- /** Called whenever an availability checkbox is toggled. */
4643
- onAvailabilityChange?: (sel: Availability[]) => void;
4643
+ activeAvailability?: Availability;
4644
+ /** Currently active minimum stock quantity (URL-driven). Undefined means the minimum. */
4645
+ activeMinStock?: number;
4646
+ /** Called on every toggle or stepper change with both values. */
4647
+ onAvailabilityChange?: (sel: Availability, minStock: number) => void;
4644
4648
  /**
4645
4649
  * When true, all checkboxes and price inputs are disabled.
4646
4650
  * Wire to ProductGrid's `onLoadingChange` to block rapid re-clicks while a fetch is in flight.
@@ -4826,15 +4830,14 @@ interface GridToolbarProps {
4826
4830
  */
4827
4831
  onPriceFilterRemove?: () => void;
4828
4832
  /**
4829
- * Currently active availability (stock) filter selections.
4830
- * Renders one removable chip per selected bucket.
4833
+ * Currently active availability (stock) selection.
4834
+ * Renders a single removable chip when set to `'in-stock'`.
4831
4835
  */
4832
- availability?: Availability[];
4833
- /**
4834
- * Called when an availability filter badge × is clicked.
4835
- * Receives the specific bucket to remove.
4836
- */
4837
- onAvailabilityFilterRemove?: (value: Availability) => void;
4836
+ availability?: Availability;
4837
+ /** Currently active minimum stock quantity, shown on the chip above the default. */
4838
+ minStock?: number;
4839
+ /** Called when the availability filter badge × is clicked. */
4840
+ onAvailabilityFilterRemove?: () => void;
4838
4841
  /**
4839
4842
  * Called when "Clear All" is clicked.
4840
4843
  */
@@ -6233,10 +6236,12 @@ interface ProductGridProps {
6233
6236
  /** * Active price range lower bound from the FiltersSidebar `onPriceChange`. * Triggers a re-fetch when changed. */ priceFilterMin?: number;
6234
6237
  /** * Active price range upper bound from the FiltersSidebar `onPriceChange`. * Triggers a re-fetch when changed. */ priceFilterMax?: number;
6235
6238
  /**
6236
- * Active stock buckets from the filters sidebar. Triggers a re-fetch when
6237
- * changed. Empty or both buckets means no stock filter.
6239
+ * Active stock selection from the filters sidebar. Triggers a re-fetch when
6240
+ * changed. `'all'` or undefined means no stock filter.
6238
6241
  */
6239
- availability?: Availability[];
6242
+ availability?: Availability;
6243
+ /** Minimum stock quantity for the `'in-stock'` selection. Defaults to the minimum threshold. */
6244
+ minStock?: number;
6240
6245
  /** * Called when sort state changes internally (for syncing a sibling toolbar). */ onSortChange?: (field: string, order: string) => void;
6241
6246
  /** * Called after each internal data fetch with the min/max price of the * current product set — use to populate a price range slider in the parent. */ onPriceBoundsChange?: (min: number, max: number) => void;
6242
6247
  /** * Called after each fetch with the total number of products found — * use to display a result count in the parent toolbar. */ onItemsFoundChange?: (count: number) => void;
package/dist/index.d.ts CHANGED
@@ -1396,11 +1396,13 @@ interface UseProductSearchOptions {
1396
1396
  /** Upper price bound filter. */
1397
1397
  priceFilterMax?: number;
1398
1398
  /**
1399
- * Stock buckets to filter by. Empty, unset, or both buckets sends no stock
1400
- * filter. Filtering happens server-side, so `itemsFound` and the page count
1399
+ * Stock selection to filter by. `'all'` or unset sends no stock filter.
1400
+ * Filtering happens server-side, so `itemsFound` and the page count
1401
1401
  * describe the filtered set.
1402
1402
  */
1403
- availability?: Availability[];
1403
+ availability?: Availability;
1404
+ /** Minimum stock quantity for the `'in-stock'` selection. */
1405
+ minStock?: number;
1404
1406
  /** Sort field; overrides the internal sort state when set. */
1405
1407
  sortField?: string;
1406
1408
  /** Sort direction (`'ASC'` / `'DESC'`); overrides internal state when set. */
@@ -4635,12 +4637,14 @@ interface GridFiltersProps {
4635
4637
  */
4636
4638
  showAvailabilityFilter?: boolean;
4637
4639
  /**
4638
- * Currently active availability buckets (URL-driven). Seeds the checkboxes
4639
- * on the first render so a restored filtered URL renders them ticked.
4640
+ * Currently active availability selection (URL-driven). Seeds the toggle
4641
+ * on the first render so a restored filtered URL renders it correctly.
4640
4642
  */
4641
- activeAvailability?: Availability[];
4642
- /** Called whenever an availability checkbox is toggled. */
4643
- onAvailabilityChange?: (sel: Availability[]) => void;
4643
+ activeAvailability?: Availability;
4644
+ /** Currently active minimum stock quantity (URL-driven). Undefined means the minimum. */
4645
+ activeMinStock?: number;
4646
+ /** Called on every toggle or stepper change with both values. */
4647
+ onAvailabilityChange?: (sel: Availability, minStock: number) => void;
4644
4648
  /**
4645
4649
  * When true, all checkboxes and price inputs are disabled.
4646
4650
  * Wire to ProductGrid's `onLoadingChange` to block rapid re-clicks while a fetch is in flight.
@@ -4826,15 +4830,14 @@ interface GridToolbarProps {
4826
4830
  */
4827
4831
  onPriceFilterRemove?: () => void;
4828
4832
  /**
4829
- * Currently active availability (stock) filter selections.
4830
- * Renders one removable chip per selected bucket.
4833
+ * Currently active availability (stock) selection.
4834
+ * Renders a single removable chip when set to `'in-stock'`.
4831
4835
  */
4832
- availability?: Availability[];
4833
- /**
4834
- * Called when an availability filter badge × is clicked.
4835
- * Receives the specific bucket to remove.
4836
- */
4837
- onAvailabilityFilterRemove?: (value: Availability) => void;
4836
+ availability?: Availability;
4837
+ /** Currently active minimum stock quantity, shown on the chip above the default. */
4838
+ minStock?: number;
4839
+ /** Called when the availability filter badge × is clicked. */
4840
+ onAvailabilityFilterRemove?: () => void;
4838
4841
  /**
4839
4842
  * Called when "Clear All" is clicked.
4840
4843
  */
@@ -6233,10 +6236,12 @@ interface ProductGridProps {
6233
6236
  /** * Active price range lower bound from the FiltersSidebar `onPriceChange`. * Triggers a re-fetch when changed. */ priceFilterMin?: number;
6234
6237
  /** * Active price range upper bound from the FiltersSidebar `onPriceChange`. * Triggers a re-fetch when changed. */ priceFilterMax?: number;
6235
6238
  /**
6236
- * Active stock buckets from the filters sidebar. Triggers a re-fetch when
6237
- * changed. Empty or both buckets means no stock filter.
6239
+ * Active stock selection from the filters sidebar. Triggers a re-fetch when
6240
+ * changed. `'all'` or undefined means no stock filter.
6238
6241
  */
6239
- availability?: Availability[];
6242
+ availability?: Availability;
6243
+ /** Minimum stock quantity for the `'in-stock'` selection. Defaults to the minimum threshold. */
6244
+ minStock?: number;
6240
6245
  /** * Called when sort state changes internally (for syncing a sibling toolbar). */ onSortChange?: (field: string, order: string) => void;
6241
6246
  /** * Called after each internal data fetch with the min/max price of the * current product set — use to populate a price range slider in the parent. */ onPriceBoundsChange?: (min: number, max: number) => void;
6242
6247
  /** * Called after each fetch with the total number of products found — * use to display a result count in the parent toolbar. */ onItemsFoundChange?: (count: number) => void;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { getLabel, getLocalizedValue, formatPrice, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl, createServices, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, buildInventoryFilter, getLanguageString, collectAttributeValues, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
2
+ import { getLabel, getLocalizedValue, formatPrice, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl, createServices, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, buildInventoryFilter, MIN_STOCK_THRESHOLD, getLanguageString, collectAttributeValues, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
3
3
  export * from '@propeller-commerce/propeller-v2-core-ui';
4
4
  import * as React6 from 'react';
5
5
  import { createContext, useState, useRef, useMemo, useCallback, useContext, useEffect } from 'react';
@@ -2242,7 +2242,8 @@ function useProductSearch(options) {
2242
2242
  JSON.stringify(options.textFilters ?? []),
2243
2243
  options.priceFilterMin ?? "",
2244
2244
  options.priceFilterMax ?? "",
2245
- JSON.stringify(options.availability ?? [])
2245
+ options.availability ?? "",
2246
+ options.minStock ?? ""
2246
2247
  ].join("|");
2247
2248
  if (inflightFetches2.has(inflightKey)) {
2248
2249
  fetchIdRef.current--;
@@ -2284,7 +2285,7 @@ function useProductSearch(options) {
2284
2285
  }
2285
2286
  ] : [];
2286
2287
  const priceFilter = options.priceFilterMin !== void 0 || options.priceFilterMax !== void 0 ? { from: options.priceFilterMin ?? 0, to: options.priceFilterMax ?? 999999 } : void 0;
2287
- const inventoryFilter = buildInventoryFilter(options.availability);
2288
+ const inventoryFilter = buildInventoryFilter(options.availability, options.minStock);
2288
2289
  const userId = options.user && "contactId" in options.user ? options.user.contactId : options.user && "customerId" in options.user ? options.user.customerId : void 0;
2289
2290
  const contactId = options.user && "contactId" in options.user ? options.user.contactId : void 0;
2290
2291
  const customerId = options.user && "customerId" in options.user ? options.user.customerId : void 0;
@@ -2385,6 +2386,7 @@ function useProductSearch(options) {
2385
2386
  options.priceFilterMin,
2386
2387
  options.priceFilterMax,
2387
2388
  options.availability,
2389
+ options.minStock,
2388
2390
  options.sortField,
2389
2391
  options.sortOrder,
2390
2392
  options.companyId,
@@ -2424,7 +2426,7 @@ function useProductSearch(options) {
2424
2426
  const userId = options.user && "contactId" in options.user ? options.user.contactId : options.user && "customerId" in options.user ? options.user.customerId : void 0;
2425
2427
  const contactId = options.user && "contactId" in options.user ? options.user.contactId : void 0;
2426
2428
  const customerId = options.user && "customerId" in options.user ? options.user.customerId : void 0;
2427
- const inventoryFilter = buildInventoryFilter(options.availability);
2429
+ const inventoryFilter = buildInventoryFilter(options.availability, options.minStock);
2428
2430
  const categoryProductSearchInput = {
2429
2431
  language,
2430
2432
  page: 1,
@@ -2517,6 +2519,7 @@ function useProductSearch(options) {
2517
2519
  options.priceFilterMin,
2518
2520
  options.priceFilterMax,
2519
2521
  options.availability,
2522
+ options.minStock,
2520
2523
  options.sortField,
2521
2524
  options.sortOrder,
2522
2525
  pageSize,
@@ -9040,6 +9043,7 @@ function ProductGrid(rawProps) {
9040
9043
  priceFilterMin: props.priceFilterMin,
9041
9044
  priceFilterMax: props.priceFilterMax,
9042
9045
  availability: props.availability,
9046
+ minStock: props.minStock,
9043
9047
  sortField: props.sortField,
9044
9048
  sortOrder: props.sortOrder,
9045
9049
  pageSize: props.pageSize,
@@ -9343,7 +9347,13 @@ function GridFilters(rawProps) {
9343
9347
  const [appliedMin, setAppliedMin] = useState(() => void 0);
9344
9348
  const [appliedMax, setAppliedMax] = useState(() => void 0);
9345
9349
  const [availability, setAvailability] = useState(
9346
- () => [...props.activeAvailability || []]
9350
+ () => props.activeAvailability || "all"
9351
+ );
9352
+ const [minStock, setMinStock] = useState(
9353
+ () => props.activeMinStock ?? MIN_STOCK_THRESHOLD
9354
+ );
9355
+ const [minStockInput, setMinStockInput] = useState(
9356
+ () => String(props.activeMinStock ?? MIN_STOCK_THRESHOLD)
9347
9357
  );
9348
9358
  function showPriceFilter() {
9349
9359
  const mode = props.portalMode || "open";
@@ -9398,13 +9408,28 @@ function GridFilters(rawProps) {
9398
9408
  props.onFilterChange(filter, value);
9399
9409
  if (props.getSelectedFilters) props.getSelectedFilters();
9400
9410
  }
9401
- function handleAvailabilityToggle(value, checked) {
9402
- const next = checked ? [...availability, value] : availability.filter((v) => v !== value);
9403
- setAvailability(next);
9411
+ function handleAvailabilityChange(value) {
9412
+ const nextMinStock = value === "all" ? MIN_STOCK_THRESHOLD : minStock;
9413
+ setAvailability(value);
9414
+ setMinStock(nextMinStock);
9415
+ setMinStockInput(String(nextMinStock));
9416
+ setIsPending(true);
9417
+ if (props.onAvailabilityChange) props.onAvailabilityChange(value, nextMinStock);
9418
+ if (props.getSelectedFilters) props.getSelectedFilters();
9419
+ }
9420
+ function handleMinStockChange(value) {
9421
+ const n = Math.max(Math.floor(value) || MIN_STOCK_THRESHOLD, MIN_STOCK_THRESHOLD);
9422
+ setMinStock(n);
9423
+ setMinStockInput(String(n));
9424
+ if (n === minStock) return;
9404
9425
  setIsPending(true);
9405
- if (props.onAvailabilityChange) props.onAvailabilityChange(next);
9426
+ if (props.onAvailabilityChange) props.onAvailabilityChange(availability, n);
9406
9427
  if (props.getSelectedFilters) props.getSelectedFilters();
9407
9428
  }
9429
+ function commitMinStockInput() {
9430
+ const parsed = parseInt(minStockInput, 10);
9431
+ handleMinStockChange(isNaN(parsed) ? MIN_STOCK_THRESHOLD : parsed);
9432
+ }
9408
9433
  function handleMinChange(value) {
9409
9434
  const n = value > currentMax ? currentMax : value;
9410
9435
  setCurrentMin(n);
@@ -9442,7 +9467,7 @@ function GridFilters(rawProps) {
9442
9467
  function getCount(option) {
9443
9468
  const c = option?.count || 0;
9444
9469
  const ca = option?.countActive || 0;
9445
- return c === 0 && ca > 0 ? ca : c;
9470
+ return ca > 0 ? ca : c;
9446
9471
  }
9447
9472
  function getMinBound() {
9448
9473
  return props.priceMin || 0;
@@ -9478,7 +9503,9 @@ function GridFilters(rawProps) {
9478
9503
  setCurrentMin(props.priceMin || 0);
9479
9504
  setCurrentMax(props.priceMax || 9999);
9480
9505
  setExpandedFilters({});
9481
- setAvailability([]);
9506
+ setAvailability("all");
9507
+ setMinStock(MIN_STOCK_THRESHOLD);
9508
+ setMinStockInput(String(MIN_STOCK_THRESHOLD));
9482
9509
  }, [props.clearSignal, props.priceMin, props.priceMax]);
9483
9510
  useEffect(() => {
9484
9511
  if (!props.activeTextFilters) return;
@@ -9486,8 +9513,10 @@ function GridFilters(rawProps) {
9486
9513
  }, [props.activeTextFilters]);
9487
9514
  useEffect(() => {
9488
9515
  if (!props.activeAvailability) return;
9489
- setAvailability([...props.activeAvailability]);
9490
- }, [props.activeAvailability]);
9516
+ setAvailability(props.activeAvailability);
9517
+ setMinStock(props.activeMinStock ?? MIN_STOCK_THRESHOLD);
9518
+ setMinStockInput(String(props.activeMinStock ?? MIN_STOCK_THRESHOLD));
9519
+ }, [props.activeAvailability, props.activeMinStock]);
9491
9520
  useEffect(() => {
9492
9521
  if (props.activePriceMin === void 0 && props.activePriceMax === void 0) {
9493
9522
  setCurrentMin(props.priceMin || 0);
@@ -9590,34 +9619,76 @@ function GridFilters(rawProps) {
9590
9619
  showAvailability() ? /* @__PURE__ */ jsxs(Fragment, { children: [
9591
9620
  /* @__PURE__ */ jsxs("div", { className: "propeller-grid-filters__availability space-y-3", children: [
9592
9621
  /* @__PURE__ */ jsx("h3", { className: "propeller-grid-filters__availability-title text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: getLabel(props.labels, "availability", "Availability") }),
9593
- /* @__PURE__ */ jsxs("div", { className: "propeller-grid-filters__availability-options space-y-1.5", children: [
9594
- /* @__PURE__ */ jsxs("label", { className: "propeller-grid-filters__option flex items-center gap-2 cursor-pointer group", children: [
9622
+ /* @__PURE__ */ jsxs("div", { className: "propeller-grid-filters__availability-toggle inline-flex h-8 w-full rounded-control border border-input overflow-hidden", children: [
9623
+ /* @__PURE__ */ jsx(
9624
+ "button",
9625
+ {
9626
+ type: "button",
9627
+ className: `propeller-grid-filters__availability-option flex-1 text-xs font-medium transition-colors ${availability === "all" ? "bg-secondary text-secondary-foreground" : "bg-transparent text-muted-foreground hover:text-foreground"}`,
9628
+ "aria-pressed": availability === "all",
9629
+ disabled: !!props.isLoading,
9630
+ onClick: () => handleAvailabilityChange("all"),
9631
+ children: getLabel(props.labels, "allProducts", "All products")
9632
+ }
9633
+ ),
9634
+ /* @__PURE__ */ jsx(
9635
+ "button",
9636
+ {
9637
+ type: "button",
9638
+ className: `propeller-grid-filters__availability-option flex-1 text-xs font-medium transition-colors ${availability === "in-stock" ? "bg-secondary text-secondary-foreground" : "bg-transparent text-muted-foreground hover:text-foreground"}`,
9639
+ "aria-pressed": availability === "in-stock",
9640
+ disabled: !!props.isLoading,
9641
+ onClick: () => handleAvailabilityChange("in-stock"),
9642
+ children: getLabel(props.labels, "inStock", "In stock")
9643
+ }
9644
+ )
9645
+ ] }),
9646
+ availability === "in-stock" ? /* @__PURE__ */ jsxs("div", { className: "propeller-grid-filters__availability-quantity flex items-center gap-2 text-sm text-muted-foreground", children: [
9647
+ /* @__PURE__ */ jsx("span", { children: getLabel(props.labels, "atLeast", "at least") }),
9648
+ /* @__PURE__ */ jsxs("div", { className: "propeller-grid-filters__availability-stepper inline-flex items-center h-8 rounded-control border border-input bg-card overflow-hidden focus-within:ring-1 focus-within:ring-secondary", children: [
9595
9649
  /* @__PURE__ */ jsx(
9596
- "input",
9650
+ "button",
9597
9651
  {
9598
- type: "checkbox",
9599
- className: "propeller-grid-filters__checkbox h-4 w-4 rounded border-input text-secondary focus:ring-secondary cursor-pointer flex-shrink-0",
9600
- checked: availability.includes("in-stock"),
9601
- disabled: !!props.isLoading,
9602
- onChange: (e) => handleAvailabilityToggle("in-stock", e.target.checked)
9652
+ type: "button",
9653
+ className: "propeller-grid-filters__quantity-decrease h-full w-8 flex items-center justify-center text-muted-foreground disabled:opacity-40 disabled:cursor-not-allowed hover:bg-accent hover:text-foreground transition-colors",
9654
+ "aria-label": getLabel(props.labels, "quantityDecrease", "Decrease quantity"),
9655
+ disabled: !!props.isLoading || minStock <= MIN_STOCK_THRESHOLD,
9656
+ onClick: () => handleMinStockChange(minStock - 1),
9657
+ children: "\u2212"
9603
9658
  }
9604
9659
  ),
9605
- /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__option-label flex-1 text-sm text-muted-foreground leading-none select-none group-hover:text-foreground", children: getLabel(props.labels, "inStock", "In stock") })
9606
- ] }),
9607
- /* @__PURE__ */ jsxs("label", { className: "propeller-grid-filters__option flex items-center gap-2 cursor-pointer group", children: [
9608
9660
  /* @__PURE__ */ jsx(
9609
9661
  "input",
9610
9662
  {
9611
- type: "checkbox",
9612
- className: "propeller-grid-filters__checkbox h-4 w-4 rounded border-input text-secondary focus:ring-secondary cursor-pointer flex-shrink-0",
9613
- checked: availability.includes("out-of-stock"),
9663
+ type: "number",
9664
+ inputMode: "numeric",
9665
+ className: "propeller-grid-filters__availability-quantity-input w-10 h-full px-0 text-center font-medium text-foreground bg-transparent border-0 focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9666
+ "aria-label": getLabel(props.labels, "atLeast", "at least"),
9667
+ min: MIN_STOCK_THRESHOLD,
9668
+ step: 1,
9669
+ value: minStockInput,
9614
9670
  disabled: !!props.isLoading,
9615
- onChange: (e) => handleAvailabilityToggle("out-of-stock", e.target.checked)
9671
+ onChange: (e) => setMinStockInput(e.target.value),
9672
+ onBlur: () => commitMinStockInput(),
9673
+ onKeyDown: (e) => {
9674
+ if (e.key === "Enter") e.target.blur();
9675
+ }
9616
9676
  }
9617
9677
  ),
9618
- /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__option-label flex-1 text-sm text-muted-foreground leading-none select-none group-hover:text-foreground", children: getLabel(props.labels, "outOfStock", "Out of stock") })
9619
- ] })
9620
- ] })
9678
+ /* @__PURE__ */ jsx(
9679
+ "button",
9680
+ {
9681
+ type: "button",
9682
+ className: "propeller-grid-filters__quantity-increase h-full w-8 flex items-center justify-center text-muted-foreground disabled:opacity-40 disabled:cursor-not-allowed hover:bg-accent hover:text-foreground transition-colors",
9683
+ "aria-label": getLabel(props.labels, "quantityIncrease", "Increase quantity"),
9684
+ disabled: !!props.isLoading,
9685
+ onClick: () => handleMinStockChange(minStock + 1),
9686
+ children: "+"
9687
+ }
9688
+ )
9689
+ ] }),
9690
+ /* @__PURE__ */ jsx("span", { children: getLabel(props.labels, "pcs", "pcs") })
9691
+ ] }) : null
9621
9692
  ] }),
9622
9693
  /* @__PURE__ */ jsx("div", { className: "propeller-grid-filters__divider h-px bg-border-subtle" })
9623
9694
  ] }) : null,
@@ -9797,7 +9868,6 @@ var DEFAULT_LABELS = {
9797
9868
  perPage: " per page",
9798
9869
  price: "Price",
9799
9870
  inStock: "In stock",
9800
- outOfStock: "Out of stock",
9801
9871
  switchToList: "Switch to list view",
9802
9872
  switchToGrid: "Switch to grid view"
9803
9873
  };
@@ -9826,7 +9896,7 @@ function GridToolbar(rawProps) {
9826
9896
  const text = props.activeTextFilters || {};
9827
9897
  const hasText = Object.keys(text).some((k) => (text[k] || []).length > 0);
9828
9898
  const hasPrice = props.priceFilterMin !== void 0 || props.priceFilterMax !== void 0;
9829
- const hasAvailability = (props.availability || []).length > 0;
9899
+ const hasAvailability = props.availability === "in-stock";
9830
9900
  return hasText || hasPrice || hasAvailability;
9831
9901
  }
9832
9902
  function getActiveFilterBadges() {
@@ -9845,8 +9915,10 @@ function GridToolbar(rawProps) {
9845
9915
  function isPriceSortDisabled() {
9846
9916
  return isContentHidden(props.portalMode, props.user);
9847
9917
  }
9848
- function getAvailabilityLabel(value) {
9849
- return value === "in-stock" ? getLabel56("inStock") : getLabel56("outOfStock");
9918
+ function getAvailabilityLabel() {
9919
+ const qty = props.minStock;
9920
+ if (qty !== void 0 && qty > MIN_STOCK_THRESHOLD) return `${getLabel56("inStock")}: ${qty}+`;
9921
+ return getLabel56("inStock");
9850
9922
  }
9851
9923
  function handleSortFieldChange(field) {
9852
9924
  setCurrentSortField(field);
@@ -10021,20 +10093,19 @@ function GridToolbar(rawProps) {
10021
10093
  ]
10022
10094
  }
10023
10095
  ) : null,
10024
- (props.availability || []).map((value) => /* @__PURE__ */ jsxs(
10096
+ props.availability === "in-stock" ? /* @__PURE__ */ jsxs(
10025
10097
  "span",
10026
10098
  {
10027
10099
  className: "propeller-grid-toolbar__filter-badge propeller-grid-toolbar__filter-badge--availability inline-flex items-center gap-1 cursor-pointer px-2.5 py-0.5 rounded-full text-xs font-semibold border border-input bg-background hover:bg-primary hover:text-primary-foreground hover:border-primary transition-colors",
10028
10100
  onClick: (event) => {
10029
- if (props.onAvailabilityFilterRemove) props.onAvailabilityFilterRemove(value);
10101
+ if (props.onAvailabilityFilterRemove) props.onAvailabilityFilterRemove();
10030
10102
  },
10031
10103
  children: [
10032
- getAvailabilityLabel(value),
10104
+ getAvailabilityLabel(),
10033
10105
  /* @__PURE__ */ jsx("span", { className: "propeller-grid-toolbar__filter-badge-remove", children: "\xD7" })
10034
10106
  ]
10035
- },
10036
- value
10037
- )),
10107
+ }
10108
+ ) : null,
10038
10109
  getActiveFilterBadges()?.map((badge) => /* @__PURE__ */ jsxs(
10039
10110
  "span",
10040
10111
  {