@jotul/jotul-widgets 1.2.0 → 1.2.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.
@@ -4,5 +4,5 @@ import type { JotulWidgetProps } from './types';
4
4
  export { DEFAULT_WIDGET_LOCALE_TAG, normalizeWidgetLocale, resolveWidgetUiLocale, } from './i18n/widgetStrings';
5
5
  export type { JotulWidgetLocale } from './i18n/widgetStrings';
6
6
  export { checkWidgetAuthorization, searchLocationSuggestions, searchDealersByCoordinates, searchDealersByPostalCode, };
7
- export type { CheckWidgetAuthorizationOptions, DealerSearchResponse, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetProps, WidgetTriggerRenderProps, JotulWidgetStyling, JotulWidgetType, WidgetAuthClientResponse, } from './types';
8
- export declare function JotulWidget({ type, endpoint, className, productName, locale: localeProp, market: marketProp, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }: JotulWidgetProps): import("react/jsx-runtime").JSX.Element;
7
+ export type { CheckWidgetAuthorizationOptions, DealerSearchResponse, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetProps, JotulWidgetScope, WidgetTriggerRenderProps, JotulWidgetStyling, JotulWidgetType, WidgetAuthClientResponse, } from './types';
8
+ export declare function JotulWidget({ type, endpoint, className, productName, locale: localeProp, market: marketProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }: JotulWidgetProps): import("react/jsx-runtime").JSX.Element;
@@ -28,7 +28,7 @@ const MARKET_FALLBACK_CENTER = {
28
28
  FI: [60.1699, 24.9384],
29
29
  DE: [52.52, 13.405],
30
30
  };
