@propeller-commerce/propeller-v2-vue-ui 0.3.35 → 0.3.37

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 CHANGED
@@ -8,6 +8,62 @@ 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.3.37] - 2026-07-21
12
+
13
+ ### Fixed
14
+
15
+ - **`SearchBar` autosuggest now respects orderlist (contract) scoping.** The
16
+ debounced live-search query built a plain `ProductSearchInput` that never
17
+ passed `orderlistIds`/`applyOrderlists`, so the dropdown previewed the full
18
+ catalogue even inside a B2B contract catalogue (the submitted results were
19
+ already correctly scoped — only the preview leaked). It now threads the same
20
+ orderlist scope as the grid fetch, so previews and results agree and a PDP
21
+ outside the contract is no longer reachable from the preview.
22
+
23
+ ### Added
24
+
25
+ - **`SearchBar`: `#price` scoped slot + `showPrice` prop.** The scoped
26
+ `#price` slot (receives `{ result }`) replaces the price cell of each result
27
+ with custom content — e.g. a "Price by quotation" label for a contract
28
+ catalogue where prices are quote-only; it fully overrides the default price
29
+ rendering. `showPrice` (default `true`) is a simpler boolean to hide the
30
+ price column outright. Both default to the previous behaviour, so the change
31
+ is backward-compatible.
32
+
33
+ ## [0.3.36] - 2026-07-21
34
+
35
+ ### Added
36
+
37
+ - **`SearchBar`: real anchor links for navigation.** New optional
38
+ `getResultHref(result)` and `getViewAllHref(term)` props. When provided, the
39
+ autosuggest result rows and the "View all results" CTA render as real
40
+ `<a href>` elements — middle-clickable, open-in-new-tab, hover-preview,
41
+ crawlable — while the existing `onResultClick`/`onViewAllClick` callbacks
42
+ still fire for SPA navigation (modified clicks fall through to the browser).
43
+ Omit the props to keep the previous behaviour.
44
+ - **`OrderList`: URL-persistable filters.** New optional `initialSearchForm`
45
+ (seed the filter form on mount, e.g. rehydrated from the URL) and
46
+ `onSearchApply(form)` (fires when the user applies/clears filters) props, so
47
+ the consuming page can keep the filter state in the URL — bookmarkable,
48
+ shareable, back-button-friendly. `useOrders` gained the matching
49
+ `initialSearchForm` option.
50
+
51
+ ### Changed
52
+
53
+ - **`AccountIconAndMenu`: account-menu items are now `<a href>` instead of
54
+ `<button>`** (both the sidebar and dropdown variants). They use each link's
55
+ existing `href`, so they are middle-clickable / new-tab-able / crawlable;
56
+ `onMenuItemClick` still handles plain-click SPA navigation.
57
+ - **`SearchBar`: the "View all results" fallback is now a `<button>`** (was a
58
+ non-focusable `<div>`), so it is keyboard-accessible even without the new
59
+ `getViewAllHref` prop.
60
+
61
+ ### Fixed
62
+
63
+ - **`OrderList`: clickable rows now show `cursor: pointer`.** When
64
+ `rowsClickable` is set, the row cursor matches its behaviour (was `auto`,
65
+ inconsistent with the favourites cards).
66
+
11
67
  ## [0.3.35] - 2026-07-20
12
68
 
13
69
  ### Fixed
