@propeller-commerce/propeller-v2-react-ui 0.10.0 → 0.11.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 CHANGED
@@ -8,6 +8,53 @@ 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.11.0] - 2026-07-30
12
+
13
+ ### Fixed
14
+
15
+ - **`<Menu depth>` was inert past three levels.** `depth` was threaded into
16
+ `useMenu`, which correctly built a recursive query to any depth, but every
17
+ style rendered exactly three hand-coded levels. `depth={4}` and beyond fetched
18
+ data that was never displayed — extra payload for nothing, with no warning
19
+ that the prop was only half-honoured. All styles now render to `depth`.
20
+ - **The expand chevron promised levels that never rendered.** It keyed off "has
21
+ children" alone, so a category at the deepest rendered level showed an
22
+ affordance that did nothing. It is now also gated on the child being within
23
+ `depth`.
24
+
25
+ ### Changed
26
+
27
+ - **Per-level menu state replaced with a single open path.** The four
28
+ positional state slots (`hoveredL1Id` / `hoveredL2Id` / `expandedL1` /
29
+ `expandedL2`) are now one `openPath: number[]`. "Opening a shallower item
30
+ closes the deeper ones" is structural (`slice(0, level)`) rather than a
31
+ hand-written reset per level, which grew quadratically and was easy to get
32
+ wrong when adding a level.
33
+ - **`data-level` is emitted to whatever depth renders** instead of a hardcoded
34
+ `1`/`2`/`3`, so consumer CSS can target arbitrary depth.
35
+ - **Flyout styles cap the levels they can lay out** — 4 for
36
+ `dropdown-vertical`, 3 for `dropdown-horizontal`/`jumbotron`, since each level
37
+ is another horizontal column and beyond that they run off-screen. The
38
+ accordion nests vertically and is uncapped. Exceeding a cap logs a
39
+ `console.warn` in development (previously the prop silently did nothing).
40
+
41
+ `depth` still defaults to 3, and all fifteen `propeller-menu__*` class hooks are
42
+ unchanged, so a three-level menu keeps its existing structure and styling. Some
43
+ Tailwind utility classes internal to the component differ where per-level
44
+ values (`pl-8` / `pl-12` indentation) became a computed `padding-left`; styling
45
+ that targets the `propeller-menu__*` hooks is unaffected.
46
+
47
+ ## [0.10.1] - 2026-07-30
48
+
49
+ ### Fixed
50
+
51
+ - **`<SearchBar>` autosuggest ignored orderlist scoping.** The component
52
+ resolves `user` like every other infra prop but never passed it to
53
+ `useProductSearch`, and the backend drives orderlist scoping off the user id —
54
+ so `orderlistIds` alone had no effect on the autosuggest query. The dropdown
55
+ returned the whole catalogue while the grid below it, which does pass `user`,
56
+ showed only the contract's products. Forwarding `user` makes the two agree.
57
+
11
58
  ## [0.10.0] - 2026-07-29
12
59
 
13
60
  ### Added