31
- export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, market: marketProp, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }) {
31
+ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, market: marketProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }) {
32
32
  const resolvedUiLocale = useMemo(() => resolveWidgetUiLocale(localeProp, marketProp), [localeProp, marketProp]);
33
33
  const t = WIDGET_STRINGS[resolvedUiLocale];
34
34
  const apiLocaleTag = useMemo(() => (localeProp?.trim() ? localeProp.trim() : DEFAULT_WIDGET_LOCALE_TAG), [localeProp]);
@@ -65,9 +65,10 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
65
65
  endpoint,
66
66
  locale: apiLocaleTag,
67
67
  market: apiMarket,
68
+ scope,
68
69
  brands,
69
70
  campaignSlug: productPageCampaignSlug,
70
- }), [apiLocaleTag, apiMarket, brands, endpoint, productPageCampaignSlug]);
71
+ }), [apiLocaleTag, apiMarket, brands, endpoint, productPageCampaignSlug, scope]);
71
72
  const runDealerSearchByCoordinates = useCallback(async (latitude, longitude) => {
72
73
  setLocationError(null);
73
74
  setIsSearching(true);
@@ -80,7 +81,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
80
81
  finally {
81
82
  setIsSearching(false);
82
83
  }
83
- }, [dealerSearchOptions]);
84
+ }, [dealerSearchOptions, scope]);
84
85
  const runFallbackDealerSearch = useCallback(() => {
85
86
  const fallbackCenter = (apiMarket != null ? MARKET_FALLBACK_CENTER[apiMarket] : undefined) ??
86
87
  MARKET_FALLBACK_CENTER.NO;
@@ -269,7 +270,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
269
270
  return _jsx("div", { className: rootClass, children: getSafeWidgetErrorMessage(auth?.error, t) });
270
271
  }
271
272
  if (widgetType === 'productPage') {
272
- return (_jsx("div", { className: rootClass, children: _jsx(ProductPageWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
273
+ return (_jsx("div", { className: rootClass, children: _jsx(ProductPageWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
273
274
  ? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
274
275
  : searchResult, mapSearchResult: mapSearchResult?.ok === false
275
276
  ? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
@@ -349,7 +350,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
349
350
  transform: isOpen ? 'translateX(0)' : 'translateX(100%)',
350
351
  transition: 'transform 300ms ease-out',
351
352
  willChange: 'transform',
352
- }, "aria-hidden": !isOpen, children: drawerLoading ? (_jsxs("div", { className: "jwi-flex jwi-h-full jwi-w-full jwi-bg-white", children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-1/2 jwi-flex-col jwi-overflow-hidden", children: _jsxs("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-gap-3 jwi-overflow-hidden jwi-bg-white jwi-p-6", children: [_jsx("div", { className: "jwi-h-12 jwi-w-full jwi-animate-pulse jwi-rounded-[10px] jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }), _jsxs("div", { className: "jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] }) }), _jsx("div", { className: "jwi-h-full jwi-w-1/2 jwi-bg-[#e8eef1]" })] })) : (_jsx(FindDealerDrawerWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
353
+ }, "aria-hidden": !isOpen, children: drawerLoading ? (_jsxs("div", { className: "jwi-flex jwi-h-full jwi-w-full jwi-bg-white", children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-1/2 jwi-flex-col jwi-overflow-hidden", children: _jsxs("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-gap-3 jwi-overflow-hidden jwi-bg-white jwi-p-6", children: [_jsx("div", { className: "jwi-h-12 jwi-w-full jwi-animate-pulse jwi-rounded-[10px] jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }), _jsxs("div", { className: "jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] }) }), _jsx("div", { className: "jwi-h-full jwi-w-1/2 jwi-bg-[#e8eef1]" })] })) : (_jsx(FindDealerDrawerWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
353
354
  ? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
354
355
  : searchResult, mapSearchResult: mapSearchResult?.ok === false
355
356
  ? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
package/dist/api.js CHANGED
@@ -13,6 +13,9 @@ function appendLocaleAndMarket(params, options) {
13
13
  params.set('market', upper);
14
14
  }
15
15
  }
16
+ if (options?.scope === 'ildstedet') {
17
+ params.set('dealerScope', options.scope);
18
+ }
16
19
  }
17
20
  export async function checkWidgetAuthorization(options) {
18
21
  const endpoint = options?.endpoint ?? '/api/jotul/widget';
@@ -1,12 +1,13 @@
1
1
  import 'leaflet/dist/leaflet.css';
2
2
  import 'leaflet.markercluster/dist/MarkerCluster.css';
3
3
  import type { WidgetStrings } from '../i18n/widgetStrings';
4
- import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, LocationSuggestion } from '../types';
4
+ import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
5
5
  type FindDealerDrawerWidgetProps = {
6
6
  t: WidgetStrings;
7
7
  buttonStyling?: JotulWidgetButtonStyling;
8
8
  borderStyling?: JotulWidgetBorderStyling;
9
9
  market?: string;
10
+ scope?: JotulWidgetScope;
10
11
  isSearching: boolean;
11
12
  locationError: string | null;
12
13
  searchResult: DealerSearchResponse | null;
@@ -35,5 +36,5 @@ type FindDealerDrawerWidgetProps = {
35
36
  }) => void;
36
37
  onClose: () => void;
37
38
  };
38
- export declare function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }: FindDealerDrawerWidgetProps): import("react/jsx-runtime").JSX.Element;
39
+ export declare function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }: FindDealerDrawerWidgetProps): import("react/jsx-runtime").JSX.Element;
39
40
  export {};
@@ -17,7 +17,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
17
17
  import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
18
18
  import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
19
19
  import { JOTUL_BRAND_PRIMARY_HEX } from '../constants';
20
+ import { isExclusiveDealer } from '../utils';
20
21
  const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
22
+ const EMPTY_DEALERS = [];
21
23
  function mapPointsBoundsKey(points, defaultCenter) {
22
24
  const body = points.length === 0
23
25
  ? ''
@@ -49,16 +51,7 @@ function getDealerMapPoint(dealer) {
49
51
  const longitude = readNumber(dealer.longitude);
50
52
  if (latitude == null || longitude == null)
51
53
  return null;
52
- const rawExclusive = dealer.exclusive;
53
- const isExclusive = rawExclusive === true ||
54
- rawExclusive === 1 ||
55
- rawExclusive === '1' ||
56
- rawExclusive === 'true' ||
57
- rawExclusive === 'TRUE' ||
58
- rawExclusive === 'yes' ||
59
- rawExclusive === 'YES' ||
60
- rawExclusive === 'y' ||
61
- rawExclusive === 'Y';
54
+ const isExclusive = isExclusiveDealer(dealer);
62
55
  return { dealerName: getDealerName(dealer), latitude, longitude, isExclusive };
63
56
  }
64
57
  function toAssetSrc(value) {
@@ -229,9 +222,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
229
222
  }, [map, pointsBoundsKey, clusterThemeKey]);
230
223
  return null;
231
224
  }
232
- export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }) {
233
- const dealers = (searchResult?.dealers ?? []);
234
- const mapDealers = (mapSearchResult?.dealers ?? dealers);
225
+ export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }) {
226
+ const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
227
+ const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
228
+ const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
229
+ const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
235
230
  const total = dealers.length;
236
231
  const inquiryFormOpen = inquiryValues != null;
237
232
  const [activeDealerName, setActiveDealerName] = useState(null);
@@ -1,12 +1,13 @@
1
1
  import 'leaflet/dist/leaflet.css';
2
2
  import 'leaflet.markercluster/dist/MarkerCluster.css';
3
3
  import type { WidgetStrings } from '../i18n/widgetStrings';
4
- import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, LocationSuggestion } from '../types';
4
+ import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
5
5
  type ProductPageWidgetProps = {
6
6
  t: WidgetStrings;
7
7
  buttonStyling?: JotulWidgetButtonStyling;
8
8
  borderStyling?: JotulWidgetBorderStyling;
9
9
  market?: string;
10
+ scope?: JotulWidgetScope;
10
11
  isSearching: boolean;
11
12
  locationError: string | null;
12
13
  searchResult: DealerSearchResponse | null;
@@ -35,5 +36,5 @@ type ProductPageWidgetProps = {
35
36
  }) => void;
36
37
  onClosePopup?: () => void;
37
38
  };
38
- export declare function ProductPageWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }: ProductPageWidgetProps): import("react/jsx-runtime").JSX.Element;
39
+ export declare function ProductPageWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }: ProductPageWidgetProps): import("react/jsx-runtime").JSX.Element;
39
40
  export {};