@@ -1,4 +1,5 @@
1
1
  import { Contact, Customer, GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';
2
+ import { OrderSearchForm } from '../composables/vue/useOrders';
2
3
  export interface OrderListProps {
3
4
  /** The authenticated user (Contact or Customer). Resolved from PropellerProvider when omitted. */
4
5
  user?: Contact | Customer | null;
@@ -16,6 +17,19 @@ export interface OrderListProps {
16
17
  enableSearch?: boolean;
17
18
  /** Fields enabled for searching (UI inputs) */
18
19
  searchFields?: string[];
20
+ /**
21
+ * Seed the filter form on mount — typically rehydrated from the URL query so
22
+ * a bookmarked/shared filtered view restores on reload. Pair with
23
+ * `onSearchApply` so the page can keep the URL in sync when filters change.
24
+ */
25
+ initialSearchForm?: OrderSearchForm;
26
+ /**
27
+ * Fires when the user applies or clears filters (the "Search"/"Clear"
28
+ * buttons). Receives the active filter form. Use it to persist the filters
29
+ * to the URL — the component owns no router, so the page decides how (and
30
+ * whether) to reflect them in `location`.
31
+ */
32
+ onSearchApply?: (form: OrderSearchForm) => void;
19
33
  /** Term fields configuration (backend) */
20
34
  termFields?: any[];
21
35
  /** Override company ID for order filtering (respects company switcher) */
@@ -47,6 +47,31 @@ export interface SearchBarProps {
47
47
  onResultClick?: (result: SearchBarResult) => void;
48
48
  /** Fires when "View all results" is clicked. Receives the search term. */
49
49
  onViewAllClick?: (term: string) => void;
50
+ /**
51
+ * Build the destination URL for a result item. When provided, each result
52
+ * renders as a real `<a href>` (middle-clickable, new-tab, crawlable) while
53
+ * `onResultClick` still fires for SPA navigation. Omit to keep the
54
+ * div-based fallback.
55
+ */
56
+ getResultHref?: (result: SearchBarResult) => string;
57
+ /**
58
+ * Build the destination URL for the "View all results" CTA. When provided,
59
+ * the CTA renders as a real `<a href>` (middle-clickable, new-tab, crawlable,
60
+ * keyboard-focusable) while `onViewAllClick` still fires for SPA navigation.
61
+ * Omit to keep the button fallback.
62
+ */
63
+ getViewAllHref?: (term: string) => string;
64
+ /**
65
+ * Show the price column on each autosuggest result. Defaults to `true`.
66
+ * Set `false` to hide prices entirely in the dropdown — e.g. a B2B
67
+ * contract-catalogue context where prices are quote-only and shouldn't
68
+ * appear in the live preview. Ignored when the `price` slot is provided.
69
+ *
70
+ * For custom per-result price content (e.g. a "Price by quotation" label),
71
+ * use the scoped `#price` slot instead — it receives `{ result }` and fully
72
+ * overrides the default price cell.
73
+ */
74
+ showPrice?: boolean;
50
75
  /** Custom price formatting function */
51
76
  formatPrice?: (price: number) => string;
52
77
  /** Labels for the component */
@@ -93,5 +118,32 @@ export interface SearchBarProps {
93
118
  */
94
119
  clearSignal?: number;
95
120
  }
96
- declare const _default: import('vue').DefineComponent<SearchBarProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SearchBarProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
121
+ declare function __VLS_template(): {
122
+ attrs: Partial<{}>;
123
+ slots: {
124
+ price?(_: {
125
+ result: {
126
+ id: number | string;
127
+ name: string;
128
+ sku?: string | undefined;
129
+ price?: number | undefined;
130
+ priceNet?: number | undefined;
131
+ priceGross?: number | undefined;
132
+ imageUrl?: string | undefined;
133
+ url?: string | undefined;
134
+ isCluster?: boolean | undefined;
135
+ };
136
+ }): any;
137
+ };
138
+ refs: {};
139
+ rootEl: HTMLDivElement;
140
+ };
141
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
142
+ declare const __VLS_component: import('vue').DefineComponent<SearchBarProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SearchBarProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
143
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
97
144
  export default _default;
145
+ type __VLS_WithTemplateSlots<T, S> = T & {
146
+ new (): {
147
+ $slots: S;
148
+ };
149
+ };
@@ -18,6 +18,11 @@ export interface UseOrdersOptions {
18
18
  /** Default statuses to filter by */
19
19
  orderStatuses?: string[];
20
20
  termFields?: OrderSearchFields[];
21
+ /**
22
+ * Seed the search/filter form on mount — e.g. rehydrated from the URL query
23
+ * so a bookmarked/shared filtered view restores. The consumer owns the fetch.
24
+ */
25
+ initialSearchForm?: OrderSearchForm;
21
26
  configuration?: {
22
27
  imageSearchFiltersGrid?: MediaImageProductSearchInput;
23
28
  imageVariantFiltersSmall?: TransformationsInput;
package/dist/index.cjs CHANGED
@@ -1549,7 +1549,7 @@ function useOrders(options) {
1549
1549
  const orders = vue.ref([]);
1550
1550
  const loading = vue.ref(false);
1551
1551
  const error = vue.ref(null);
1552
- const searchForm = vue.ref({});
1552
+ const searchForm = vue.ref(options.initialSearchForm ?? {});
1553
1553
  const currentOrder = vue.ref(null);
1554
1554
  const orderLoading = vue.ref(false);
1555
1555
  const termFields = options.termFields ?? [
@@ -2192,6 +2192,11 @@ function useProductSearch(options) {
2192
2192
  try {
2193
2193
  const service = index.createServices(graphqlClient).product;
2194
2194
  const lang = languageRef.value || "NL";
2195
+ const searchOrderlistIds = options.orderlistIds?.value;
2196
+ const orderlistScope = searchOrderlistIds && searchOrderlistIds.length > 0 ? {
2197
+ applyOrderlists: options.applyOrderlists?.value !== false,
2198
+ orderlistIds: searchOrderlistIds
2199
+ } : { applyOrderlists: false };
2195
2200
  const input = {
2196
2201
  term,
2197
2202
  language: lang,
@@ -2203,6 +2208,7 @@ function useProductSearch(options) {
2203
2208
  propellerSdkV2.ProductStatus.T,
2204
2209
  propellerSdkV2.ProductStatus.S
2205
2210
  ],
2211
+ ...orderlistScope,
2206
2212
  sortInputs: [{ field: propellerSdkV2.ProductSortField.RELEVANCE, order: propellerSdkV2.SortOrder.DESC }],
2207
2213
  searchFields: [
2208
2214
  {
@@ -3406,7 +3412,7 @@ const _hoisted_4$J = { class: "propeller-account-menu__user-label text-xs text-m
3406
3412
  const _hoisted_5$I = { class: "propeller-account-menu__user-name font-medium text-foreground truncate" };
3407
3413
  const _hoisted_6$H = { class: "propeller-account-menu__nav py-2" };
3408
3414
  const _hoisted_7$H = { class: "propeller-account-menu__list space-y-0.5" };
3409
- const _hoisted_8$D = ["onClick", "data-active"];
3415
+ const _hoisted_8$D = ["href", "onClick", "data-active"];
3410
3416
  const _hoisted_9$B = { class: "propeller-account-menu__logout-wrapper px-4 py-3 border-t border-border" };
3411
3417
  const _hoisted_10$z = ["aria-label", "data-open"];
3412
3418
  const _hoisted_11$v = {
@@ -3429,7 +3435,7 @@ const _hoisted_15$s = { class: "propeller-account-menu__user-label text-xs text-
3429
3435
  const _hoisted_16$r = { class: "propeller-account-menu__user-name font-medium text-foreground truncate" };
3430
3436
  const _hoisted_17$q = { class: "propeller-account-menu__nav" };
3431
3437
  const _hoisted_18$o = { class: "propeller-account-menu__list space-y-0.5" };
3432
- const _hoisted_19$o = ["onClick"];
3438
+ const _hoisted_19$o = ["href", "onClick"];
3433
3439
  const _hoisted_20$m = { class: "propeller-account-menu__logout-wrapper mt-3 pt-3 border-t border-border" };
3434
3440
  const _hoisted_21$k = {
3435
3441
  key: 1,
@@ -3564,6 +3570,13 @@ const _sfc_main$T = /* @__PURE__ */ vue.defineComponent({
3564
3570
  menuOpen.value = false;
3565
3571
  if (props.onMenuItemClick) props.onMenuItemClick(href);
3566
3572
  }
3573
+ function handleMenuLinkClick(event, href) {
3574
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
3575
+ return;
3576
+ }
3577
+ event.preventDefault();
3578
+ handleMenuItemClick(href);
3579
+ }
3567
3580
  function handleLogoutClick() {
3568
3581
  menuOpen.value = false;
3569
3582
  if (props.onLogoutClick) props.onLogoutClick();
@@ -3605,9 +3618,9 @@ const _sfc_main$T = /* @__PURE__ */ vue.defineComponent({
3605
3618
  key: link.href,
3606
3619
  class: "propeller-account-menu__item"
3607
3620
  }, [
3608
- vue.createElementVNode("button", {
3609
- type: "button",
3610
- onClick: async (event) => handleMenuItemClick(link.href),
3621
+ vue.createElementVNode("a", {
3622
+ href: link.href,
3623
+ onClick: (event) => handleMenuLinkClick(event, link.href),
3611
3624
  "data-active": isActiveLink(link.href) ? "true" : "false",
3612
3625
  class: vue.normalizeClass(`propeller-account-menu__link flex w-full items-center gap-3 px-4 py-2.5 text-sm font-medium transition-colors ${isActiveLink(link.href) ? "bg-secondary/5 text-secondary border-l-2 border-secondary" : "text-muted-foreground hover:bg-surface-hover hover:text-foreground"}`)
3613
3626
  }, vue.toDisplayString(link.label), 11, _hoisted_8$D)
@@ -3661,10 +3674,10 @@ const _sfc_main$T = /* @__PURE__ */ vue.defineComponent({
3661
3674
  key: link.href,
3662
3675
  class: "propeller-account-menu__item"
3663
3676
  }, [
3664
- vue.createElementVNode("button", {
3665
- type: "button",
3677
+ vue.createElementVNode("a", {
3678
+ href: link.href,
3666
3679
  class: "propeller-account-menu__link flex w-full items-center gap-3 px-3 py-2 text-sm font-medium rounded-[var(--radius-control)] text-muted-foreground hover:bg-surface-hover hover:text-foreground transition-colors",
3667
- onClick: async (event) => handleMenuItemClick(link.href)
3680
+ onClick: (event) => handleMenuLinkClick(event, link.href)
3668
3681
  }, vue.toDisplayString(link.label), 9, _hoisted_19$o)
3669
3682
  ]);
3670
3683
  }), 128))
@@ -13844,6 +13857,8 @@ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
13844
13857
  columnConfig: {},
13845
13858
  enableSearch: { type: Boolean },
13846
13859
  searchFields: {},
13860
+ initialSearchForm: {},
13861
+ onSearchApply: { type: Function },
13847
13862
  termFields: {},
13848
13863
  companyId: {},
13849
13864
  orderStatus: {},
@@ -13888,7 +13903,8 @@ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
13888
13903
  configuration: infra.configuration,
13889
13904
  channelIds: props.channelIds,
13890
13905
  onCartCreated: props.onCartCreated,
13891
- afterReorder: props.afterReorder
13906
+ afterReorder: props.afterReorder,
13907
+ initialSearchForm: props.initialSearchForm
13892
13908
  });
13893
13909
  const columns = vue.ref(
13894
13910
  props.columns || ["id", "date", "status", "total"]
@@ -14198,11 +14214,15 @@ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
14198
14214
  class: "propeller-order-list__clear-btn inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-[var(--radius-control)] shadow-sm text-muted-foreground bg-card hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary",
14199
14215
  onClick: _cache[11] || (_cache[11] = async (event) => {
14200
14216
  vue.unref(resetSearch)();
14217
+ props.onSearchApply?.({});
14201
14218
  })
14202
14219
  }, vue.toDisplayString(getLabel("clearButton", "Clear")), 1),
14203
14220
  vue.createElementVNode("button", {
14204
14221
  class: "propeller-order-list__search-btn inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-[var(--radius-control)] shadow-sm text-primary-foreground bg-primary hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary",
14205
- onClick: _cache[12] || (_cache[12] = async (event) => vue.unref(fetchOrders)(1))
14222
+ onClick: _cache[12] || (_cache[12] = async (event) => {
14223
+ vue.unref(fetchOrders)(1);
14224
+ props.onSearchApply?.(vue.unref(searchForm));
14225
+ })
14206
14226
  }, vue.toDisplayString(getLabel("searchButton", "Search")), 1)
14207
14227
  ])
14208
14228
  ])) : vue.createCommentVNode("", true),
@@ -14225,7 +14245,7 @@ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
14225
14245
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(orders), (order, index2) => {
14226
14246
  return vue.openBlock(), vue.createElementBlock("tr", {
14227
14247
  key: order.id,
14228
- class: "propeller-order-list__row hover:bg-surface-hover",
14248
+ class: vue.normalizeClass(`propeller-order-list__row hover:bg-surface-hover ${rowsClickable.value ? "cursor-pointer" : ""}`),
14229
14249
  "data-clickable": rowsClickable.value ? "true" : "false",
14230
14250
  onClick: async (event) => rowsClickable.value && __props.onOrderClick(order.id)
14231
14251
  }, [
@@ -14272,7 +14292,7 @@ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
14272
14292
  ], 64)) : vue.createCommentVNode("", true)
14273
14293
  ], 10, _hoisted_36$6);
14274
14294
  }), 128))
14275
- ], 8, _hoisted_35$6);
14295
+ ], 10, _hoisted_35$6);
14276
14296
  }), 128))