package/dist/index.cjs CHANGED
@@ -12847,10 +12847,7 @@ function ItemsOverview(props) {
12847
12847
  var ItemsOverview_default = ItemsOverview;
12848
12848
  function Menu(rawProps) {
12849
12849
  const props = useInfraProps(rawProps);
12850
- const [hoveredL1Id, setHoveredL1Id] = React6.useState(null);
12851
- const [hoveredL2Id, setHoveredL2Id] = React6.useState(null);
12852
- const [expandedL1, setExpandedL1] = React6.useState(null);
12853
- const [expandedL2, setExpandedL2] = React6.useState(null);
12850
+ const [openPath, setOpenPath] = React6.useState([]);
12854
12851
  const userKey = props.user ? "contactId" in props.user ? `c${props.user.contactId}` : `u${props.user.customerId}` : "";
12855
12852
  const hasPrefetchedTree = Array.isArray(props.tree);
12856
12853
  const { categories: fetchedCategories, loading: fetchedLoading, error: menuError, fetchMenu } = useMenu({
@@ -12887,16 +12884,139 @@ function Menu(rawProps) {
12887
12884
  });
12888
12885
  }
12889
12886
  }
12890
- function setHoveredL1(id) {
12891
- setHoveredL1Id(id);
12892
- setHoveredL2Id(null);
12887
+ function openAt(level, categoryId) {
12888
+ setOpenPath((prev) => {
12889
+ const next = prev.slice(0, level);
12890
+ if (categoryId !== null) next.push(categoryId);
12891
+ return next;
12892
+ });
12893
12893
  }
12894
- function setHoveredL2(id) {
12895
- setHoveredL2Id(id);
12894
+ function toggleAt(level, categoryId) {
12895
+ setOpenPath(
12896
+ (prev) => prev[level] === categoryId ? prev.slice(0, level) : [...prev.slice(0, level), categoryId]
12897
+ );
12898
+ }
12899
+ function isOpenAt(level, categoryId) {
12900
+ return openPath[level] === categoryId;
12896
12901
  }
12897
12902
  function getMenuStyle() {
12898
12903
  return props.menuStyle || "dropdown-vertical";
12899
12904
  }
12905
+ function getRenderableDepth() {
12906
+ const requested = Math.max(1, props.depth ?? 3);
12907
+ const cap = getMenuStyle() === "dropdown-horizontal" ? 3 : getMenuStyle() === "accordion" ? Number.POSITIVE_INFINITY : 4;
12908
+ if (process.env.NODE_ENV !== "production" && requested > cap) {
12909
+ console.warn(
12910
+ `[Menu] depth={${requested}} exceeds what menuStyle="${getMenuStyle()}" can lay out (${cap}); rendering ${cap} levels. Use menuStyle="accordion" for deeper trees.`
12911
+ );
12912
+ }
12913
+ return Math.min(requested, cap);
12914
+ }
12915
+ const maxDepth = getRenderableDepth();
12916
+ function renderChevron(cat, level, rotated = false) {
12917
+ if (getSubCategories(cat).length === 0 || level + 1 >= maxDepth) return null;
12918
+ return /* @__PURE__ */ jsxRuntime.jsx(
12919
+ "svg",
12920
+ {
12921
+ className: `propeller-menu__chevron w-3.5 h-3.5 flex-shrink-0 transition-transform ${rotated ? "rotate-180" : ""}`,
12922
+ viewBox: "0 0 24 24",
12923
+ fill: "none",
12924
+ stroke: "currentColor",
12925
+ strokeWidth: "2",
12926
+ strokeLinecap: "round",
12927
+ strokeLinejoin: "round",
12928
+ "aria-hidden": "true",
12929
+ children: rotated ? /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) : /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" })
12930
+ }
12931
+ );
12932
+ }
12933
+ function renderColumns(items, level) {
12934
+ if (!items.length || level >= maxDepth) return [];
12935
+ const openId = openPath[level];
12936
+ const openCat = items.find((c) => c.categoryId === openId);
12937
+ const column = /* @__PURE__ */ jsxRuntime.jsx(
12938
+ "ul",
12939
+ {
12940
+ className: `propeller-menu__list w-64 py-1 flex-shrink-0 ${level + 1 < maxDepth ? "border-r border-border" : ""}`,
12941
+ "data-level": level + 1,
12942
+ children: items.map((cat, idx) => /* @__PURE__ */ jsxRuntime.jsx(
12943
+ "li",
12944
+ {
12945
+ className: "propeller-menu__item",
12946
+ "data-level": level + 1,
12947
+ "data-active": isOpenAt(level, cat.categoryId) ? "true" : "false",
12948
+ onMouseEnter: () => openAt(level, cat.categoryId),
12949
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
12950
+ "a",
12951
+ {
12952
+ href: getCategoryUrl(cat),
12953
+ onClick: (e) => handleItemClick(cat, e),
12954
+ className: `propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${isOpenAt(level, cat.categoryId) ? "bg-accent text-accent-foreground" : "text-foreground hover:bg-accent/50"}`,
12955
+ children: [
12956
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(cat) }),
12957
+ renderChevron(cat, level)
12958
+ ]
12959
+ }
12960
+ )
12961
+ },
12962
+ `l${level}-${cat.categoryId}-${idx}`
12963
+ ))
12964
+ },
12965
+ `col-${level}`
12966
+ );
12967
+ const deeper = openCat ? renderColumns(getSubCategories(openCat), level + 1) : [];
12968
+ return [column, ...deeper];
12969
+ }
12970
+ function renderAccordion(items, level) {
12971
+ if (!items.length || level >= maxDepth) return null;
12972
+ return /* @__PURE__ */ jsxRuntime.jsx(
12973
+ "ul",
12974
+ {
12975
+ className: `propeller-menu__list ${level === 0 ? "divide-y divide-border" : level === 1 ? "bg-accent/30" : "bg-accent/20"}`,
12976
+ "data-level": level + 1,
12977
+ children: items.map((cat, idx) => {
12978
+ const children = getSubCategories(cat);
12979
+ const expanded = isOpenAt(level, cat.categoryId);
12980
+ const canExpand = children.length > 0 && level + 1 < maxDepth;
12981
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12982
+ "li",
12983
+ {
12984
+ className: "propeller-menu__item",
12985
+ "data-level": level + 1,
12986
+ "data-expanded": expanded ? "true" : "false",
12987
+ children: [
12988
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
12989
+ /* @__PURE__ */ jsxRuntime.jsx(
12990
+ "a",
12991
+ {
12992
+ href: getCategoryUrl(cat),
12993
+ onClick: (e) => handleItemClick(cat, e),
12994
+ className: "propeller-menu__link flex-1 px-4 py-3 text-sm text-foreground",
12995
+ style: { paddingLeft: `${1 + level}rem` },
12996
+ children: getCategoryName(cat)
12997
+ }
12998
+ ),
12999
+ canExpand ? /* @__PURE__ */ jsxRuntime.jsx(
13000
+ "button",
13001
+ {
13002
+ type: "button",
13003
+ className: "propeller-menu__toggle px-4 py-3",
13004
+ "aria-expanded": expanded,
13005
+ "aria-label": getCategoryName(cat),
13006
+ onClick: () => toggleAt(level, cat.categoryId),
13007
+ children: renderChevron(cat, level, expanded)
13008
+ }
13009
+ ) : null
13010
+ ] }),
13011
+ expanded && canExpand ? renderAccordion(children, level + 1) : null
13012
+ ]
13013
+ },
13014
+ `l${level}-${cat.categoryId}-${idx}`
13015
+ );
13016
+ })
13017
+ }
13018
+ );
13019
+ }
12900
13020
  React6.useEffect(() => {
12901
13021
  if (hasPrefetchedTree) return;
12902
13022
  if (!props.graphqlClient) return;
@@ -12919,125 +13039,7 @@ function Menu(rawProps) {
12919
13039
  "nav",
12920
13040
  {
12921
13041
  className: `propeller-menu__nav hidden md:block ${props.menuClass || ""}`,
12922
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex bg-popover border border-border shadow-lg", children: [
12923
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "propeller-menu__list w-64 py-1 border-r border-border flex-shrink-0", "data-level": "1", children: menuCategories?.map((l1, idx) => /* @__PURE__ */ jsxRuntime.jsx(
12924
- "li",
12925
- {
12926
- className: "propeller-menu__item",
12927
- "data-level": "1",
12928
- "data-active": hoveredL1Id === l1.categoryId ? "true" : "false",
12929
- onMouseEnter: (event) => setHoveredL1(l1.categoryId),
12930
- children: /* @__PURE__ */ jsxRuntime.jsxs(
12931
- "a",
12932
- {
12933
- href: getCategoryUrl(l1),
12934
- onClick: (e) => handleItemClick(l1, e),
12935
- className: `propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${hoveredL1Id === l1.categoryId ? "bg-accent text-accent-foreground" : "text-foreground hover:bg-accent/50"}`,
12936
- children: [
12937
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label font-medium truncate", children: getCategoryName(l1) }),
12938
- getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
12939
- "svg",
12940
- {
12941
- fill: "none",
12942
- stroke: "currentColor",
12943
- viewBox: "0 0 24 24",
12944
- className: "propeller-menu__chevron w-4 h-4 text-muted-foreground",
12945
- children: /* @__PURE__ */ jsxRuntime.jsx(
12946
- "path",
12947
- {
12948
- strokeLinecap: "round",
12949
- strokeLinejoin: "round",
12950
- d: "M9 5l7 7-7 7",
12951
- strokeWidth: 2
12952
- }
12953
- )
12954
- }
12955
- ) : null
12956
- ]
12957
- }
12958
- )
12959
- },
12960
- `l1-${l1.categoryId}-${idx}`
12961
- )) }),
12962
- menuCategories?.map(
12963
- (l1, idx) => hoveredL1Id === l1.categoryId && getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
12964
- "ul",
12965
- {
12966
- className: "propeller-menu__list w-64 py-1 border-r border-border flex-shrink-0",
12967
- "data-level": "2",
12968
- children: getSubCategories(l1)?.map((l2, idx2) => /* @__PURE__ */ jsxRuntime.jsx(
12969
- "li",
12970
- {
12971
- className: "propeller-menu__item",
12972
- "data-level": "2",
12973
- "data-active": hoveredL2Id === l2.categoryId ? "true" : "false",
12974
- onMouseEnter: (event) => setHoveredL2(l2.categoryId),
12975
- children: /* @__PURE__ */ jsxRuntime.jsxs(
12976
- "a",
12977
- {
12978
- href: getCategoryUrl(l2),
12979
- onClick: (e) => handleItemClick(l2, e),
12980
- className: `propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${hoveredL2Id === l2.categoryId ? "bg-accent text-accent-foreground" : "text-foreground hover:bg-accent/50"}`,
12981
- children: [
12982
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label truncate", children: getCategoryName(l2) }),
12983
- getSubCategories(l2).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
12984
- "svg",
12985
- {
12986
- fill: "none",
12987
- stroke: "currentColor",
12988
- viewBox: "0 0 24 24",
12989
- className: "propeller-menu__chevron w-4 h-4 text-muted-foreground",
12990
- children: /* @__PURE__ */ jsxRuntime.jsx(
12991
- "path",
12992
- {
12993
- strokeLinecap: "round",
12994
- strokeLinejoin: "round",
12995
- d: "M9 5l7 7-7 7",
12996
- strokeWidth: 2
12997
- }
12998
- )
12999
- }
13000
- ) : null
13001
- ]
13002
- }
13003
- )
13004
- },
13005
- `l2-${l2.categoryId}-${idx2}`
13006
- ))
13007
- },
13008
- `l1-sub-${l1.categoryId}-${idx}`
13009
- ) : null
13010
- ),
13011
- menuCategories?.map(
13012
- (l1, idx) => hoveredL1Id === l1.categoryId ? /* @__PURE__ */ jsxRuntime.jsx(React6__namespace.Fragment, { children: getSubCategories(l1)?.map(
13013
- (l2, idx2) => hoveredL2Id === l2.categoryId && getSubCategories(l2).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
13014
- "ul",
13015
- {
13016
- className: "propeller-menu__list w-64 py-1 flex-shrink-0",
13017
- "data-level": "3",
13018
- children: getSubCategories(l2)?.map((l3, idx3) => /* @__PURE__ */ jsxRuntime.jsx(
13019
- "li",
13020
- {
13021
- className: "propeller-menu__item",
13022
- "data-level": "3",
13023
- children: /* @__PURE__ */ jsxRuntime.jsx(
13024
- "a",
13025
- {
13026
- className: "propeller-menu__link block px-4 py-2.5 text-sm text-foreground hover:bg-accent/50 transition-colors",
13027
- href: getCategoryUrl(l3),
13028
- onClick: (e) => handleItemClick(l3, e),
13029
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(l3) })
13030
- }
13031
- )
13032
- },
13033
- `l3-${l3.categoryId}-${idx3}`
13034
- ))
13035
- },
13036
- `l3-col-${l2.categoryId}-${idx2}`
13037
- ) : null
13038
- ) }, `l1-l3col-${l1.categoryId}-${idx}`) : null
13039
- )
13040
- ] })
13042
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex bg-popover border border-border shadow-lg", children: renderColumns(menuCategories, 0) })
13041
13043
  }