@@ -18,7 +18,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
18
18
  import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
19
19
  import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
20
20
  import { JOTUL_BRAND_PRIMARY_HEX, R10 } from '../constants';
21
+ import { isExclusiveDealer } from '../utils';
21
22
  const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
23
+ const EMPTY_DEALERS = [];
22
24
  function mapPointsBoundsKey(points, defaultCenter) {
23
25
  const body = points.length === 0
24
26
  ? ''
@@ -52,16 +54,7 @@ function getDealerMapPoint(dealer) {
52
54
  const longitude = readNumber(dealer.longitude);
53
55
  if (latitude == null || longitude == null)
54
56
  return null;
55
- const rawExclusive = dealer.exclusive;
56
- const isExclusive = rawExclusive === true ||
57
- rawExclusive === 1 ||
58
- rawExclusive === '1' ||
59
- rawExclusive === 'true' ||
60
- rawExclusive === 'TRUE' ||
61
- rawExclusive === 'yes' ||
62
- rawExclusive === 'YES' ||
63
- rawExclusive === 'y' ||
64
- rawExclusive === 'Y';
57
+ const isExclusive = isExclusiveDealer(dealer);
65
58
  return {
66
59
  dealer,
67
60
  dealerName: getDealerName(dealer),
@@ -236,9 +229,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
236
229
  }, [map, pointsBoundsKey, clusterThemeKey]);
237
230
  return null;
238
231
  }