14277
14297
  ])
14278
14298
  ])
@@ -19911,24 +19931,24 @@ const _hoisted_5$1 = {
19911
19931
  class: "propeller-search-bar__dropdown absolute top-full left-0 right-0 mt-2 bg-card rounded-[var(--radius-container)] shadow-xl border z-50 flex flex-col max-h-96"
19912
19932
  };
19913
19933
  const _hoisted_6$1 = { class: "propeller-search-bar__results flex-1 overflow-y-auto" };
19914
- const _hoisted_7$1 = ["onClick"];
19915
- const _hoisted_8$1 = {
19934
+ const _hoisted_7$1 = {
19916
19935
  key: 0,
19917
19936
  class: "propeller-search-bar__result-media relative w-16 h-16 flex-shrink-0"
19918
19937
  };
19919
- const _hoisted_9$1 = ["src", "alt"];
19920
- const _hoisted_10$1 = { class: "flex-1 min-w-0" };
19921
- const _hoisted_11$1 = { class: "propeller-search-bar__result-name font-semibold truncate" };
19922
- const _hoisted_12$1 = {
19938
+ const _hoisted_8$1 = ["src", "alt"];
19939
+ const _hoisted_9$1 = { class: "flex-1 min-w-0" };
19940
+ const _hoisted_10$1 = { class: "propeller-search-bar__result-name font-semibold truncate" };
19941
+ const _hoisted_11$1 = {
19923
19942
  key: 0,
19924
19943
  class: "propeller-search-bar__result-sku text-sm text-muted-foreground"
19925
19944
  };
19926
- const _hoisted_13$1 = {
19927
- key: 1,
19945
+ const _hoisted_12$1 = {
19946
+ key: 2,
19928
19947
  class: "propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0 text-right"
19929
19948
  };
19930
- const _hoisted_14$1 = { class: "propeller-search-bar__result-price-value" };
19931
- const _hoisted_15$1 = { class: "propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground" };
19949
+ const _hoisted_13$1 = { class: "propeller-search-bar__result-price-value" };
19950
+ const _hoisted_14$1 = { class: "propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground" };
19951
+ const _hoisted_15$1 = ["href"];
19932
19952
  const _hoisted_16$1 = {
19933
19953
  key: 1,
19934
19954
  class: "propeller-search-bar__empty p-4 text-center text-muted-foreground"
@@ -19948,6 +19968,9 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
19948
19968
  onSubmit: { type: Function },
19949
19969
  onResultClick: { type: Function },
19950
19970
  onViewAllClick: { type: Function },
19971
+ getResultHref: { type: Function },
19972
+ getViewAllHref: { type: Function },
19973
+ showPrice: { type: Boolean },
19951
19974
  formatPrice: { type: Function },
19952
19975
  labels: {},
19953
19976
  includeTax: { type: Boolean },
@@ -20101,6 +20124,21 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
20101
20124
  }
20102
20125
  showDropdown.value = false;
20103
20126
  }
20127
+ function isModifiedClick(event) {
20128
+ return event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
20129
+ }
20130
+ function handleResultAnchorClick(event, result) {
20131
+ if (props.getResultHref) {
20132
+ if (isModifiedClick(event)) return;
20133
+ event.preventDefault();
20134
+ }
20135
+ handleResultClick(result);
20136
+ }
20137
+ function handleViewAllAnchorClick(event) {
20138
+ if (isModifiedClick(event)) return;
20139
+ event.preventDefault();
20140
+ handleViewAllClick();
20141
+ }
20104
20142
  return (_ctx, _cache) => {
20105
20143
  return vue.openBlock(), vue.createElementBlock("div", {
20106
20144
  "data-search-bar": true,
@@ -20112,7 +20150,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
20112
20150
  onSubmit: _cache[1] || (_cache[1] = async (e) => handleSubmit(e))
20113
20151
  }, [
20114
20152
  vue.createElementVNode("div", _hoisted_2$1, [
20115
- _cache[4] || (_cache[4] = vue.createElementVNode("button", {
20153
+ _cache[3] || (_cache[3] = vue.createElementVNode("button", {
20116
20154
  type: "submit",
20117
20155
  class: "propeller-search-bar__submit absolute left-3 top-1/2 transform -translate-y-1/2 p-0 bg-transparent border-none cursor-pointer"
20118
20156
  }, [
@@ -20138,7 +20176,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
20138
20176
  value: searchTerm.value,
20139
20177
  onInput: _cache[0] || (_cache[0] = async (e) => handleInputChange(e.target.value))
20140
20178
  }, null, 40, _hoisted_3$1),
20141
- vue.unref(isLoading) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$1, [..._cache[3] || (_cache[3] = [
20179
+ vue.unref(isLoading) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$1, [..._cache[2] || (_cache[2] = [
20142
20180
  vue.createElementVNode("div", { class: "propeller-search-bar__spinner animate-spin rounded-full h-5 w-5 border-b-2 border-primary" }, null, -1)
20143
20181
  ])])) : vue.createCommentVNode("", true)
20144
20182
  ])
@@ -20147,34 +20185,49 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
20147
20185
  results.value.length > 0 ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
20148
20186
  vue.createElementVNode("div", _hoisted_6$1, [
20149
20187
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(results.value, (result, index2) => {
20150
- return vue.openBlock(), vue.createElementBlock("div", {
20188
+ return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(props.getResultHref ? "a" : "div"), {
20151
20189
  key: result.id + "-" + index2,
20190
+ href: props.getResultHref ? props.getResultHref(result) : void 0,
20152
20191
  class: "propeller-search-bar__result flex items-center gap-4 p-3 hover:bg-surface-hover cursor-pointer border-b border-border last:border-b-0",
20153
- onClick: async (event) => handleResultClick(result)
20154
- }, [
20155
- result.imageUrl || noImageUrl.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$1, [
20156
- vue.createElementVNode("img", {
20157
- class: "propeller-search-bar__result-image w-full h-full object-contain",
20158
- src: result.imageUrl || noImageUrl.value,
20159
- alt: result.name
20160
- }, null, 8, _hoisted_9$1)
20161
- ])) : vue.createCommentVNode("", true),
20162
- vue.createElementVNode("div", _hoisted_10$1, [
20163
- vue.createElementVNode("div", _hoisted_11$1, vue.toDisplayString(result.name), 1),
20164
- result.sku ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_12$1, "SKU: " + vue.toDisplayString(result.sku), 1)) : vue.createCommentVNode("", true)
20192
+ onClick: (event) => handleResultAnchorClick(event, result)
20193
+ }, {
20194
+ default: vue.withCtx(() => [
20195
+ result.imageUrl || noImageUrl.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$1, [
20196
+ vue.createElementVNode("img", {
20197
+ class: "propeller-search-bar__result-image w-full h-full object-contain",
20198
+ src: result.imageUrl || noImageUrl.value,
20199
+ alt: result.name
20200
+ }, null, 8, _hoisted_8$1)
20201
+ ])) : vue.createCommentVNode("", true),
20202
+ vue.createElementVNode("div", _hoisted_9$1, [
20203
+ vue.createElementVNode("div", _hoisted_10$1, vue.toDisplayString(result.name), 1),
20204
+ result.sku ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_11$1, "SKU: " + vue.toDisplayString(result.sku), 1)) : vue.createCommentVNode("", true)
20205
+ ]),
20206
+ _ctx.$slots.price ? vue.renderSlot(_ctx.$slots, "price", {
20207
+ key: 1,
20208
+ result
20209
+ }) : __props.showPrice !== false && result.price !== void 0 && result.price !== null ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_12$1, [
20210
+ vue.createElementVNode("span", _hoisted_13$1, vue.toDisplayString(formatItemPrice(leadingPrice(result))), 1),
20211
+ vue.createElementVNode("span", _hoisted_14$1, vue.toDisplayString(priceTaxLabel()), 1)
20212
+ ])) : vue.createCommentVNode("", true)
20165
20213
  ]),
20166
- result.price !== void 0 && result.price !== null ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_13$1, [
20167
- vue.createElementVNode("span", _hoisted_14$1, vue.toDisplayString(formatItemPrice(leadingPrice(result))), 1),
20168
- vue.createElementVNode("span", _hoisted_15$1, vue.toDisplayString(priceTaxLabel()), 1)
20169
- ])) : vue.createCommentVNode("", true)
20170
- ], 8, _hoisted_7$1);
20214
+ _: 2
20215
+ }, 1032, ["href", "onClick"]);
20171
20216
  }), 128))