13042
13044
  ) : null,
13043
13045
  !isLoading && !hasError && menuCategories.length > 0 && getMenuStyle() === "jumbotron" ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -13048,22 +13050,22 @@ function Menu(rawProps) {
13048
13050
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-menu__tabs flex items-center border-b border-border", children: menuCategories?.map((l1, idx) => /* @__PURE__ */ jsxRuntime.jsx(
13049
13051
  "button",
13050
13052
  {
13051
- className: `propeller-menu__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 ${hoveredL1Id === l1.categoryId ? "border-primary text-primary" : "border-transparent text-foreground hover:text-primary hover:border-primary/50"}`,
13053
+ className: `propeller-menu__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 ${isOpenAt(0, l1.categoryId) ? "border-primary text-primary" : "border-transparent text-foreground hover:text-primary hover:border-primary/50"}`,
13052
13054
  "data-level": "1",
13053
- "data-active": hoveredL1Id === l1.categoryId ? "true" : "false",
13054
- onMouseEnter: (event) => setHoveredL1(l1.categoryId),
13055
+ "data-active": isOpenAt(0, l1.categoryId) ? "true" : "false",
13056
+ onMouseEnter: (event) => openAt(0, l1.categoryId),
13055
13057
  onClick: (e) => handleItemClick(l1, e),
13056
13058
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(l1) })
13057
13059
  },
