@evenicanpm/storefront-core 2.0.0 → 2.1.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.
Files changed (125) hide show
  1. package/.storybook/main.ts +2 -3
  2. package/.storybook/preview.tsx +0 -2
  3. package/__mocks__/create-mutation.ts +16 -8
  4. package/__mocks__/next-image.tsx +12 -3
  5. package/package.json +2 -2
  6. package/src/api-manager/datasources/d365/d365-categories.datasource.ts +2 -3
  7. package/src/api-manager/datasources/d365/d365-order.datasource.ts +4 -4
  8. package/src/api-manager/datasources/d365/d365-organization.datasource.ts +15 -8
  9. package/src/api-manager/datasources/d365/d365-product.datasource.ts +31 -19
  10. package/src/api-manager/datasources/d365/d365-user.datasource.ts +47 -19
  11. package/src/api-manager/datasources/e4/address/e4-address.remaps.ts +2 -2
  12. package/src/api-manager/datasources/e4/cart/e4-cart.remaps.ts +1 -1
  13. package/src/api-manager/datasources/e4/product/e4-product.remaps.ts +3 -3
  14. package/src/api-manager/datasources/e4/user/e4-user.datasource.ts +4 -8
  15. package/src/api-manager/index.ts +10 -127
  16. package/src/api-manager/lib/get-graphql-client.ts +2 -2
  17. package/src/api-manager/schemas/product.schema.ts +9 -0
  18. package/src/api-manager/services/create-extension-query.ts +1 -1
  19. package/src/api-manager/services/create-query.ts +106 -266
  20. package/src/api-manager/types/Datasource.ts +0 -3
  21. package/src/cms/blocks/components/category-card.tsx +0 -1
  22. package/src/cms/blocks/components/category-carousel/index.tsx +0 -1
  23. package/src/cms/blocks/components/featured-categories.tsx +1 -2
  24. package/src/cms/blocks/components/featured-products.tsx +1 -2
  25. package/src/cms/blocks/components/footer/index.tsx +0 -1
  26. package/src/cms/blocks/components/footer/sections/footer-app-store.tsx +1 -1
  27. package/src/cms/blocks/components/footer/sections/footer-contact.tsx +0 -1
  28. package/src/cms/blocks/components/footer/sections/footer-links.tsx +1 -1
  29. package/src/cms/blocks/components/footer/sections/footer-logo.tsx +0 -1
  30. package/src/cms/blocks/components/footer/sections/footer-social-links.tsx +0 -1
  31. package/src/cms/blocks/components/footer.tsx +0 -1
  32. package/src/cms/blocks/components/hero-carousel/index.tsx +0 -1
  33. package/src/cms/blocks/components/hero.tsx +0 -1
  34. package/src/cms/blocks/components/image.tsx +0 -1
  35. package/src/cms/blocks/components/media-card.tsx +0 -1
  36. package/src/cms/blocks/components/product-carousel/index.tsx +0 -1
  37. package/src/cms/blocks/components/product-section-fullwidth/index.tsx +0 -1
  38. package/src/cms/blocks/components/rich-text.tsx +0 -1
  39. package/src/cms/blocks/components/seo/index.tsx +1 -2
  40. package/src/cms/blocks/components/services/index.tsx +0 -1
  41. package/src/cms/blocks/components/services/service-card.tsx +0 -1
  42. package/src/cms/blocks/components/shared/featured-product-card.tsx +0 -1
  43. package/src/cms/blocks/components/shared/product-category-item.tsx +1 -1
  44. package/src/cms/blocks/components/shared/product-grid.tsx +0 -1
  45. package/src/cms/blocks/components/shared/top-categories-card.tsx +0 -1
  46. package/src/cms/blocks/components/shared/top-rating-product-card.tsx +0 -1
  47. package/src/cms/blocks/icons/components/category.tsx +0 -1
  48. package/src/cms/blocks/icons/components/dotted-star.tsx +0 -1
  49. package/src/cms/blocks/icons/components/fallback-icon.tsx +0 -1
  50. package/src/cms/blocks/icons/components/gift-box.tsx +0 -1
  51. package/src/cms/blocks/icons/components/light.tsx +0 -1
  52. package/src/cms/blocks/icons/components/new-arrival.tsx +0 -1
  53. package/src/cms/blocks/icons/components/rank-badge.tsx +0 -1
  54. package/src/components/BazaarTextField.tsx +7 -7
  55. package/src/components/CountryInput.stories.tsx +4 -2
  56. package/src/components/T/__tests__/T.test.tsx +9 -13
  57. package/src/components/T/index.tsx +0 -1
  58. package/src/components/Typography.tsx +0 -1
  59. package/src/components/_tests_/site-logo.test.tsx +4 -5
  60. package/src/components/categories/category-list/category-list.tsx +1 -1
  61. package/src/components/countries-input.tsx +1 -1
  62. package/src/components/nav-link/nav-link.tsx +2 -8
  63. package/src/components/navbar/mega-menu/mega-menu.tsx +7 -1
  64. package/src/components/navbar/mobile-menu/mobile-menu.test.tsx +2 -1
  65. package/src/components/navbar/nav-list/cms-nav.test.tsx +0 -1
  66. package/src/components/no-records.tsx +0 -1
  67. package/src/components/product-cards/favorite-button.tsx +0 -1
  68. package/src/components/product-cards/product-card/styles/index.ts +2 -2
  69. package/src/components/product-cards/product-card-plp-list/ProductCardPlpList.stories.tsx +0 -1
  70. package/src/components/product-cards/product-card-search/ProductCardSearch.stories.tsx +0 -1
  71. package/src/components/product-dimensions/Dimensions.stories.tsx +2 -4
  72. package/src/components/product-dimensions/compound/dimensions-group-list-chip.tsx +1 -1
  73. package/src/components/product-dimensions/compound/dimensions.tsx +1 -1
  74. package/src/components/product-quantity-buttons/ProductQuantity.stories.tsx +1 -3
  75. package/src/components/product-quantity-buttons/__tests__/product-quantity-buttons.test.tsx +3 -2
  76. package/src/components/product-quantity-buttons/compound/quantity-buttons-root.tsx +1 -1
  77. package/src/components/product-quantity-buttons/index.tsx +0 -1
  78. package/src/components/product-quantity-variants/ProductQuantity.stories.tsx +1 -3
  79. package/src/components/products-view/ProductsGrid.stories.tsx +1 -3
  80. package/src/components/products-view/ProductsList.stories.tsx +1 -3
  81. package/src/components/products-view/__tests__/products-view.test.tsx +20 -9
  82. package/src/components/products-view/index.tsx +1 -1
  83. package/src/components/scrollbar/Scrollbar.stories.tsx +1 -3
  84. package/src/components/scrollbar/__tests__/scrollbar.test.tsx +7 -1
  85. package/src/components/search-bar/SearchBarLarge.stories.tsx +1 -3
  86. package/src/components/search-bar/compound/results-item-lg.tsx +0 -1
  87. package/src/components/search-bar/compound/results-item-sm.tsx +0 -1
  88. package/src/components/search-bar/compound/textfield-adornment-category.tsx +0 -1
  89. package/src/components/search-bar/compound/textfield.tsx +0 -1
  90. package/src/components/search-bar/utils/findCategoryNameById.ts +3 -3
  91. package/src/components/section/__tests__/section.test.tsx +14 -7
  92. package/src/components/side-nav/SideNav.stories.tsx +1 -1
  93. package/src/components/site-logo.tsx +8 -1
  94. package/src/components/wishlist-dialogs/add-to-wishlist/add-to-wishlist-button.tsx +1 -1
  95. package/src/components/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx +1 -1
  96. package/src/components/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-header.tsx +0 -1
  97. package/src/components/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx +1 -1
  98. package/src/hooks/use-nextauth-session.ts +4 -1
  99. package/src/lib/lib.ts +1 -1
  100. package/src/lib/page-slugs.ts +0 -2
  101. package/src/lib/refiner-utils.ts +3 -3
  102. package/src/pages/account/account-navigation.tsx +17 -20
  103. package/src/pages/account/addresses/address-form.tsx +15 -7
  104. package/src/pages/account/dashboard-header.tsx +1 -1
  105. package/src/pages/cart/checkout-form.tsx +1 -1
  106. package/src/pages/checkout/checkout-alt-form/checkout-step.tsx +1 -1
  107. package/src/pages/checkout/checkout-alt-form/steps/address/new-address-form.tsx +1 -1
  108. package/src/pages/checkout/checkout-alt-form/steps/payment/payment-details.tsx +5 -2
  109. package/src/pages/checkout/checkout-alt-summary/cart-item.tsx +1 -1
  110. package/src/pages/checkout/checkout-alt-summary/checkout-alt-summary.tsx +1 -1
  111. package/src/pages/confirmation/address.tsx +1 -1
  112. package/src/pages/confirmation/confirmation-summary.tsx +1 -1
  113. package/src/pages/product-details/currency.ts +1 -1
  114. package/src/pages/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +4 -1
  115. package/src/pages/product-list/breadcrumbs.tsx +0 -1
  116. package/src/pages/product-list/list-filter.tsx +0 -1
  117. package/src/pages/product-list/product-list-context.tsx +1 -1
  118. package/src/pages/product-list/product-list-view.tsx +2 -2
  119. package/src/pages/product-list/selected-facets.tsx +1 -1
  120. package/src/pages/quickorder/context.ts +8 -2
  121. package/src/pages/quickorder/order-upload.tsx +26 -8
  122. package/src/pages/quickorder/provider.tsx +8 -9
  123. package/src/pages/quickorder/quick-order.tsx +17 -11
  124. package/src/providers/nav-provider/index.tsx +1 -1
  125. package/tsconfig.json +0 -1