239
- export function ProductPageWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }) {
240
- const dealers = (searchResult?.dealers ?? []);
241
- const mapDealers = (mapSearchResult?.dealers ?? dealers);
232
+ export function ProductPageWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }) {
233
+ const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
234
+ const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
235
+ const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
236
+ const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
242
237
  const total = dealers.length;
243
238
  const inquiryFormOpen = inquiryValues != null;
244
239
  const [activeDealerName, setActiveDealerName] = useState(null);
@@ -6,7 +6,7 @@ import { TelephoneIcon } from '../../icons/TelephoneIcon';
6
6
  import { getWidgetPrimaryButtonPresentation } from '../../utils/widgetPrimaryButtonPresentation';
7
7
  import exclusiveDealerBadge from '../../images/jotul-exclusive-dealer.png';
8
8
  import ildstedetDealer from '../../images/ildstedet-dealer.svg';
9
- import { asText, formatDistance, getDealerAddressLines, getDealerKey, getDealerName, } from '../../utils';
9
+ import { asText, formatDistance, getDealerAddressLines, getDealerKey, getDealerName, isExclusiveDealer, } from '../../utils';
10
10
  export function DealerList({ dealers, total, selectedDealerName, activeDealerName = null, maxHeightClassName = 'jwi-max-h-[min(60vh,480px)]', fitAvailableHeight = false, autoScrollToActive = false, enableInternalScroll = true, headerRight, t, buttonStyling, borderStyling, market, onStartInquiry, onSelectDealer, }) {
11
11
  const cardRefs = useRef({});
12
12
  useEffect(() => {
@@ -17,7 +17,7 @@ export function DealerList({ dealers, total, selectedDealerName, activeDealerNam
17
17
  return;
18
18
  card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
19
19
  }, [activeDealerName, autoScrollToActive]);
20
- const defaultBorderColor = borderStyling?.borderColor ?? '#e6e1d7';
20
+ const activeBorderColor = borderStyling?.borderColor?.trim();
21
21
  const inquiryCta = getWidgetPrimaryButtonPresentation(buttonStyling, 'panel', {
22
22
  extraClassName: 'jwi-w-full jwi-max-w-full jwi-shrink-0 jwi-justify-between jwi-gap-2 md:jwi-max-w-[220px]',
23
23
  });
@@ -30,13 +30,11 @@ export function DealerList({ dealers, total, selectedDealerName, activeDealerNam
30
30
  const dealerName = getDealerName(dealer, t.unknownDealer);
31
31
  const isSelectedDealer = selectedDealerName === dealerName;
32
32
  const isActiveDealer = activeDealerName === dealerName;
33
- const isExclusive = dealer.exclusive === true ||
34
- dealer.exclusive === 1 ||
35
- dealer.exclusive === '1';
33
+ const isExclusive = isExclusiveDealer(dealer);
36
34
  return (_jsxs("div", { ref: (element) => {
37
35
  cardRefs.current[dealerName] = element;
38
- }, className: `jwi-w-full jwi-cursor-pointer ${R10} jwi-border jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)] ${isActiveDealer ? 'jwi-border-[#ef2b18]' : ''}`, style: !isActiveDealer && defaultBorderColor !== '#e6e1d7'
39
- ? { borderColor: defaultBorderColor }
36
+ }, className: `jwi-w-full jwi-cursor-pointer ${R10} jwi-border jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)] ${isActiveDealer ? 'jwi-border-[#ef2b18]' : ''}`, style: isActiveDealer && activeBorderColor
37
+ ? { borderColor: activeBorderColor }
40
38
  : undefined, onClick: () => onSelectDealer?.(dealerName), children: [_jsxs("div", { className: "jwi-flex jwi-items-start jwi-justify-between jwi-gap-3", children: [_jsx("div", { className: "jwi-min-w-0 jwi-max-w-[calc(100%-5rem)] jwi-pr-1", children: _jsxs("div", { className: "jwi-flex jwi-items-center jwi-gap-2", children: [isExclusive && (() => {
41
39
  const badgeImage = market === 'NO' ? ildstedetDealer : exclusiveDealerBadge;
42
40
  const badgeAlt = market === 'NO' ? 'Ildstedet dealer' : 'Jotul exclusive dealer';
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { CSSProperties, ReactNode } from 'react';
2
2
  export type JotulWidgetType = 'productPage' | 'findDealerDrawer' | 'dealerFinder' | 'warrantyForm';
3
+ export type JotulWidgetScope = 'ildstedet';
3
4
  export type WidgetAuthClientResponse = {
4
5
  apiVersion?: string;
5
6
  ok: boolean;
@@ -49,6 +50,7 @@ export type CheckWidgetAuthorizationOptions = {
49
50
  locale?: string;
50
51
  /** ISO 3166-1 alpha-2 market/country (e.g. `NO`, `SE`) sent to the API as `market`. */
51
52
  market?: string;
53
+ scope?: JotulWidgetScope;
52
54
  brands?: string[];
53
55
  /** Optional Sanity campaign slug used to limit dealer results to campaign dealers. */
54
56
  campaignSlug?: string;
@@ -82,6 +84,7 @@ export type JotulWidgetProps = {
82
84
  locale?: string;
83
85
  /** ISO 3166-1 alpha-2 market filter for dealers and geocoder country bias (`NO`, `SE`, …). */
84
86
  market?: string;
87
+ scope?: JotulWidgetScope;
85
88
  brands?: string[];
86
89
  /** Optional Sanity campaign slug used to limit dealer results to campaign dealers. */
87
90
  campaignSlug?: string;
package/dist/utils.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare const VALID_WIDGET_TYPES: JotulWidgetType[];
4
4
  export declare function isWidgetType(value: string | undefined): value is JotulWidgetType;
5
5
  export declare function asText(value: unknown): string | null;
6
6
  export declare function formatDistance(dealer: DealerRecord): string | null;
7
+ export declare function isExclusiveDealer(dealer: DealerRecord): boolean;
7
8
  export declare function getDealerKey(dealer: DealerRecord, index: number): string;
8
9
  export declare function getDealerName(dealer: DealerRecord, unknownLabel: string): string;
9
10
  /** True when the tapped map pin matches a dealer already in the current successful search payload. */
package/dist/utils.js CHANGED
@@ -24,6 +24,18 @@ export function formatDistance(dealer) {
24
24
  }
25
25
  return null;
26
26
  }
27
+ export function isExclusiveDealer(dealer) {
28
+ const rawExclusive = dealer.exclusive;
29
+ return (rawExclusive === true ||
30
+ rawExclusive === 1 ||
31
+ rawExclusive === '1' ||
32
+ rawExclusive === 'true' ||
33
+ rawExclusive === 'TRUE' ||
34
+ rawExclusive === 'yes' ||
35
+ rawExclusive === 'YES' ||
36
+ rawExclusive === 'y' ||
37
+ rawExclusive === 'Y');
38
+ }
27
39
  export function getDealerKey(dealer, index) {
28
40
  return String(dealer.dealerId ?? dealer.name ?? index);
29
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jotul/jotul-widgets",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "sideEffects": [