20172
20217
  ]),
20173
- itemsFound.value > results.value.length ? (vue.openBlock(), vue.createElementBlock("div", {
20174
- key: 0,
20175
- class: "propeller-search-bar__view-all flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-[var(--radius-container)]",
20176
- onClick: _cache[2] || (_cache[2] = async (event) => handleViewAllClick())
20177
- }, vue.toDisplayString(getLabel("viewAll", "View all results")) + " (" + vue.toDisplayString(itemsFound.value) + ") ", 1)) : vue.createCommentVNode("", true)
20218
+ itemsFound.value > results.value.length ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
20219
+ props.getViewAllHref ? (vue.openBlock(), vue.createElementBlock("a", {
20220
+ key: 0,
20221
+ href: props.getViewAllHref(searchTerm.value),
20222
+ class: "propeller-search-bar__view-all block flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-[var(--radius-container)]",
20223
+ onClick: handleViewAllAnchorClick
20224
+ }, vue.toDisplayString(getLabel("viewAll", "View all results")) + " (" + vue.toDisplayString(itemsFound.value) + ") ", 9, _hoisted_15$1)) : (vue.openBlock(), vue.createElementBlock("button", {
20225
+ key: 1,
20226
+ type: "button",
20227
+ class: "propeller-search-bar__view-all block w-full flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-[var(--radius-container)]",
20228
+ onClick: handleViewAllClick
20229
+ }, vue.toDisplayString(getLabel("viewAll", "View all results")) + " (" + vue.toDisplayString(itemsFound.value) + ") ", 1))
20230
+ ], 64)) : vue.createCommentVNode("", true)
20178
20231
  ], 64)) : vue.createCommentVNode("", true),
20179
20232
  results.value.length === 0 && searchTerm.value.length >= minLength.value && !vue.unref(isLoading) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_16$1, vue.toDisplayString(getLabel("noResults", "No products found for")) + ' "' + vue.toDisplayString(searchTerm.value) + '" ', 1)) : vue.createCommentVNode("", true)
20180
20233
  ])) : vue.createCommentVNode("", true)