@@ -1,6 +1,5 @@
1
1
  import { Box, Container } from "@mui/material";
2
2
  import Grid from "@mui/material/Grid2";
3
- import React from "react";
4
3
 
5
4
  // Local components
6
5
  import MediaCard from "@/cms/blocks/components/media-card";
@@ -23,7 +22,7 @@ const FeaturedProducts = (productsData: FeaturedProductsBlock) => {
23
22
  size={3}
24
23
  display="flex"
25
24
  justifyContent="center"
26
- key={"product_index_" + i}
25
+ key={`product_index_${i}`}
27
26
  >
28
27
  <MediaCard
29
28
  name={product?.description ?? ""}
@@ -1,7 +1,6 @@
1
1
  // MUI
2
2
  import { Box, Container } from "@mui/material";
3
3
  import Grid from "@mui/material/Grid2";
4
- import React from "react";
5
4
  import type {
6
5
  FooterBlock,
7
6
  FooterResponse,
@@ -1,6 +1,6 @@
1
1
  import FlexBox from "@evenicanpm/storefront-core/src/components/flex-box/flex-box";
2
2
  import { Box } from "@mui/material";
3
- import React, { Fragment } from "react";
3
+ import { Fragment } from "react";
4
4
  import { MdFacebook as Facebook } from "react-icons/md";
5
5
  import { Link } from "react-router-dom";
6
6
 
@@ -1,6 +1,5 @@
1
1
  import { Paragraph } from "@evenicanpm/storefront-core/src/components/Typography";
2
2
  import Grid from "@mui/material/Grid2";
3
- import React from "react";
4
3
  import type { SocialLink } from "@/cms/blocks/components/footer/interfaces";
5
4
  import SocialLinks from "@/cms/blocks/components/footer/sections/footer-social-links";
6
5
  import { Heading } from "@/cms/blocks/components/footer/styles/index";
@@ -1,6 +1,6 @@
1
1
  import { Box } from "@mui/material";
2
2
  import Grid from "@mui/material/Grid2";
3
- import React, { Fragment } from "react";
3
+ import { Fragment } from "react";
4
4
  import type { Link } from "@/cms/blocks/components/footer/interfaces";
5
5
  import {
6
6
  Heading,
@@ -5,7 +5,6 @@ import { Paragraph } from "@evenicanpm/storefront-core/src/components/Typography
5
5
  import Grid from "@mui/material/Grid2";
6
6
  import useTheme from "@mui/material/styles/useTheme";
7
7
  import useMediaQuery from "@mui/material/useMediaQuery";
8
- import React from "react";
9
8
 
10
9
  interface Props {
11
10
  description: string;
@@ -4,7 +4,6 @@
4
4
  import FlexBox from "@evenicanpm/storefront-core/src/components/flex-box/flex-box";
5
5
  import IconButton from "@mui/material/IconButton";
6
6
  import styled from "@mui/material/styles/styled";
7
- import React from "react";
8
7
  import {
9
8
  FaGoogle as Google,
10
9
  FaInstagram as Instagram,
@@ -3,7 +3,6 @@
3
3
  import { Box, Container, Typography } from "@mui/material";
4
4
  import Grid from "@mui/material/Grid2";
5
5
  import { useTheme } from "@mui/material/styles";
6
- import React from "react";
7
6
  import {
8
7
  MdEmail as Email,
9
8
  MdLocationOn as LocationOn,
@@ -5,7 +5,6 @@
5
5
  import { Carousel } from "@evenicanpm/storefront-core/src/components/carousel/index";
6
6
  import CarouselCard1 from "@evenicanpm/storefront-core/src/components/carousel-cards/carousel-card-1/index";
7
7
  import { Box, Container } from "@mui/material";
8
- import React from "react";
9
8
  import type { HeroCarouselBlock, Slide } from "@/cms/blocks/interfaces";
10
9
  import { getImageUrl } from "@/cms/endpoints";
11
10
 
@@ -1,7 +1,6 @@
1
1
  import { Box, Button, Container, Typography } from "@mui/material";
2
2
  import Image from "next/image";
3
3
  import NextLink from "next/link";
4
- import React from "react";
5
4
  import type { HeroSectionBlock } from "@/cms/blocks/interfaces";
6
5
  import cmsEndPoints from "@/cms/endpoints";
7
6
 
@@ -1,6 +1,5 @@
1
1
  import { Container, Paper } from "@mui/material";
2
2
  import NextImage from "next/image";
3
- import React from "react";
4
3
  import type { Media } from "@/cms/blocks/interfaces";
5
4
  import { getImageUrl, type sizes } from "@/cms/endpoints";
6
5
 
@@ -3,7 +3,6 @@ import Card from "@mui/material/Card";
3
3
  import CardContent from "@mui/material/CardContent";
4
4
  import Typography from "@mui/material/Typography";
5
5
  import Image from "next/image";
6
- import React from "react";
7
6
 
8
7
  import cmsEndPoints from "@/cms/endpoints";
9
8
 
@@ -6,7 +6,6 @@ import ProductCard from "@evenicanpm/storefront-core/src/components/product-card
6
6
  import { Section } from "@evenicanpm/storefront-core/src/components/section";
7
7
  import type { SimpleProduct } from "@msdyn365-commerce/retail-proxy";
8
8
  import { Box } from "@mui/system";
9
- import React from "react";
10
9
  import { Light } from "@/cms/blocks/icons/index";
11
10
  import type { Product, ProductCarouselBlock } from "@/cms/blocks/interfaces";
12
11
  import { getImageUrl } from "@/cms/endpoints";
@@ -13,7 +13,6 @@ import type { SimpleProduct } from "@msdyn365-commerce/retail-proxy";
13
13
  import Grid from "@mui/material/Grid2";
14
14
  import Image from "next/image";
15
15
  import NextLink from "next/link";
16
- import React from "react";
17
16
  // Icons
18
17
  import { getIcon } from "@/cms/blocks/icons/index";
19
18
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Container } from "@mui/material";
4
4
  import Markdown from "marked-react";
5
- import React from "react";
6
5
 
7
6
  interface Props {
8
7
  content: string;
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { Helmet } from "react-helmet-async";
3
2
  import type { MetaItem, SeoPageData } from "@/cms/blocks/interfaces";
4
3
  import cmsEndPoints from "@/cms/endpoints";
@@ -35,7 +34,7 @@ const Seo = (pageData: SeoPageData) => {
35
34
  <meta name="googlebot" content="noindex"></meta>
36
35
  </>
37
36
  )}
38
- {pageData?.seo?.meta?.map((metaItem: MetaItem, i: number) => (
37
+ {pageData?.seo?.meta?.map((metaItem: MetaItem, _i: number) => (
39
38
  <meta
40
39
  name={metaItem.name}
41
40
  key={metaItem.id}
@@ -1,6 +1,5 @@
1
1
  import Container from "@mui/material/Container";
2
2
  import Grid from "@mui/material/Grid2";
3
- import React from "react";
4
3
  // LOCAL CUSTOM COMPONENTS
5
4
  import ServiceCard from "@/cms/blocks/components/services/service-card";
6
5
  import type {
@@ -9,7 +9,6 @@ import Card from "@mui/material/Card";
9
9
  import Fab from "@mui/material/Fab";
10
10
  import Grid from "@mui/material/Grid2";
11
11
  import styled from "@mui/material/styles/styled";
12
- import React from "react";
13
12
  // CUSTOM ICON COMPONENTS
14
13
  import { getIcon } from "@/cms/blocks/icons/index";
15
14
 
@@ -2,7 +2,6 @@
2
2
  import HoverBox from "@evenicanpm/storefront-core/src/components/HoverBox";
3
3
  import Image from "@evenicanpm/storefront-core/src/components/Image";
4
4
  import { H4 } from "@evenicanpm/storefront-core/src/components/Typography";
5
- import React from "react";
6
5
 
7
6
  // ==========================================================
8
7
  type Props = { title: string; imgUrl: string };
@@ -3,7 +3,7 @@ import BazaarImage from "@evenicanpm/storefront-core/src/components/BazaarImage"
3
3
  // GLOBAL CUSTOM COMPONENTS
4
4
  import { H4 } from "@evenicanpm/storefront-core/src/components/Typography";
5
5
  import { type SxProps, styled, type Theme } from "@mui/material/styles";
6
- import React, { type HtmlHTMLAttributes } from "react";
6
+ import type HtmlHTMLAttributes from "react";
7
7
 
8
8
  // STYLED COMPONENT
9
9
  const StyledBazaarCard = styled(BazaarCard)(({ theme }) => ({
@@ -3,7 +3,6 @@ import ProductCard from "@evenicanpm/storefront-core/src/components/product-card
3
3
  import { Section } from "@evenicanpm/storefront-core/src/components/section";
4
4
  import Box from "@mui/material/Box";
5
5
  import Grid from "@mui/material/Grid2";
6
- import React from "react";
7
6
 
8
7
  // CUSTOM DATA MODEL
9
8
 
@@ -6,7 +6,6 @@ import Card from "@mui/material/Card";
6
6
  import Chip from "@mui/material/Chip";
7
7
  import { useTheme } from "@mui/material/styles";
8
8
  import styled from "@mui/material/styles/styled";
9
- import React from "react";
10
9
 
11
10
  // STYLED COMPONENT
12
11
  const StyledChip = styled(Chip)({
@@ -9,7 +9,6 @@ import {
9
9
  // CUSTOM UTILS LIBRARY FUNCTION
10
10
  import { currency } from "@evenicanpm/storefront-core/src/lib/lib";
11
11
  import Rating from "@mui/material/Rating";
12
- import React from "react";
13
12
 
14
13
  // ======================================================
15
14
  interface Props {
@@ -2,7 +2,6 @@
2
2
  import type { OverridableComponent } from "@mui/material/OverridableComponent";
3
3
  import type { SvgIconTypeMap } from "@mui/material/SvgIcon";
4
4
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
5
- import React from "react";
6
5
 
7
6
  const Category: OverridableComponent<SvgIconTypeMap> = createSvgIcon(
8
7
  <svg fill="currentColor" viewBox="0 0 64 64">
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
4
- import React from "react";
5
4
 
6
5
  const DottedStar = createSvgIcon(
7
6
  <svg fill="currentColor" viewBox="0 0 24 24">
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
4
- import React from "react";
5
4
 
6
5
  const FallbackIcon = createSvgIcon(
7
6
  <svg
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
4
- import React from "react";
5
4
 
6
5
  const GiftBox = createSvgIcon(
7
6
  <svg fill="currentColor" viewBox="0 0 22 20">
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
4
- import React from "react";
5
4
 
6
5
  const Light = createSvgIcon(
7
6
  <svg fill="currentColor" viewBox="0 0 24 24">
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
4
- import React from "react";
5
4
 
6
5
  const NewArrival = createSvgIcon(
7
6
  <svg fill="currentColor" viewBox="0 0 24 24">
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
  import createSvgIcon from "@mui/material/utils/createSvgIcon";
3
- import React from "react";
4
3
 
5
4
  const RankBadge = createSvgIcon(
6
5
  <svg fill="currentColor" viewBox="0 0 24 24">
@@ -12,20 +12,20 @@ export default function BazaarTextField({
12
12
  InputProps,
13
13
  ...props
14
14
  }: Props) {
15
- const boxProps: BoxProps = {};
16
- const textFieldProps: TextFieldProps = {};
15
+ const boxProps: Record<string, unknown> = {};
16
+ const textFieldProps: Record<string, unknown> = {};
17
17
 
18
18
  // Splits props into Box and TextField props. Bracket notation allows dynamic names like "mt" or "mb".
19
- for (const key in props) {
19
+ for (const [key, value] of Object.entries(props)) {
20
20
  if (SPACE_PROPS_LIST.has(key)) {
21
- (boxProps as any)[key] = (props as any)[key];
21
+ boxProps[key] = value;
22
22
  } else {
23
- (textFieldProps as any)[key] = (props as any)[key];
23
+ textFieldProps[key] = value;
24
24
  }
25
25
  }
26
26
 
27
27
  return (
28
- <Box {...boxProps}>
28
+ <Box {...(boxProps as BoxProps)}>
29
29
  {/* INPUT LEVEL TEXT */}
30
30
  {label ? (
31
31
  <H6 mb={1} fontSize={13} color="grey.700">
@@ -39,7 +39,7 @@ export default function BazaarTextField({
39
39
  ...InputProps,
40
40
  style: { ...InputProps?.style, height: 44 },
41
41
  }}
42
- {...textFieldProps}
42
+ {...(textFieldProps as TextFieldProps)}
43
43
  />
44
44
  </Box>
45
45
  );
@@ -1,3 +1,4 @@
1
+ import type { CountryRegionInfo } from "@msdyn365-commerce/retail-proxy";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { useState } from "react";
3
4
  import { countries } from "../../__mocks__/countries";
@@ -12,8 +13,9 @@ const meta = {
12
13
  export default meta;
13
14
  type Story = StoryObj<typeof CountryInput>;
14
15
 
15
- const Template = (args: any) => {
16
- const [selectedCountry, setSelectedCountry] = useState(null);
16
+ const Template = (args: React.ComponentProps<typeof CountryInput>) => {
17
+ const [selectedCountry, setSelectedCountry] =
18
+ useState<CountryRegionInfo | null>(null);
17
19
  console.log(selectedCountry);
18
20
 
19
21
  return (
@@ -1,5 +1,5 @@
1
1
  import { render, screen } from "@testing-library/react";
2
- import { vi } from "vitest";
2
+ import { describe, expect, it, vi } from "vitest";
3
3
  import T from "../index";
4
4
 
5
5
  vi.mock("next-intl", () => ({
@@ -19,7 +19,7 @@ vi.mock("next-intl", () => ({
19
19
  describe("T (Translation Component)", () => {
20
20
  it("renders translation for given path", () => {
21
21
  render(<T path="HomePage.welcome" />);
22
- expect(screen.getByText("Welcome to our store")).toBeInTheDocument();
22
+ expect(screen.getByText("Welcome to our store")).toBeTruthy();
23
23
  });
24
24
 
25
25
  it("renders multiple translations", () => {
@@ -36,17 +36,17 @@ describe("T (Translation Component)", () => {
36
36
 
37
37
  it("renders fallback path when translation not found", () => {
38
38
  render(<T path="Unknown.path" />);
39
- expect(screen.getByText("Unknown.path")).toBeInTheDocument();
39
+ expect(screen.getByText("Unknown.path")).toBeTruthy();
40
40
  });
41
41
 
42
42
  it("handles nested translation paths", () => {
43
43
  render(<T path="Navigation.home" />);
44
- expect(screen.getByText("Home")).toBeInTheDocument();
44
+ expect(screen.getByText("Home")).toBeTruthy();
45
45
  });
46
46
 
47
47
  it("renders common translations", () => {
48
48
  render(<T path="Common.loading" />);
49
- expect(screen.getByText("Loading...")).toBeInTheDocument();
49
+ expect(screen.getByText("Loading...")).toBeTruthy();
50
50
  });
51
51
 
52
52
  it("renders multiple different paths together", () => {
@@ -63,17 +63,13 @@ describe("T (Translation Component)", () => {
63
63
 
64
64
  it("renders translation with special characters", () => {
65
65
  render(<T path="Common.error" />);
66
- expect(screen.getByText("An error occurred")).toBeInTheDocument();
66
+ expect(screen.getByText("An error occurred")).toBeTruthy();
67
67
  });
68
68
 
69
69
  it("accepts dynamic paths", () => {
70
70
  const paths = ["HomePage.welcome", "Navigation.home", "Common.loading"];
71
71
  const { container } = render(
72
- <>
73
- {paths.map((path) => (
74
- <T key={path} path={path} />
75
- ))}
76
- </>,
72
+ paths.map((path) => <T key={path} path={path} />),
77
73
  );
78
74
  const text = container.textContent || "";
79
75
  expect(text).toContain("Welcome to our store");
@@ -83,9 +79,9 @@ describe("T (Translation Component)", () => {
83
79
 
84
80
  it("re-renders when path changes", () => {
85
81
  const { rerender } = render(<T path="HomePage.welcome" />);
86
- expect(screen.getByText("Welcome to our store")).toBeInTheDocument();
82
+ expect(screen.getByText("Welcome to our store")).toBeTruthy();
87
83
 
88
84
  rerender(<T path="Navigation.home" />);
89
- expect(screen.getByText("Home")).toBeInTheDocument();
85
+ expect(screen.getByText("Home")).toBeTruthy();
90
86
  });
91
87
  });
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { useTranslations } from "next-intl";
4
- import React from "react";
5
4
 
6
5
  interface Props {
7
6
  path: string;
@@ -3,7 +3,6 @@
3
3
  import Box, { type BoxProps } from "@mui/material/Box";
4
4
  import styled from "@mui/material/styles/styled";
5
5
  import clsx from "clsx";
6
- import React from "react";
7
6
 
8
7
  // ==============================================================
9
8
  type Ellipsis = { ellipsis: number };
@@ -15,11 +15,10 @@ vi.mock("next/link", () => ({
15
15
  describe("SiteLogo", () => {
16
16
  it("renders logo image", () => {
17
17
  render(<SiteLogo />);
18
- expect(screen.getByAltText("E4 Logo")).toBeInTheDocument();
19
- expect(screen.getByAltText("E4 Logo")).toHaveAttribute(
20
- "src",
21
- "/logo-blue.png",
22
- );
18
+ const logo = screen.getByAltText("E4 Logo");
19
+ expect(logo).toBeInTheDocument();
20
+ // next/image rewrites src to an optimized URL (e.g. /_next/image?url=...)
21
+ expect(logo.getAttribute("src")).toMatch(/logo-blue\.png/);
23
22
  });
24
23
 
25
24
  it("wraps logo in home link", () => {
@@ -9,7 +9,7 @@ import CategoryListItem from "@evenicanpm/storefront-core/src/components/categor
9
9
  import MegaMenu1 from "@evenicanpm/storefront-core/src/components/categories/mega-menu/mega-menu-1";
10
10
  import MegaMenu2 from "@evenicanpm/storefront-core/src/components/categories/mega-menu/mega-menu-2";
11
11
  import type { CategoryHierarchy } from "@evenicanpm/storefront-core/src/lib/category-helpers";
12
- import React, { createContext, type ReactNode, useContext } from "react";
12
+ import { createContext, type ReactNode, useContext } from "react";
13
13
 
14
14
  type MegaMenuType = "default" | "mega-menu-1" | "mega-menu-2";
15
15
 
@@ -28,7 +28,7 @@ export default function CountryInput({
28
28
 
29
29
  const renderOption = (
30
30
  props: React.HTMLAttributes<HTMLLIElement> & {
31
- key: any;
31
+ key: string | number;
32
32
  },
33
33
  option: CountryRegionInfo,
34
34
  ) => {
@@ -46,14 +46,8 @@ export default function NavLink({
46
46
  pathname,
47
47
  ...props
48
48
  }: Readonly<NavLinkProps>) {
49
- let resolvedPathname = pathname;
50
- if (resolvedPathname === undefined) {
51
- try {
52
- resolvedPathname = usePathname() ?? "";
53
- } catch {
54
- resolvedPathname = "";
55
- }
56
- }
49
+ const pathFromHook = usePathname();
50
+ const resolvedPathname = pathname ?? pathFromHook ?? "";
57
51
 
58
52
  return (
59
53
  <StyledLink
@@ -26,7 +26,13 @@ type MegaMenuContextType = {
26
26
  checkOverflow: () => void;
27
27
  };
28
28
  const MegaMenuContext = createContext<MegaMenuContextType | null>(null);
29
- const useMegaMenu = () => useContext(MegaMenuContext)!;
29
+ const useMegaMenu = () => {
30
+ const context = useContext(MegaMenuContext);
31
+ if (!context) {
32
+ throw new Error("useMegaMenu must be used within MegaMenu");
33
+ }
34
+ return context;
35
+ };
30
36
 
31
37
  const Grid2Size = (length: number) => {
32
38
  if (length === 1) return 12;
@@ -1,6 +1,7 @@
1
1
  import MobileMenu from "@evenicanpm/storefront-core/src/components/navbar/mobile-menu/mobile-menu";
2
2
  import { transformCmsNav } from "@evenicanpm/storefront-core/src/components/navbar/utils/transform-nav";
3
3
  import { fireEvent, render, screen } from "@testing-library/react";
4
+ import type React from "react";
4
5
  import { beforeEach, describe, it, vi } from "vitest";
5
6
  import type { CmsNavItem } from "@/cms/interfaces/navigation";
6
7
 
@@ -11,7 +12,7 @@ vi.mock("@evenicanpm/storefront-core/src/providers/nav-provider", () => {
11
12
  return {
12
13
  NavContext: {
13
14
  // We'll replace these in beforeEach per test
14
- Provider: ({ value, children }: any) => (
15
+ Provider: ({ children }: { children: React.ReactNode }) => (
15
16
  <div data-testid="nav-context-provider">{children}</div>
16
17
  ),
17
18
  },
@@ -1,7 +1,6 @@
1
1
  import NavCms from "@evenicanpm/storefront-core/src/components/navbar/nav-list/index";
2
2
  import { NavContext } from "@evenicanpm/storefront-core/src/providers/nav-provider";
3
3
  import { render, screen } from "@testing-library/react";
4
- import React from "react";
5
4
  import { describe, expect, it } from "vitest";
6
5
 
7
6
  describe("NavCms", () => {
@@ -1,7 +1,6 @@
1
1
  import { H4 } from "@evenicanpm/storefront-core/src/components/Typography";
2
2
  import { Box } from "@mui/material";
3
3
  import { useTranslations } from "next-intl";
4
- import React from "react";
5
4
 
6
5
  type Props = { message: string };
7
6
 
@@ -3,7 +3,6 @@
3
3
  import Favorite from "@mui/icons-material/Favorite";
4
4
  import FavoriteBorder from "@mui/icons-material/FavoriteBorder";
5
5
  import IconButton, { type IconButtonProps } from "@mui/material/IconButton";
6
- import React from "react";
7
6
 
8
7
  export interface FavoriteButtonProps extends Omit<IconButtonProps, "onClick"> {
9
8
  isFavorite: boolean;
@@ -46,7 +46,7 @@ export const ContentWrapper = styled("div")({
46
46
  },
47
47
  });
48
48
 
49
- const StyledBazaarCardType: StyledComponent<typeof BazaarCard, {}, "div"> =
50
- StyledBazaarCard as StyledComponent<typeof BazaarCard, {}, "div">;
49
+ const StyledBazaarCardType: StyledComponent<typeof BazaarCard, object, "div"> =
50
+ StyledBazaarCard as StyledComponent<typeof BazaarCard, object, "div">;
51
51
 
52
52
  export default StyledBazaarCardType;
@@ -1,5 +1,4 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
- import React from "react";
3
2
  import { data } from "../../../../__mocks__/products";
4
3
  import { ProductCardPlpList } from "./index";
5
4
 
@@ -1,6 +1,5 @@
1
1
  import { Box } from "@mui/material";
2
2
  import type { Meta, StoryObj } from "@storybook/react";
3
- import React from "react";
4
3
  import { data } from "../../../../__mocks__/products";
5
4
  import ProductCardSearch from "./index";
6
5
 
@@ -1,7 +1,6 @@
1
1
  // Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
2
2
 
3
- import type { Meta, StoryObj } from "@storybook/react";
4
- import React from "react";
3
+ import type { Meta } from "@storybook/react";
5
4
  import useVariants from "../../hooks/use-variants";
6
5
  import { data, product } from "./__mocks__/data";
7
6
  import { Dimensions } from "./compound/dimensions";
@@ -13,7 +12,6 @@ const meta = {
13
12
  } satisfies Meta<typeof Dimensions>;
14
13
 
15
14
  export default meta;
16
- type Story = StoryObj<typeof meta>;
17
15
 
18
16
  export const Interactive = () => {
19
17
  const { handleChangeVariant, selectDimensions } = useVariants(product);
@@ -24,7 +22,7 @@ export const Interactive = () => {
24
22
  handleChangeVariant={handleChangeVariant}
25
23
  showDimensionError={true}
26
24
  >
27
- {data.dimensionGroups.map((group, i) => (
25
+ {data.dimensionGroups.map((group, _i) => (
28
26
  <Dimensions.Group dimensions={group}>
29
27
  <Dimensions.Group.Label />
30
28
  <Dimensions.Group.List />
@@ -8,7 +8,7 @@ import {
8
8
  type ProductDimensionValueInventoryAvailability,
9
9
  } from "@msdyn365-commerce/retail-proxy";
10
10
  import { Chip } from "@mui/material";
11
- import React, { useContext } from "react";
11
+ import { useContext } from "react";
12
12
 
13
13
  /**
14
14
  * @category Props
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { DimensionGroup } from "@evenicanpm/storefront-core/src/components/product-dimensions/compound/dimensions-group";
3
3
  import type { ProductDimensionValueInventoryAvailability } from "@msdyn365-commerce/retail-proxy";
4
- import React, {
4
+ import {
5
5
  createContext,
6
6
  type PropsWithChildren,
7
7
  type ReactElement,
@@ -1,7 +1,6 @@
1
1
  // Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
2
2
 
3
- import type { Meta, StoryObj } from "@storybook/react";
4
- import React from "react";
3
+ import type { Meta } from "@storybook/react";
5
4
  import { QuantityButtons } from "./compound/quantity-buttons-root";
6
5
 
7
6
  const meta = {
@@ -11,7 +10,6 @@ const meta = {
11
10
  } satisfies Meta<typeof QuantityButtons>;
12
11
 
13
12
  export default meta;
14
- type Story = StoryObj<typeof meta>;
15
13
 
16
14
  export const Interactive = () => {
17
15
  return (