13058
13060
  `l1-${l1.categoryId}-${idx}`
13059
13061
  )) }),
13060
13062
  menuCategories?.map(
13061
- (l1, idx) => hoveredL1Id === l1.categoryId && getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
13063
+ (l1, idx) => isOpenAt(0, l1.categoryId) && getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
13062
13064
  "div",
13063
13065
  {
13064
13066
  className: "propeller-menu__panel bg-popover border border-border border-t-0 shadow-lg p-6",
13065
- onMouseEnter: (event) => setHoveredL1(l1.categoryId),
13066
- onMouseLeave: (event) => setHoveredL1(null),
13067
+ onMouseEnter: (event) => openAt(0, l1.categoryId),
13068
+ onMouseLeave: (event) => openAt(0, null),
13067
13069
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-menu__panel-grid grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6", children: getSubCategories(l1)?.map((l2, idx2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-menu__group", "data-level": "2", children: [
13068
13070
  /* @__PURE__ */ jsxRuntime.jsx(
13069
13071
  "a",
@@ -13090,123 +13092,7 @@ function Menu(rawProps) {
13090
13092
  ]
13091
13093
  }
13092
13094
  ) : null,
13093
- !isLoading && !hasError && menuCategories.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { className: `propeller-menu__nav md:hidden ${props.menuClass || ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "propeller-menu__list divide-y divide-border", "data-level": "1", children: menuCategories?.map((l1, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
13094
- "li",
13095
- {
13096
- className: "propeller-menu__item",
13097
- "data-level": "1",
13098
- "data-expanded": expandedL1 === l1.categoryId ? "true" : "false",
13099
- children: [
13100
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
13101
- /* @__PURE__ */ jsxRuntime.jsx(
13102
- "a",
13103
- {
13104
- className: "propeller-menu__link flex-1 px-4 py-3 text-sm font-medium text-foreground",
13105
- href: getCategoryUrl(l1),
13106
- onClick: (e) => handleItemClick(l1, e),
13107
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(l1) })
13108
- }
13109
- ),
13110
- getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
13111
- "button",
13112
- {
13113
- type: "button",
13114
- className: "propeller-menu__toggle px-4 py-3 text-muted-foreground",
13115
- onClick: (event) => {
13116
- setExpandedL1(expandedL1 === l1.categoryId ? null : l1.categoryId);
13117
- },
13118
- children: /* @__PURE__ */ jsxRuntime.jsx(
13119
- "svg",
13120
- {
13121
- fill: "none",
13122
- stroke: "currentColor",
13123
- viewBox: "0 0 24 24",
13124
- className: `propeller-menu__chevron w-4 h-4 transition-transform ${expandedL1 === l1.categoryId ? "rotate-180" : ""}`,
13125
- children: /* @__PURE__ */ jsxRuntime.jsx(
13126
- "path",
13127
- {
13128
- strokeLinecap: "round",
13129
- strokeLinejoin: "round",
13130
- d: "m6 9 6 6 6-6",
13131
- strokeWidth: 2
13132
- }
13133
- )
13134
- }
13135
- )
13136
- }
13137
- ) : null
13138
- ] }),
13139
- expandedL1 === l1.categoryId && getSubCategories(l1).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "propeller-menu__list bg-accent/30", "data-level": "2", children: getSubCategories(l1)?.map((l2, idx2) => /* @__PURE__ */ jsxRuntime.jsxs(
13140
- "li",
13141
- {
13142
- className: "propeller-menu__item",
13143
- "data-level": "2",
13144
- "data-expanded": expandedL2 === l2.categoryId ? "true" : "false",
13145
- children: [
13146
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
13147
- /* @__PURE__ */ jsxRuntime.jsx(
13148
- "a",
13149
- {
13150
- className: "propeller-menu__link flex-1 pl-8 pr-4 py-2.5 text-sm text-foreground",
13151
- href: getCategoryUrl(l2),
13152
- onClick: (e) => handleItemClick(l2, e),
13153
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(l2) })
13154
- }
13155
- ),
13156
- getSubCategories(l2).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
13157
- "button",
13158
- {
13159
- type: "button",
13160
- className: "propeller-menu__toggle px-4 py-2.5 text-muted-foreground",
13161
- onClick: (event) => {
13162
- setExpandedL2(expandedL2 === l2.categoryId ? null : l2.categoryId);
13163
- },
13164
- children: /* @__PURE__ */ jsxRuntime.jsx(
13165
- "svg",
13166
- {
13167
- fill: "none",
13168
- stroke: "currentColor",
13169
- viewBox: "0 0 24 24",
13170
- className: `propeller-menu__chevron w-3.5 h-3.5 transition-transform ${expandedL2 === l2.categoryId ? "rotate-180" : ""}`,
13171
- children: /* @__PURE__ */ jsxRuntime.jsx(
13172
- "path",
13173
- {
13174
- strokeLinecap: "round",
13175
- strokeLinejoin: "round",
13176
- d: "m6 9 6 6 6-6",
13177
- strokeWidth: 2
13178
- }
13179
- )
13180
- }
13181
- )
13182
- }
13183
- ) : null
13184
- ] }),
13185
- expandedL2 === l2.categoryId && getSubCategories(l2).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "propeller-menu__list bg-accent/20", "data-level": "3", children: getSubCategories(l2)?.map((l3, idx3) => /* @__PURE__ */ jsxRuntime.jsx(
13186
- "li",
13187
- {
13188
- className: "propeller-menu__item",
13189
- "data-level": "3",
13190
- children: /* @__PURE__ */ jsxRuntime.jsx(
13191
- "a",
13192
- {
13193
- className: "propeller-menu__link block pl-12 pr-4 py-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
13194
- href: getCategoryUrl(l3),
13195
- onClick: (e) => handleItemClick(l3, e),
13196
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-menu__label", children: getCategoryName(l3) })
13197
- }
13198
- )
13199
- },
13200
- `l3-mobile-${l3.categoryId}-${idx3}`
13201
- )) }) : null
13202
- ]
13203
- },
13204
- `l2-mobile-${l2.categoryId}-${idx2}`
13205
- )) }) : null
13206
- ]
13207
- },
13208
- `l1-mobile-${l1.categoryId}-${idx}`
13209
- )) }) }) : null
13095
+ !isLoading && !hasError && menuCategories.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { className: `propeller-menu__nav md:hidden ${props.menuClass || ""}`, children: renderAccordion(menuCategories, 0) }) : null
13210
13096
  ]
13211
13097
  }
13212
13098
  );
@@ -18460,6 +18346,12 @@ function SearchBar(rawProps) {
18460
18346
  graphqlClient: props.graphqlClient,
18461
18347
  language: props.language,
18462
18348
  configuration: props.configuration || {},
18349
+ // `user` supplies userId/contactId/customerId to the autosuggest query.
18350
+ // Without it the dropdown's results diverge from the grid's: orderlist
18351
+ // scoping is driven by userId, so `orderlistIds` alone is ignored by the
18352
+ // backend and the dropdown shows the whole catalogue while the grid below
18353
+ // shows only the contract's products.
18354
+ user: props.user,
18463
18355
  companyId: props.companyId,
18464
18356
  orderlistIds: props.orderlistIds,
18465
18357
  applyOrderlists: props.applyOrderlists