@jotul/jotul-widgets 1.2.0 → 1.2.2

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.
@@ -1 +1 @@
1
- .jwi-pointer-events-none{pointer-events:none}.jwi-fixed{position:fixed}.jwi-absolute{position:absolute}.jwi-relative{position:relative}.jwi-inset-0{inset:0}.jwi-inset-x-0{left:0;right:0}.jwi-bottom-0{bottom:0}.jwi-left-0{left:0}.jwi-right-0{right:0}.jwi-right-3{right:.75rem}.jwi-top-0{top:0}.jwi-top-3{top:.75rem}.jwi-z-20{z-index:20}.jwi-z-30{z-index:30}.jwi-z-\[1200\]{z-index:1200}.jwi-z-\[9998\]{z-index:9998}.jwi-z-\[9999\]{z-index:9999}.jwi-m-0{margin:0}.jwi--mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.-jwi-mt-px{margin-top:-1px}.jwi-mb-3{margin-bottom:.75rem}.jwi-mr-\[-12px\]{margin-right:-12px}.jwi-mt-1{margin-top:.25rem}.jwi-mt-2{margin-top:.5rem}.jwi-mt-3{margin-top:.75rem}.jwi-mt-4{margin-top:1rem}.jwi-box-border{box-sizing:border-box}.jwi-flex{display:flex}.jwi-inline-flex{display:inline-flex}.jwi-h-10{height:2.5rem}.jwi-h-12{height:3rem}.jwi-h-14{height:3.5rem}.jwi-h-3\.5{height:.875rem}.jwi-h-4{height:1rem}.jwi-h-5{height:1.25rem}.jwi-h-6{height:1.5rem}.jwi-h-9{height:2.25rem}.jwi-h-\[14px\]{height:14px}.jwi-h-\[18px\]{height:18px}.jwi-h-\[22px\]{height:22px}.jwi-h-\[45\%\]{height:45%}.jwi-h-\[60px\]{height:60px}.jwi-h-\[78vh\]{height:78vh}.jwi-h-\[calc\(78vh-48px\)\]{height:calc(78vh - 48px)}.jwi-h-\[min\(85vh\,860px\)\]{height:min(85vh,860px)}.jwi-h-auto{height:auto}.jwi-h-full{height:100%}.jwi-max-h-\[min\(60vh\,480px\)\]{max-height:min(60vh,480px)}.jwi-max-h-none{max-height:none}.jwi-min-h-0{min-height:0}.jwi-min-h-\[48px\]{min-height:48px}.jwi-min-h-\[56px\]{min-height:56px}.jwi-w-1\/2{width:50%}.jwi-w-14{width:3.5rem}.jwi-w-2\/3{width:66.666667%}.jwi-w-24{width:6rem}.jwi-w-28{width:7rem}.jwi-w-3\.5{width:.875rem}.jwi-w-4{width:1rem}.jwi-w-48{width:12rem}.jwi-w-5{width:1.25rem}.jwi-w-9{width:2.25rem}.jwi-w-\[14px\]{width:14px}.jwi-w-\[18px\]{width:18px}.jwi-w-\[22px\]{width:22px}.jwi-w-\[40px\]{width:40px}.jwi-w-\[540px\]{width:540px}.jwi-w-\[min\(100vw\,1200px\)\]{width:min(100vw,1200px)}.jwi-w-\[min\(92vw\,620px\)\]{width:min(92vw,620px)}.jwi-w-\[min\(96vw\,1200px\)\]{width:min(96vw,1200px)}.jwi-w-auto{width:auto}.jwi-w-fit{width:-moz-fit-content;width:fit-content}.jwi-w-full{width:100%}.jwi-min-w-0{min-width:0}.jwi-max-w-\[220px\]{max-width:220px}.jwi-max-w-\[520px\]{max-width:520px}.jwi-max-w-\[70\%\]{max-width:70%}.jwi-max-w-\[calc\(100\%-5rem\)\]{max-width:calc(100% - 5rem)}.jwi-max-w-full{max-width:100%}.jwi-flex-1{flex:1 1 0%}.jwi-flex-shrink-0,.jwi-shrink-0{flex-shrink:0}.jwi-scale-100{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes jwi-pulse{50%{opacity:.5}}.jwi-animate-pulse{animation:jwi-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes jwi-spin{to{transform:rotate(1turn)}}.jwi-animate-spin{animation:jwi-spin 1s linear infinite}.jwi-cursor-pointer{cursor:pointer}.jwi-resize-y{resize:vertical}.jwi-flex-row{flex-direction:row}.jwi-flex-col{flex-direction:column}.jwi-items-start{align-items:flex-start}.jwi-items-center{align-items:center}.jwi-items-stretch{align-items:stretch}.jwi-justify-end{justify-content:flex-end}.jwi-justify-center{justify-content:center}.jwi-justify-between{justify-content:space-between}.jwi-gap-0\.5{gap:.125rem}.jwi-gap-1\.5{gap:.375rem}.jwi-gap-2{gap:.5rem}.jwi-gap-3{gap:.75rem}.jwi-gap-4{gap:1rem}.jwi-space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.jwi-self-stretch{align-self:stretch}.jwi-overflow-hidden{overflow:hidden}.jwi-overflow-y-auto{overflow-y:auto}.jwi-overscroll-y-contain{overscroll-behavior-y:contain}.jwi-whitespace-nowrap{white-space:nowrap}.jwi-break-all{word-break:break-all}.jwi-rounded-\[10px\]{border-radius:10px}.jwi-rounded-\[12px\]{border-radius:12px}.jwi-rounded-full{border-radius:9999px}.jwi-rounded-md{border-radius:.375rem}.jwi-rounded-b-\[10px\]{border-bottom-right-radius:10px;border-bottom-left-radius:10px}.jwi-rounded-t-\[10px\]{border-top-left-radius:10px;border-top-right-radius:10px}.jwi-rounded-t-\[16px\]{border-top-left-radius:16px;border-top-right-radius:16px}.jwi-border{border-width:1px}.jwi-border-0{border-width:0}.jwi-border-b{border-bottom-width:1px}.jwi-border-t{border-top-width:1px}.jwi-border-t-0{border-top-width:0}.jwi-border-\[\#b7e5c2\]{--tw-border-opacity:1;border-color:rgb(183 229 194/var(--tw-border-opacity,1))}.jwi-border-\[\#b8d8aa\]{--tw-border-opacity:1;border-color:rgb(184 216 170/var(--tw-border-opacity,1))}.jwi-border-\[\#d8d2c7\]{--tw-border-opacity:1;border-color:rgb(216 210 199/var(--tw-border-opacity,1))}.jwi-border-\[\#e6e1d7\]{--tw-border-opacity:1;border-color:rgb(230 225 215/var(--tw-border-opacity,1))}.jwi-border-\[\#ef2b18\]{--tw-border-opacity:1;border-color:rgb(239 43 24/var(--tw-border-opacity,1))}.jwi-border-\[\#f0c7c2\]{--tw-border-opacity:1;border-color:rgb(240 199 194/var(--tw-border-opacity,1))}.jwi-bg-\[\#FCFCFC\]{--tw-bg-opacity:1;background-color:rgb(252 252 252/var(--tw-bg-opacity,1))}.jwi-bg-\[\#e8eef1\]{--tw-bg-opacity:1;background-color:rgb(232 238 241/var(--tw-bg-opacity,1))}.jwi-bg-\[\#ece8df\]{--tw-bg-opacity:1;background-color:rgb(236 232 223/var(--tw-bg-opacity,1))}.jwi-bg-\[\#eefbf2\]{--tw-bg-opacity:1;background-color:rgb(238 251 242/var(--tw-bg-opacity,1))}.jwi-bg-\[\#ef2b18\]{--tw-bg-opacity:1;background-color:rgb(239 43 24/var(--tw-bg-opacity,1))}.jwi-bg-\[\#eff9e9\]{--tw-bg-opacity:1;background-color:rgb(239 249 233/var(--tw-bg-opacity,1))}.jwi-bg-\[\#f7f5ef\]{--tw-bg-opacity:1;background-color:rgb(247 245 239/var(--tw-bg-opacity,1))}.jwi-bg-\[\#fbf3db\]{--tw-bg-opacity:1;background-color:rgb(251 243 219/var(--tw-bg-opacity,1))}.jwi-bg-\[\#fff3f1\]{--tw-bg-opacity:1;background-color:rgb(255 243 241/var(--tw-bg-opacity,1))}.jwi-bg-black\/35{background-color:rgba(0,0,0,.35)}.jwi-bg-black\/45{background-color:rgba(0,0,0,.45)}.jwi-bg-transparent{background-color:transparent}.jwi-bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.jwi-bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.jwi-from-white{--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.jwi-to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.jwi-p-0{padding:0}.jwi-p-2{padding:.5rem}.jwi-p-4{padding:1rem}.jwi-p-6{padding:1.5rem}.jwi-p-8{padding:2rem}.jwi-px-2\.5{padding-left:.625rem;padding-right:.625rem}.jwi-px-3{padding-left:.75rem;padding-right:.75rem}.jwi-px-4{padding-left:1rem;padding-right:1rem}.jwi-px-5{padding-left:1.25rem;padding-right:1.25rem}.jwi-px-6{padding-left:1.5rem;padding-right:1.5rem}.jwi-px-7{padding-left:1.75rem;padding-right:1.75rem}.jwi-py-1{padding-top:.25rem;padding-bottom:.25rem}.jwi-py-2{padding-top:.5rem;padding-bottom:.5rem}.jwi-py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.jwi-py-3{padding-top:.75rem;padding-bottom:.75rem}.jwi-py-4{padding-top:1rem;padding-bottom:1rem}.jwi-py-8{padding-top:2rem;padding-bottom:2rem}.jwi-pb-24{padding-bottom:6rem}.jwi-pb-3{padding-bottom:.75rem}.jwi-pl-5{padding-left:1.25rem}.jwi-pr-1{padding-right:.25rem}.jwi-pr-3{padding-right:.75rem}.jwi-pr-\[12px\]{padding-right:12px}.jwi-pt-3{padding-top:.75rem}.jwi-text-left{text-align:left}.jwi-text-center{text-align:center}.jwi-font-sans{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.jwi-text-2xl{font-size:1.5rem;line-height:2rem}.jwi-text-\[13px\]{font-size:13px}.jwi-text-base{font-size:1rem;line-height:1.5rem}.jwi-text-sm{font-size:.875rem;line-height:1.25rem}.jwi-text-xl{font-size:1.25rem;line-height:1.75rem}.jwi-text-xs{font-size:.75rem;line-height:1rem}.jwi-font-medium{font-weight:500}.jwi-font-normal{font-weight:400}.jwi-font-semibold{font-weight:600}.jwi-uppercase{text-transform:uppercase}.jwi-tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.jwi-leading-6{line-height:1.5rem}.jwi-leading-\[1\.35\]{line-height:1.35}.jwi-leading-\[1\.4\]{line-height:1.4}.jwi-leading-none{line-height:1}.jwi-leading-snug{line-height:1.375}.jwi-leading-tight{line-height:1.25}.jwi-tracking-\[0\.06em\]{letter-spacing:.06em}.jwi-text-\[\#111111\]{--tw-text-opacity:1;color:rgb(17 17 17/var(--tw-text-opacity,1))}.jwi-text-\[\#16330f\]{--tw-text-opacity:1;color:rgb(22 51 15/var(--tw-text-opacity,1))}.jwi-text-\[\#1b5e20\]{--tw-text-opacity:1;color:rgb(27 94 32/var(--tw-text-opacity,1))}.jwi-text-\[\#333333\]{--tw-text-opacity:1;color:rgb(51 51 51/var(--tw-text-opacity,1))}.jwi-text-\[\#767676\]{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.jwi-text-\[\#8f2d21\]{--tw-text-opacity:1;color:rgb(143 45 33/var(--tw-text-opacity,1))}.jwi-text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.jwi-text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.jwi-opacity-25{opacity:.25}.jwi-opacity-75{opacity:.75}.jwi-opacity-95{opacity:.95}.jwi-shadow-\[-8px_0_32px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow:-8px 0 32px rgba(0,0,0,.2);--tw-shadow-colored:-8px 0 32px var(--tw-shadow-color)}.jwi-shadow-\[-8px_0_32px_rgba\(0\,0\,0\,0\.2\)\],.jwi-shadow-\[0_-12px_36px_rgba\(0\,0\,0\,0\.22\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_-12px_36px_rgba\(0\,0\,0\,0\.22\)\]{--tw-shadow:0 -12px 36px rgba(0,0,0,.22);--tw-shadow-colored:0 -12px 36px var(--tw-shadow-color)}.jwi-shadow-\[0_-6px_20px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 -6px 20px rgba(0,0,0,.12);--tw-shadow-colored:0 -6px 20px var(--tw-shadow-color)}.jwi-shadow-\[0_-6px_20px_rgba\(0\,0\,0\,0\.12\)\],.jwi-shadow-\[0_1px_2px_rgba\(17\,17\,17\,0\.03\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_1px_2px_rgba\(17\,17\,17\,0\.03\)\]{--tw-shadow:0 1px 2px hsla(0,0%,7%,.03);--tw-shadow-colored:0 1px 2px var(--tw-shadow-color)}.jwi-shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.25\)\]{--tw-shadow:0 20px 60px rgba(0,0,0,.25);--tw-shadow-colored:0 20px 60px var(--tw-shadow-color)}.jwi-shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.25\)\],.jwi-shadow-\[0_2px_8px_rgba\(0\,0\,0\,0\.12\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_2px_8px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 2px 8px rgba(0,0,0,.12);--tw-shadow-colored:0 2px 8px var(--tw-shadow-color)}.jwi-shadow-\[0_6px_16px_rgba\(22\,51\,15\,0\.08\)\]{--tw-shadow:0 6px 16px rgba(22,51,15,.08);--tw-shadow-colored:0 6px 16px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_8px_24px_rgba\(17\,17\,17\,0\.08\)\]{--tw-shadow:0 8px 24px hsla(0,0%,7%,.08);--tw-shadow-colored:0 8px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-outline-none{outline:2px solid transparent;outline-offset:2px}.jwi-transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.placeholder\:jwi-text-\[13px\]::-moz-placeholder{font-size:13px}.placeholder\:jwi-text-\[13px\]::placeholder{font-size:13px}.placeholder\:jwi-text-\[\#767676\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.placeholder\:jwi-text-\[\#767676\]::placeholder{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.hover\:jwi-bg-\[\#d92817\]:hover{--tw-bg-opacity:1;background-color:rgb(217 40 23/var(--tw-bg-opacity,1))}.hover\:jwi-bg-\[\#f7f5f0\]:hover{--tw-bg-opacity:1;background-color:rgb(247 245 240/var(--tw-bg-opacity,1))}.hover\:jwi-text-\[\#444444\]:hover{--tw-text-opacity:1;color:rgb(68 68 68/var(--tw-text-opacity,1))}.hover\:jwi-underline:hover{text-decoration-line:underline}.focus\:jwi-border-\[\#111111\]:focus{--tw-border-opacity:1;border-color:rgb(17 17 17/var(--tw-border-opacity,1))}.disabled\:jwi-cursor-wait:disabled{cursor:wait}.disabled\:hover\:jwi-bg-\[\#ef2b18\]:hover:disabled{--tw-bg-opacity:1;background-color:rgb(239 43 24/var(--tw-bg-opacity,1))}@media (min-width:768px){.md\:jwi-h-full{height:100%}.md\:jwi-w-\[48\%\]{width:48%}.md\:jwi-w-\[52\%\]{width:52%}.md\:jwi-max-w-\[220px\]{max-width:220px}.md\:jwi-flex-row{flex-direction:row}.md\:jwi-items-center{align-items:center}.md\:jwi-justify-between{justify-content:space-between}.md\:jwi-border-r{border-right-width:1px}.md\:jwi-border-\[\#ece8df\]{--tw-border-opacity:1;border-color:rgb(236 232 223/var(--tw-border-opacity,1))}.md\:jwi-text-\[14px\]{font-size:14px}.md\:jwi-text-base{font-size:1rem;line-height:1.5rem}.md\:jwi-text-sm{font-size:.875rem;line-height:1.25rem}.md\:placeholder\:jwi-text-\[14px\]::-moz-placeholder{font-size:14px}.md\:placeholder\:jwi-text-\[14px\]::placeholder{font-size:14px}}
1
+ .jwi-pointer-events-none{pointer-events:none}.jwi-fixed{position:fixed}.jwi-absolute{position:absolute}.jwi-relative{position:relative}.jwi-inset-0{inset:0}.jwi-inset-x-0{left:0;right:0}.jwi-bottom-0{bottom:0}.jwi-left-0{left:0}.jwi-right-0{right:0}.jwi-right-3{right:.75rem}.jwi-top-0{top:0}.jwi-top-3{top:.75rem}.jwi-z-20{z-index:20}.jwi-z-30{z-index:30}.jwi-z-\[1200\]{z-index:1200}.jwi-z-\[2147483647\]{z-index:2147483647}.jwi-m-0{margin:0}.jwi--mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.-jwi-mt-px{margin-top:-1px}.jwi-mb-3{margin-bottom:.75rem}.jwi-mr-\[-12px\]{margin-right:-12px}.jwi-mt-1{margin-top:.25rem}.jwi-mt-2{margin-top:.5rem}.jwi-mt-3{margin-top:.75rem}.jwi-mt-4{margin-top:1rem}.jwi-box-border{box-sizing:border-box}.jwi-flex{display:flex}.jwi-inline-flex{display:inline-flex}.jwi-h-10{height:2.5rem}.jwi-h-12{height:3rem}.jwi-h-14{height:3.5rem}.jwi-h-3\.5{height:.875rem}.jwi-h-4{height:1rem}.jwi-h-5{height:1.25rem}.jwi-h-6{height:1.5rem}.jwi-h-9{height:2.25rem}.jwi-h-\[14px\]{height:14px}.jwi-h-\[18px\]{height:18px}.jwi-h-\[22px\]{height:22px}.jwi-h-\[45\%\]{height:45%}.jwi-h-\[60px\]{height:60px}.jwi-h-\[78vh\]{height:78vh}.jwi-h-\[calc\(78vh-48px\)\]{height:calc(78vh - 48px)}.jwi-h-\[min\(85vh\,860px\)\]{height:min(85vh,860px)}.jwi-h-auto{height:auto}.jwi-h-full{height:100%}.jwi-max-h-\[min\(60vh\,480px\)\]{max-height:min(60vh,480px)}.jwi-max-h-none{max-height:none}.jwi-min-h-0{min-height:0}.jwi-min-h-\[48px\]{min-height:48px}.jwi-min-h-\[56px\]{min-height:56px}.jwi-w-1\/2{width:50%}.jwi-w-14{width:3.5rem}.jwi-w-2\/3{width:66.666667%}.jwi-w-24{width:6rem}.jwi-w-28{width:7rem}.jwi-w-3\.5{width:.875rem}.jwi-w-4{width:1rem}.jwi-w-48{width:12rem}.jwi-w-5{width:1.25rem}.jwi-w-9{width:2.25rem}.jwi-w-\[14px\]{width:14px}.jwi-w-\[18px\]{width:18px}.jwi-w-\[22px\]{width:22px}.jwi-w-\[40px\]{width:40px}.jwi-w-\[540px\]{width:540px}.jwi-w-\[min\(100vw\,1200px\)\]{width:min(100vw,1200px)}.jwi-w-\[min\(92vw\,620px\)\]{width:min(92vw,620px)}.jwi-w-\[min\(96vw\,1200px\)\]{width:min(96vw,1200px)}.jwi-w-auto{width:auto}.jwi-w-fit{width:-moz-fit-content;width:fit-content}.jwi-w-full{width:100%}.jwi-min-w-0{min-width:0}.jwi-max-w-\[220px\]{max-width:220px}.jwi-max-w-\[520px\]{max-width:520px}.jwi-max-w-\[70\%\]{max-width:70%}.jwi-max-w-\[calc\(100\%-5rem\)\]{max-width:calc(100% - 5rem)}.jwi-max-w-full{max-width:100%}.jwi-flex-1{flex:1 1 0%}.jwi-flex-shrink-0,.jwi-shrink-0{flex-shrink:0}.jwi-scale-100{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes jwi-pulse{50%{opacity:.5}}.jwi-animate-\[pulse_2s_ease-in-out_infinite\]{animation:jwi-pulse 2s ease-in-out infinite}@keyframes jwi-spin{to{transform:rotate(1turn)}}.jwi-animate-spin{animation:jwi-spin 1s linear infinite}.jwi-cursor-pointer{cursor:pointer}.jwi-resize-y{resize:vertical}.jwi-flex-row{flex-direction:row}.jwi-flex-col{flex-direction:column}.jwi-items-start{align-items:flex-start}.jwi-items-center{align-items:center}.jwi-items-stretch{align-items:stretch}.jwi-justify-end{justify-content:flex-end}.jwi-justify-center{justify-content:center}.jwi-justify-between{justify-content:space-between}.jwi-gap-0\.5{gap:.125rem}.jwi-gap-1\.5{gap:.375rem}.jwi-gap-2{gap:.5rem}.jwi-gap-3{gap:.75rem}.jwi-gap-4{gap:1rem}.jwi-space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.jwi-self-stretch{align-self:stretch}.jwi-overflow-hidden{overflow:hidden}.jwi-overflow-y-auto{overflow-y:auto}.jwi-overscroll-y-contain{overscroll-behavior-y:contain}.jwi-whitespace-nowrap{white-space:nowrap}.jwi-break-all{word-break:break-all}.jwi-rounded-\[10px\]{border-radius:10px}.jwi-rounded-\[12px\]{border-radius:12px}.jwi-rounded-full{border-radius:9999px}.jwi-rounded-md{border-radius:.375rem}.jwi-rounded-b-\[10px\]{border-bottom-right-radius:10px;border-bottom-left-radius:10px}.jwi-rounded-t-\[10px\]{border-top-left-radius:10px;border-top-right-radius:10px}.jwi-rounded-t-\[16px\]{border-top-left-radius:16px;border-top-right-radius:16px}.jwi-border{border-width:1px}.jwi-border-0{border-width:0}.jwi-border-b{border-bottom-width:1px}.jwi-border-t{border-top-width:1px}.jwi-border-t-0{border-top-width:0}.jwi-border-\[\#b7e5c2\]{--tw-border-opacity:1;border-color:rgb(183 229 194/var(--tw-border-opacity,1))}.jwi-border-\[\#b8d8aa\]{--tw-border-opacity:1;border-color:rgb(184 216 170/var(--tw-border-opacity,1))}.jwi-border-\[\#d8d2c7\]{--tw-border-opacity:1;border-color:rgb(216 210 199/var(--tw-border-opacity,1))}.jwi-border-\[\#e6e1d7\]{--tw-border-opacity:1;border-color:rgb(230 225 215/var(--tw-border-opacity,1))}.jwi-border-\[\#ef2b18\]{--tw-border-opacity:1;border-color:rgb(239 43 24/var(--tw-border-opacity,1))}.jwi-border-\[\#f0c7c2\]{--tw-border-opacity:1;border-color:rgb(240 199 194/var(--tw-border-opacity,1))}.jwi-bg-\[\#FCFCFC\]{--tw-bg-opacity:1;background-color:rgb(252 252 252/var(--tw-bg-opacity,1))}.jwi-bg-\[\#e8eef1\]{--tw-bg-opacity:1;background-color:rgb(232 238 241/var(--tw-bg-opacity,1))}.jwi-bg-\[\#ece8df\]{--tw-bg-opacity:1;background-color:rgb(236 232 223/var(--tw-bg-opacity,1))}.jwi-bg-\[\#eefbf2\]{--tw-bg-opacity:1;background-color:rgb(238 251 242/var(--tw-bg-opacity,1))}.jwi-bg-\[\#ef2b18\]{--tw-bg-opacity:1;background-color:rgb(239 43 24/var(--tw-bg-opacity,1))}.jwi-bg-\[\#eff9e9\]{--tw-bg-opacity:1;background-color:rgb(239 249 233/var(--tw-bg-opacity,1))}.jwi-bg-\[\#f7f5ef\]{--tw-bg-opacity:1;background-color:rgb(247 245 239/var(--tw-bg-opacity,1))}.jwi-bg-\[\#fbf3db\]{--tw-bg-opacity:1;background-color:rgb(251 243 219/var(--tw-bg-opacity,1))}.jwi-bg-\[\#fff3f1\]{--tw-bg-opacity:1;background-color:rgb(255 243 241/var(--tw-bg-opacity,1))}.jwi-bg-black\/35{background-color:rgba(0,0,0,.35)}.jwi-bg-black\/45{background-color:rgba(0,0,0,.45)}.jwi-bg-transparent{background-color:transparent}.jwi-bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.jwi-bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.jwi-from-white{--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.jwi-to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.jwi-p-0{padding:0}.jwi-p-2{padding:.5rem}.jwi-p-4{padding:1rem}.jwi-p-6{padding:1.5rem}.jwi-p-8{padding:2rem}.jwi-px-2\.5{padding-left:.625rem;padding-right:.625rem}.jwi-px-3{padding-left:.75rem;padding-right:.75rem}.jwi-px-4{padding-left:1rem;padding-right:1rem}.jwi-px-5{padding-left:1.25rem;padding-right:1.25rem}.jwi-px-6{padding-left:1.5rem;padding-right:1.5rem}.jwi-px-7{padding-left:1.75rem;padding-right:1.75rem}.jwi-py-1{padding-top:.25rem;padding-bottom:.25rem}.jwi-py-2{padding-top:.5rem;padding-bottom:.5rem}.jwi-py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.jwi-py-3{padding-top:.75rem;padding-bottom:.75rem}.jwi-py-4{padding-top:1rem;padding-bottom:1rem}.jwi-py-8{padding-top:2rem;padding-bottom:2rem}.jwi-pb-24{padding-bottom:6rem}.jwi-pb-3{padding-bottom:.75rem}.jwi-pl-5{padding-left:1.25rem}.jwi-pr-1{padding-right:.25rem}.jwi-pr-3{padding-right:.75rem}.jwi-pr-\[12px\]{padding-right:12px}.jwi-pt-3{padding-top:.75rem}.jwi-text-left{text-align:left}.jwi-text-center{text-align:center}.jwi-font-sans{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.jwi-text-2xl{font-size:1.5rem;line-height:2rem}.jwi-text-\[13px\]{font-size:13px}.jwi-text-base{font-size:1rem;line-height:1.5rem}.jwi-text-sm{font-size:.875rem;line-height:1.25rem}.jwi-text-xl{font-size:1.25rem;line-height:1.75rem}.jwi-text-xs{font-size:.75rem;line-height:1rem}.jwi-font-medium{font-weight:500}.jwi-font-normal{font-weight:400}.jwi-font-semibold{font-weight:600}.jwi-uppercase{text-transform:uppercase}.jwi-tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.jwi-leading-6{line-height:1.5rem}.jwi-leading-\[1\.35\]{line-height:1.35}.jwi-leading-\[1\.4\]{line-height:1.4}.jwi-leading-none{line-height:1}.jwi-leading-snug{line-height:1.375}.jwi-leading-tight{line-height:1.25}.jwi-tracking-\[0\.06em\]{letter-spacing:.06em}.jwi-text-\[\#111111\]{--tw-text-opacity:1;color:rgb(17 17 17/var(--tw-text-opacity,1))}.jwi-text-\[\#16330f\]{--tw-text-opacity:1;color:rgb(22 51 15/var(--tw-text-opacity,1))}.jwi-text-\[\#1b5e20\]{--tw-text-opacity:1;color:rgb(27 94 32/var(--tw-text-opacity,1))}.jwi-text-\[\#333333\]{--tw-text-opacity:1;color:rgb(51 51 51/var(--tw-text-opacity,1))}.jwi-text-\[\#767676\]{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.jwi-text-\[\#8f2d21\]{--tw-text-opacity:1;color:rgb(143 45 33/var(--tw-text-opacity,1))}.jwi-text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.jwi-text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.jwi-opacity-25{opacity:.25}.jwi-opacity-75{opacity:.75}.jwi-opacity-95{opacity:.95}.jwi-shadow-\[-8px_0_32px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow:-8px 0 32px rgba(0,0,0,.2);--tw-shadow-colored:-8px 0 32px var(--tw-shadow-color)}.jwi-shadow-\[-8px_0_32px_rgba\(0\,0\,0\,0\.2\)\],.jwi-shadow-\[0_-12px_36px_rgba\(0\,0\,0\,0\.22\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_-12px_36px_rgba\(0\,0\,0\,0\.22\)\]{--tw-shadow:0 -12px 36px rgba(0,0,0,.22);--tw-shadow-colored:0 -12px 36px var(--tw-shadow-color)}.jwi-shadow-\[0_-6px_20px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 -6px 20px rgba(0,0,0,.12);--tw-shadow-colored:0 -6px 20px var(--tw-shadow-color)}.jwi-shadow-\[0_-6px_20px_rgba\(0\,0\,0\,0\.12\)\],.jwi-shadow-\[0_1px_2px_rgba\(17\,17\,17\,0\.03\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_1px_2px_rgba\(17\,17\,17\,0\.03\)\]{--tw-shadow:0 1px 2px hsla(0,0%,7%,.03);--tw-shadow-colored:0 1px 2px var(--tw-shadow-color)}.jwi-shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.25\)\]{--tw-shadow:0 20px 60px rgba(0,0,0,.25);--tw-shadow-colored:0 20px 60px var(--tw-shadow-color)}.jwi-shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.25\)\],.jwi-shadow-\[0_2px_8px_rgba\(0\,0\,0\,0\.12\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_2px_8px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 2px 8px rgba(0,0,0,.12);--tw-shadow-colored:0 2px 8px var(--tw-shadow-color)}.jwi-shadow-\[0_6px_16px_rgba\(22\,51\,15\,0\.08\)\]{--tw-shadow:0 6px 16px rgba(22,51,15,.08);--tw-shadow-colored:0 6px 16px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-shadow-\[0_8px_24px_rgba\(17\,17\,17\,0\.08\)\]{--tw-shadow:0 8px 24px hsla(0,0%,7%,.08);--tw-shadow-colored:0 8px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.jwi-outline-none{outline:2px solid transparent;outline-offset:2px}.jwi-transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.jwi-transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.jwi-duration-300{transition-duration:.3s}.jwi-ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.placeholder\:jwi-text-\[13px\]::-moz-placeholder{font-size:13px}.placeholder\:jwi-text-\[13px\]::placeholder{font-size:13px}.placeholder\:jwi-text-\[\#767676\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.placeholder\:jwi-text-\[\#767676\]::placeholder{--tw-text-opacity:1;color:rgb(118 118 118/var(--tw-text-opacity,1))}.hover\:jwi-bg-\[\#d92817\]:hover{--tw-bg-opacity:1;background-color:rgb(217 40 23/var(--tw-bg-opacity,1))}.hover\:jwi-bg-\[\#f7f5f0\]:hover{--tw-bg-opacity:1;background-color:rgb(247 245 240/var(--tw-bg-opacity,1))}.hover\:jwi-text-\[\#444444\]:hover{--tw-text-opacity:1;color:rgb(68 68 68/var(--tw-text-opacity,1))}.hover\:jwi-underline:hover{text-decoration-line:underline}.focus\:jwi-border-\[\#111111\]:focus{--tw-border-opacity:1;border-color:rgb(17 17 17/var(--tw-border-opacity,1))}.disabled\:jwi-cursor-wait:disabled{cursor:wait}.disabled\:hover\:jwi-bg-\[\#ef2b18\]:hover:disabled{--tw-bg-opacity:1;background-color:rgb(239 43 24/var(--tw-bg-opacity,1))}@media (min-width:768px){.md\:jwi-h-full{height:100%}.md\:jwi-w-\[48\%\]{width:48%}.md\:jwi-w-\[52\%\]{width:52%}.md\:jwi-max-w-\[220px\]{max-width:220px}.md\:jwi-flex-row{flex-direction:row}.md\:jwi-items-center{align-items:center}.md\:jwi-justify-between{justify-content:space-between}.md\:jwi-border-r{border-right-width:1px}.md\:jwi-border-\[\#ece8df\]{--tw-border-opacity:1;border-color:rgb(236 232 223/var(--tw-border-opacity,1))}.md\:jwi-text-\[14px\]{font-size:14px}.md\:jwi-text-base{font-size:1rem;line-height:1.5rem}.md\:jwi-text-sm{font-size:.875rem;line-height:1.25rem}.md\:placeholder\:jwi-text-\[14px\]::-moz-placeholder{font-size:14px}.md\:placeholder\:jwi-text-\[14px\]::placeholder{font-size:14px}}
@@ -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, JotulWidgetHandle, JotulWidgetProps, JotulWidgetScope, WidgetTriggerRenderProps, JotulWidgetStyling, JotulWidgetType, WidgetAuthClientResponse, } from './types';
8
+ export declare function JotulWidget({ type, endpoint, className, productName, locale: localeProp, markets: marketsProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, widgetRef, }: JotulWidgetProps): import("react/jsx-runtime").JSX.Element;
@@ -1,11 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import './JotulWidget.css';
4
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
5
5
  import { FinderSearchRowSkeleton } from './components/FinderSearchRowSkeleton';
6
6
  import { DealerCardSkeleton } from './components/DealerCardSkeleton';
7
- import { ProductPageWidget } from './widgets/ProductPageWidget';
8
- import { FindDealerDrawerWidget } from './components/FindDealerDrawerWidget';
9
7
  import { ButtonSpinner } from './icons/ButtonSpinner';
10
8
  import { DEFAULT_WIDGET_LOCALE_TAG, resolveWidgetUiLocale, WIDGET_STRINGS, } from './i18n/widgetStrings';
11
9
  import { checkWidgetAuthorization, searchLocationSuggestions, searchDealersByCoordinates, searchDealersByPostalCode, } from './api';
@@ -28,17 +26,21 @@ const MARKET_FALLBACK_CENTER = {
28
26
  FI: [60.1699, 24.9384],
29
27
  DE: [52.52, 13.405],
30
28
  };
31
- export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, market: marketProp, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }) {
32
- const resolvedUiLocale = useMemo(() => resolveWidgetUiLocale(localeProp, marketProp), [localeProp, marketProp]);
29
+ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, markets: marketsProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, widgetRef, }) {
30
+ const apiMarkets = useMemo(() => {
31
+ if (marketsProp == null)
32
+ return undefined;
33
+ if (!Array.isArray(marketsProp))
34
+ return undefined;
35
+ const valid = marketsProp
36
+ .map((m) => m?.trim().toUpperCase())
37
+ .filter((m) => m.length === 2 && /^[A-Z]{2}$/.test(m));
38
+ return valid.length > 0 ? valid : undefined;
39
+ }, [marketsProp]);
40
+ const firstMarket = apiMarkets?.[0];
41
+ const resolvedUiLocale = useMemo(() => resolveWidgetUiLocale(localeProp, firstMarket), [localeProp, firstMarket]);
33
42
  const t = WIDGET_STRINGS[resolvedUiLocale];
34
43
  const apiLocaleTag = useMemo(() => (localeProp?.trim() ? localeProp.trim() : DEFAULT_WIDGET_LOCALE_TAG), [localeProp]);
35
- const apiMarket = useMemo(() => {
36
- const m = marketProp?.trim();
37
- if (!m)
38
- return undefined;
39
- const upper = m.toUpperCase();
40
- return /^[A-Z]{2}$/.test(upper) ? upper : undefined;
41
- }, [marketProp]);
42
44
  const heroPrimaryButton = useMemo(() => getWidgetPrimaryButtonPresentation(styling?.button, 'hero', {
43
45
  disabledWait: true,
44
46
  }), [styling?.button]);
@@ -59,15 +61,19 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
59
61
  const [inquiryValues, setInquiryValues] = useState(null);
60
62
  const [inquiryError, setInquiryError] = useState(null);
61
63
  const [isInquirySubmitted, setIsInquirySubmitted] = useState(false);
64
+ const [FindDealerDrawerWidgetComp, setFindDealerDrawerWidgetComp] = useState(null);
65
+ const [ProductPageWidgetComp, setProductPageWidgetComp] = useState(null);
66
+ const [isComponentLoading, setIsComponentLoading] = useState(false);
62
67
  const autocompleteCacheRef = useRef(new Map());
63
68
  const productPageCampaignSlug = type === 'productPage' ? campaignSlug : undefined;
64
69
  const dealerSearchOptions = useMemo(() => ({
65
70
  endpoint,
66
71
  locale: apiLocaleTag,
67
- market: apiMarket,
72
+ markets: apiMarkets,
73
+ scope,
68
74
  brands,
69
75
  campaignSlug: productPageCampaignSlug,
70
- }), [apiLocaleTag, apiMarket, brands, endpoint, productPageCampaignSlug]);
76
+ }), [apiLocaleTag, apiMarkets, brands, endpoint, productPageCampaignSlug, scope]);
71
77
  const runDealerSearchByCoordinates = useCallback(async (latitude, longitude) => {
72
78
  setLocationError(null);
73
79
  setIsSearching(true);
@@ -80,12 +86,12 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
80
86
  finally {
81
87
  setIsSearching(false);
82
88
  }
83
- }, [dealerSearchOptions]);
89
+ }, [dealerSearchOptions, scope]);
84
90
  const runFallbackDealerSearch = useCallback(() => {
85
- const fallbackCenter = (apiMarket != null ? MARKET_FALLBACK_CENTER[apiMarket] : undefined) ??
91
+ const fallbackCenter = (firstMarket != null ? MARKET_FALLBACK_CENTER[firstMarket] : undefined) ??
86
92
  MARKET_FALLBACK_CENTER.NO;
87
93
  return runDealerSearchByCoordinates(fallbackCenter[0], fallbackCenter[1]);
88
- }, [apiMarket, runDealerSearchByCoordinates]);
94
+ }, [firstMarket, runDealerSearchByCoordinates]);
89
95
  const runLocationSearch = useCallback(() => {
90
96
  const messages = WIDGET_STRINGS[resolvedUiLocale];
91
97
  setShouldAutoLocateAfterAuth(false);
@@ -129,7 +135,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
129
135
  setLocationSuggestions([]);
130
136
  return;
131
137
  }
132
- const cacheKey = `${apiLocaleTag}|${apiMarket ?? ''}|${productPageCampaignSlug ?? ''}|${query.toLowerCase()}`;
138
+ const cacheKey = `${apiLocaleTag}|${firstMarket ?? ''}|${productPageCampaignSlug ?? ''}|${query.toLowerCase()}`;
133
139
  const cached = autocompleteCacheRef.current.get(cacheKey);
134
140
  if (cached != null) {
135
141
  setLocationSuggestions(cached);
@@ -150,7 +156,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
150
156
  cancelled = true;
151
157
  clearTimeout(timer);
152
158
  };
153
- }, [apiLocaleTag, apiMarket, productPageCampaignSlug, dealerSearchOptions, locationQuery]);
159
+ }, [apiLocaleTag, firstMarket, productPageCampaignSlug, dealerSearchOptions, locationQuery]);
154
160
  useEffect(() => {
155
161
  if ((type === 'productPage' || type === 'findDealerDrawer') && !isOpen)
156
162
  return;
@@ -192,6 +198,33 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
192
198
  return 'typeReady';
193
199
  }, [type]);
194
200
  const widgetType = isWidgetType(type) ? type : undefined;
201
+ useEffect(() => {
202
+ if (!isOpen)
203
+ return;
204
+ const needsFindDealer = widgetType === 'findDealerDrawer' && FindDealerDrawerWidgetComp == null;
205
+ const needsProductPage = widgetType === 'productPage' && ProductPageWidgetComp == null;
206
+ if (!needsFindDealer && !needsProductPage)
207
+ return;
208
+ setIsComponentLoading(true);
209
+ const tasks = [];
210
+ if (needsFindDealer) {
211
+ tasks.push(import('./components/FindDealerDrawerWidget')
212
+ .then((m) => {
213
+ setFindDealerDrawerWidgetComp(() => m.FindDealerDrawerWidget);
214
+ })
215
+ .catch(() => { }));
216
+ }
217
+ if (needsProductPage) {
218
+ tasks.push(import('./components/ProductPageWidget')
219
+ .then((m) => {
220
+ setProductPageWidgetComp(() => m.ProductPageWidget);
221
+ })
222
+ .catch(() => { }));
223
+ }
224
+ Promise.all(tasks).finally(() => {
225
+ setIsComponentLoading(false);
226
+ });
227
+ }, [isOpen, widgetType, FindDealerDrawerWidgetComp, ProductPageWidgetComp]);
195
228
  const openProductPageWidget = useCallback(() => {
196
229
  setLocationError(null);
197
230
  setSearchResult(null);
@@ -215,6 +248,11 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
215
248
  setIsSearchingSuggestions(false);
216
249
  setMapSearchResult(null);
217
250
  }, []);
251
+ useImperativeHandle(widgetRef, () => ({
252
+ open: openProductPageWidget,
253
+ close: closeDealerWidget,
254
+ isOpen,
255
+ }), [openProductPageWidget, closeDealerWidget, isOpen]);
218
256
  const shellClass = 'jwi-box-border jwi-flex jwi-w-[540px] jwi-max-w-full jwi-flex-col jwi-font-sans jwi-text-[#111111]';
219
257
  const rootClass = className != null && className !== '' ? `${shellClass} ${className}` : shellClass;
220
258
  if (typeState !== 'typeReady') {
@@ -231,6 +269,9 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
231
269
  })
232
270
  : resolvedTrigger;
233
271
  const renderTrigger = (alwaysClickable = false) => {
272
+ if (resolvedTrigger === null) {
273
+ return null;
274
+ }
234
275
  if (resolvedTriggerNode == null) {
235
276
  return (_jsx("button", { type: "button", onClick: openProductPageWidget, className: heroPrimaryButton.className, style: heroPrimaryButton.style, children: t.findDealer }));
236
277
  }
@@ -269,7 +310,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
269
310
  return _jsx("div", { className: rootClass, children: getSafeWidgetErrorMessage(auth?.error, t) });
270
311
  }
271
312
  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
313
+ return (_jsx("div", { className: rootClass, children: ProductPageWidgetComp != null ? (_jsx(ProductPageWidgetComp, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, markets: apiMarkets, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
273
314
  ? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
274
315
  : searchResult, mapSearchResult: mapSearchResult?.ok === false
275
316
  ? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
@@ -338,18 +379,19 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
338
379
  if (isDealerInSearchResult(dealer.dealerName, searchResult, t.unknownDealer))
339
380
  return;
340
381
  void runDealerSearchByCoordinates(dealer.latitude, dealer.longitude);
341
- }, onClosePopup: closeDealerWidget }) }));
382
+ }, onClosePopup: closeDealerWidget })) : null }));
342
383
  }
343
384
  if (widgetType === 'findDealerDrawer') {
344
385
  const drawerLoading = isOpen &&
345
386
  (auth === null ||
346
387
  isLoading ||
388
+ isComponentLoading ||
347
389
  (isSearching && searchResult == null && mapSearchResult == null));
348
- return (_jsxs("div", { className: rootClass, children: [_jsx("div", { className: "jwi-flex jwi-items-center jwi-justify-center jwi-py-8", children: renderTrigger() }), isOpen && (_jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[9998] jwi-bg-black/35", onClick: closeDealerWidget })), _jsx("div", { className: "jwi-fixed jwi-right-0 jwi-top-0 jwi-z-[9999] jwi-h-full jwi-w-[min(100vw,1200px)] jwi-bg-white jwi-shadow-[-8px_0_32px_rgba(0,0,0,0.2)]", style: {
390
+ return (_jsxs("div", { className: rootClass, children: [renderTrigger() && (_jsx("div", { className: "jwi-flex jwi-items-center jwi-justify-center jwi-py-8", children: renderTrigger() })), isOpen && (_jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[2147483647] jwi-bg-black/35", onClick: closeDealerWidget })), _jsx("div", { className: "jwi-fixed jwi-right-0 jwi-top-0 jwi-z-[2147483647] jwi-h-full jwi-w-[min(100vw,1200px)] jwi-bg-white jwi-shadow-[-8px_0_32px_rgba(0,0,0,0.2)]", style: {
349
391
  transform: isOpen ? 'translateX(0)' : 'translateX(100%)',
350
392
  transition: 'transform 300ms ease-out',
351
393
  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
394
+ }, "aria-hidden": !isOpen, children: drawerLoading || FindDealerDrawerWidgetComp == null ? (_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-rounded-[10px] jwi-bg-[#ece8df] jwi-transition-opacity jwi-duration-300 jwi-ease-out" }), _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-rounded-full jwi-bg-[#ece8df] jwi-transition-opacity jwi-duration-300 jwi-ease-out" }), _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(FindDealerDrawerWidgetComp, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, markets: apiMarkets, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
353
395
  ? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
354
396
  : searchResult, mapSearchResult: mapSearchResult?.ok === false
355
397
  ? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
package/dist/api.js CHANGED
@@ -6,13 +6,20 @@ function appendLocaleAndMarket(params, options) {
6
6
  ? options.locale.trim()
7
7
  : DEFAULT_WIDGET_LOCALE_TAG;
8
8
  params.set('locale', locale);
9
- const market = options?.market?.trim();
10
- if (market) {
11
- const upper = market.toUpperCase();
12
- if (/^[A-Z]{2}$/.test(upper)) {
13
- params.set('market', upper);
9
+ if (Array.isArray(options?.markets)) {
10
+ for (const m of options.markets) {
11
+ const trimmed = m?.trim();
12
+ if (!trimmed)
13
+ continue;
14
+ const upper = trimmed.toUpperCase();
15
+ if (/^[A-Z]{2}$/.test(upper)) {
16
+ params.append('market', upper);
17
+ }
14
18
  }
15
19
  }
20
+ if (options?.scope === 'ildstedet') {
21
+ params.set('dealerScope', options.scope);
22
+ }
16
23
  }
17
24
  export async function checkWidgetAuthorization(options) {
18
25
  const endpoint = options?.endpoint ?? '/api/jotul/widget';
@@ -1,2 +1 @@
1
- /** Matches a dealer card: title + badge, two lines, CTA + phone row. */
2
1
  export declare function DealerCardSkeleton(): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { R10 } from '../constants';
3
- /** Matches a dealer card: title + badge, two lines, CTA + phone row. */
4
3
  export function DealerCardSkeleton() {
5
- return (_jsxs("div", { className: `jwi-w-full jwi-animate-pulse ${R10} jwi-border jwi-border-[#e6e1d7] jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)]`, children: [_jsxs("div", { className: "jwi-flex jwi-items-start jwi-justify-between jwi-gap-3", children: [_jsx("div", { className: "jwi-h-5 jwi-max-w-[70%] jwi-flex-1 jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-6 jwi-w-14 jwi-shrink-0 jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsxs("div", { className: "jwi-mt-4 jwi-space-y-1.5", children: [_jsx("div", { className: "jwi-h-4 jwi-w-full jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-4 jwi-w-2/3 jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsxs("div", { className: "jwi-mt-4 jwi-flex jwi-flex-col jwi-gap-3 md:jwi-flex-row md:jwi-items-center md:jwi-justify-between", children: [_jsx("div", { className: `jwi-h-12 jwi-w-full jwi-max-w-[220px] ${R10} jwi-bg-[#ece8df]` }), _jsxs("div", { className: "jwi-flex jwi-min-w-0 jwi-items-center jwi-gap-2", children: [_jsx("div", { className: "jwi-h-3.5 jwi-w-3.5 jwi-shrink-0 jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-4 jwi-w-24 jwi-rounded-full jwi-bg-[#ece8df]" })] })] })] }));
4
+ return (_jsxs("div", { className: `jwi-w-full jwi-animate-[pulse_2s_ease-in-out_infinite] ${R10} jwi-border jwi-border-[#e6e1d7] jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)] jwi-transition-opacity jwi-duration-300 jwi-ease-out`, children: [_jsxs("div", { className: "jwi-flex jwi-items-start jwi-justify-between jwi-gap-3", children: [_jsx("div", { className: "jwi-h-5 jwi-max-w-[70%] jwi-flex-1 jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-6 jwi-w-14 jwi-shrink-0 jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsxs("div", { className: "jwi-mt-4 jwi-space-y-1.5", children: [_jsx("div", { className: "jwi-h-4 jwi-w-full jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-4 jwi-w-2/3 jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsxs("div", { className: "jwi-mt-4 jwi-flex jwi-flex-col jwi-gap-3 md:jwi-flex-row md:jwi-items-center md:jwi-justify-between", children: [_jsx("div", { className: `jwi-h-12 jwi-w-full jwi-max-w-[220px] ${R10} jwi-bg-[#ece8df]` }), _jsxs("div", { className: "jwi-flex jwi-min-w-0 jwi-items-center jwi-gap-2", children: [_jsx("div", { className: "jwi-h-3.5 jwi-w-3.5 jwi-shrink-0 jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-4 jwi-w-24 jwi-rounded-full jwi-bg-[#ece8df]" })] })] })] }));
6
5
  }
@@ -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';
5
- type FindDealerDrawerWidgetProps = {
4
+ import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
5
+ export type FindDealerDrawerWidgetProps = {
6
6
  t: WidgetStrings;
7
7
  buttonStyling?: JotulWidgetButtonStyling;
8
8
  borderStyling?: JotulWidgetBorderStyling;
9
- market?: string;
9
+ markets?: string[];
10
+ scope?: JotulWidgetScope;
10
11
  isSearching: boolean;
11
12
  locationError: string | null;
12
13
  searchResult: DealerSearchResponse | null;
@@ -35,5 +36,4 @@ 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 {};
39
+ export declare function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, markets, 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;
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
3
  import 'leaflet/dist/leaflet.css';
3
4
  import 'leaflet.markercluster/dist/MarkerCluster.css';
@@ -17,7 +18,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
17
18
  import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
18
19
  import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
19
20
  import { JOTUL_BRAND_PRIMARY_HEX } from '../constants';
21
+ import { isExclusiveDealer } from '../utils';
20
22
  const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
23
+ const EMPTY_DEALERS = [];
21
24
  function mapPointsBoundsKey(points, defaultCenter) {
22
25
  const body = points.length === 0
23
26
  ? ''
@@ -49,25 +52,17 @@ function getDealerMapPoint(dealer) {
49
52
  const longitude = readNumber(dealer.longitude);
50
53
  if (latitude == null || longitude == null)
51
54
  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';
55
+ const isExclusive = isExclusiveDealer(dealer);
62
56
  return { dealerName: getDealerName(dealer), latitude, longitude, isExclusive };
63
57
  }
64
58
  function toAssetSrc(value) {
65
59
  return typeof value === 'string' ? value : value.src;
66
60
  }
67
- function createDealerPinIcon(isExclusive, active, market) {
61
+ function createDealerPinIcon(isExclusive, active, markets) {
68
62
  const size = active ? 48 : 42;
69
63
  const width = Math.round((16 / 20) * size);
70
- const exclusivePin = market === 'NO' ? dealerPinIldstedet : dealerPinExclusive;
64
+ const isNorway = markets?.includes('NO') ?? false;
65
+ const exclusivePin = isNorway ? dealerPinIldstedet : dealerPinExclusive;
71
66
  const pinUrl = isExclusive ? toAssetSrc(exclusivePin) : toAssetSrc(dealerPin);
72
67
  return icon({
73
68
  iconUrl: pinUrl,
@@ -108,7 +103,7 @@ function FocusActiveDealer({ point }) {
108
103
  }, [map, point]);
109
104
  return null;
110
105
  }
111
- function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, clusterBrandFill, clusterBrandLabel, market, activeDealerName, onSelectDealer, onUnavailable, }) {
106
+ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, clusterBrandFill, clusterBrandLabel, markets, activeDealerName, onSelectDealer, onUnavailable, }) {
112
107
  const map = useMap();
113
108
  const markersByDealerRef = useRef(new Map());
114
109
  const pointsRef = useRef(points);
@@ -124,7 +119,7 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
124
119
  for (const p of pointsRef.current) {
125
120
  const marker = markersByDealerRef.current.get(p.dealerName);
126
121
  if (marker != null) {
127
- marker.setIcon(createDealerPinIcon(p.isExclusive, active === p.dealerName, market));
122
+ marker.setIcon(createDealerPinIcon(p.isExclusive, active === p.dealerName, markets));
128
123
  }
129
124
  }
130
125
  }
@@ -154,7 +149,7 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
154
149
  }
155
150
  function makeMarker(point) {
156
151
  const marker = leaf.marker([point.latitude, point.longitude], {
157
- icon: createDealerPinIcon(point.isExclusive, activeNameRef.current === point.dealerName, market),
152
+ icon: createDealerPinIcon(point.isExclusive, activeNameRef.current === point.dealerName, markets),
158
153
  });
159
154
  marker.on('click', () => {
160
155
  onSelectRef.current?.({
@@ -229,9 +224,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
229
224
  }, [map, pointsBoundsKey, clusterThemeKey]);
230
225
  return null;
231
226
  }
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);
227
+ export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, markets, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }) {
228
+ const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
229
+ const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
230
+ const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
231
+ const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
235
232
  const total = dealers.length;
236
233
  const inquiryFormOpen = inquiryValues != null;
237
234
  const [activeDealerName, setActiveDealerName] = useState(null);
@@ -293,13 +290,13 @@ export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market
293
290
  const successPanel = (_jsx("div", { className: "jwi-flex jwi-w-full jwi-items-center jwi-justify-center jwi-bg-white jwi-p-2", children: _jsxs("div", { className: "jwi-flex jwi-w-full jwi-max-w-[520px] jwi-flex-col jwi-items-center jwi-gap-4 jwi-rounded-[10px] jwi-bg-white jwi-p-8 jwi-text-center", children: [_jsx("div", { className: "jwi-text-2xl jwi-font-semibold jwi-text-[#111111]", children: t.inquiryThankYouTitle }), _jsx("div", { className: "jwi-text-sm jwi-leading-6 jwi-text-[#333333]", children: t.inquirySentSuccess }), _jsx("button", { type: "button", onClick: onClose, className: "jwi-mt-2 jwi-inline-flex jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-md jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-px-5 jwi-py-2.5 jwi-text-sm jwi-font-medium jwi-text-[#111111]", children: t.goBack })] }) }));
294
291
  const canShowMore = visibleDealerCount < dealers.length;
295
292
  const showMoreButton = canShowMore ? (_jsx("button", { type: "button", onClick: () => setVisibleDealerCount((count) => Math.min(count + 10, dealers.length)), className: "jwi-mt-3 jwi-inline-flex jwi-w-full jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-md jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-px-3 jwi-py-2 jwi-text-sm jwi-font-medium jwi-text-[#111111]", children: "Show more" })) : null;
296
- const mapCanvas = (_jsxs(MapContainer, { center: defaultCenter ?? [59.9139, 10.7522], zoom: 6, className: "jwi-h-full jwi-w-full", zoomControl: true, children: [_jsx(TileLayer, { attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noreferrer">OpenStreetMap</a> contributors \u00A9 <a href="https://carto.com/attributions" target="_blank" rel="noreferrer">CARTO</a>', url: OSM_MINIMAL_TILE_URL, maxZoom: 19 }), _jsx(FitMapBounds, { boundsKey: mapBoundsKey, points: mapPoints, defaultCenter: defaultCenter }), _jsx(FocusActiveDealer, { point: activeMapPoint }), _jsx(ClusteredMapMarkers, { points: mapPoints, pointsBoundsKey: mapBoundsKey, clusterThemeKey: mapClusterTheme.key, clusterBrandFill: mapClusterTheme.fill, clusterBrandLabel: mapClusterTheme.label, market: market, activeDealerName: activeDealerName, onUnavailable: () => setClusterUnavailable(true), onSelectDealer: (dealer) => {
293
+ const mapCanvas = (_jsxs(MapContainer, { center: defaultCenter ?? [59.9139, 10.7522], zoom: 6, className: "jwi-h-full jwi-w-full", zoomControl: true, children: [_jsx(TileLayer, { attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noreferrer">OpenStreetMap</a> contributors \u00A9 <a href="https://carto.com/attributions" target="_blank" rel="noreferrer">CARTO</a>', url: OSM_MINIMAL_TILE_URL, maxZoom: 19 }), _jsx(FitMapBounds, { boundsKey: mapBoundsKey, points: mapPoints, defaultCenter: defaultCenter }), _jsx(FocusActiveDealer, { point: activeMapPoint }), _jsx(ClusteredMapMarkers, { points: mapPoints, pointsBoundsKey: mapBoundsKey, clusterThemeKey: mapClusterTheme.key, clusterBrandFill: mapClusterTheme.fill, clusterBrandLabel: mapClusterTheme.label, markets: markets, activeDealerName: activeDealerName, onUnavailable: () => setClusterUnavailable(true), onSelectDealer: (dealer) => {
297
294
  setActiveDealerName(dealer.dealerName);
298
295
  onMapDealerSelect?.(dealer);
299
296
  } }), clusterUnavailable &&
300
297
  mapPoints.map((point) => {
301
298
  const isActive = activeDealerName === point.dealerName;
302
- return (_jsx(Marker, { position: [point.latitude, point.longitude], icon: createDealerPinIcon(point.isExclusive, isActive, market), eventHandlers: {
299
+ return (_jsx(Marker, { position: [point.latitude, point.longitude], icon: createDealerPinIcon(point.isExclusive, isActive, markets), eventHandlers: {
303
300
  click: () => {
304
301
  setActiveDealerName(point.dealerName);
305
302
  onMapDealerSelect?.({
@@ -310,7 +307,7 @@ export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market
310
307
  },
311
308
  }, children: _jsx(Tooltip, { children: point.dealerName }) }, `${point.dealerName}-${point.latitude}-${point.longitude}`));
312
309
  })] }));
313
- const leftContent = (_jsx(_Fragment, { children: showInquirySuccessScreen ? (successPanel) : inquiryFormOpen ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching && (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-mr-[-12px] jwi-flex jwi-flex-col jwi-gap-4 jwi-overflow-y-auto jwi-pr-[12px]", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })), searchResult?.ok && !isSearching && (_jsxs(_Fragment, { children: [_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, fitAvailableHeight: !isMobileViewport, autoScrollToActive: true, enableInternalScroll: !isMobileViewport, maxHeightClassName: "jwi-max-h-none", t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, market: market, onStartInquiry: onStartInquiry, onSelectDealer: setActiveDealerName }), showMoreButton] }))] })) }));
310
+ const leftContent = (_jsx(_Fragment, { children: showInquirySuccessScreen ? (successPanel) : inquiryFormOpen ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching && (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-mr-[-12px] jwi-flex jwi-flex-col jwi-gap-4 jwi-overflow-y-auto jwi-pr-[12px]", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })), searchResult?.ok && !isSearching && (_jsxs(_Fragment, { children: [_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, fitAvailableHeight: !isMobileViewport, autoScrollToActive: true, enableInternalScroll: !isMobileViewport, maxHeightClassName: "jwi-max-h-none", t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, markets: markets, onStartInquiry: onStartInquiry, onSelectDealer: setActiveDealerName }), showMoreButton] }))] })) }));
314
311
  if (isMobileViewport) {
315
312
  return (_jsxs("div", { className: "jwi-relative jwi-flex jwi-h-full jwi-flex-col jwi-bg-white", children: [_jsx("div", { className: "jwi-flex jwi-justify-end jwi-bg-white jwi-px-4 jwi-pt-3", children: _jsx("button", { type: "button", onClick: onClose, className: "jwi-inline-flex jwi-h-9 jwi-w-9 jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-full jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-text-xl jwi-leading-none jwi-text-[#111111]", "aria-label": t.closeMap, children: "\u00D7" }) }), _jsx("div", { className: "jwi-min-h-0 jwi-flex-1 jwi-overflow-y-auto jwi-bg-white jwi-p-4 jwi-pb-24", children: leftContent }), !inquiryFormOpen && !showInquirySuccessScreen && !mobileMapExpanded && (_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded(true), className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-20 jwi-flex jwi-h-14 jwi-items-center jwi-justify-center jwi-gap-2 jwi-rounded-t-[16px] jwi-border-t jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111] jwi-shadow-[0_-6px_20px_rgba(0,0,0,0.12)]", children: [t.openMap, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(-90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] })), mobileMapExpanded && !inquiryFormOpen && !showInquirySuccessScreen && (_jsxs("div", { className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-30 jwi-h-[78vh] jwi-overflow-hidden jwi-rounded-t-[16px] jwi-bg-white jwi-shadow-[0_-12px_36px_rgba(0,0,0,0.22)]", children: [_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded(false), className: "jwi-flex jwi-h-12 jwi-w-full jwi-items-center jwi-justify-center jwi-gap-2 jwi-border-b jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111]", children: [t.closeMapMobile, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] }), _jsx("div", { className: "jwi-h-[calc(78vh-48px)] jwi-w-full", children: mapCanvas })] }))] }));
316
313
  }
@@ -1,2 +1 @@
1
- /** Matches the finder chrome: bordered box, pin + hint + Find in one row. */
2
1
  export declare function FinderSearchRowSkeleton(): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { R10 } from '../constants';
3
- /** Matches the finder chrome: bordered box, pin + hint + Find in one row. */
4
3
  export function FinderSearchRowSkeleton() {
5
- return (_jsx("div", { className: `jwi-w-full jwi-overflow-hidden ${R10} jwi-border jwi-border-[#d8d2c7] jwi-bg-white`, children: _jsxs("div", { className: "jwi-flex jwi-w-full jwi-min-w-0 jwi-flex-row jwi-items-stretch", children: [_jsxs("div", { className: "jwi-flex jwi-min-w-0 jwi-flex-1 jwi-items-center jwi-gap-3 jwi-py-4 jwi-pl-5 jwi-pr-3", children: [_jsx("div", { className: "jwi-h-4 jwi-w-4 jwi-shrink-0 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-min-w-0 jwi-flex-1 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsx("div", { className: "jwi-w-28 jwi-shrink-0 jwi-self-stretch jwi-animate-pulse jwi-bg-[#ece8df]" })] }) }));
4
+ return (_jsx("div", { className: `jwi-w-full jwi-overflow-hidden ${R10} jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-transition-opacity jwi-duration-300 jwi-ease-out`, children: _jsxs("div", { className: "jwi-flex jwi-w-full jwi-min-w-0 jwi-flex-row jwi-items-stretch", children: [_jsxs("div", { className: "jwi-flex jwi-min-w-0 jwi-flex-1 jwi-items-center jwi-gap-3 jwi-py-4 jwi-pl-5 jwi-pr-3", children: [_jsx("div", { className: "jwi-h-4 jwi-w-4 jwi-shrink-0 jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-rounded-full jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-min-w-0 jwi-flex-1 jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-rounded-full jwi-bg-[#ece8df]" })] }), _jsx("div", { className: "jwi-w-28 jwi-shrink-0 jwi-self-stretch jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-bg-[#ece8df]" })] }) }));
6
5
  }
@@ -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';
5
- type ProductPageWidgetProps = {
4
+ import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
5
+ export type ProductPageWidgetProps = {
6
6
  t: WidgetStrings;
7
7
  buttonStyling?: JotulWidgetButtonStyling;
8
8
  borderStyling?: JotulWidgetBorderStyling;
9
- market?: string;
9
+ markets?: string[];
10
+ scope?: JotulWidgetScope;
10
11
  isSearching: boolean;
11
12
  locationError: string | null;
12
13
  searchResult: DealerSearchResponse | null;
@@ -35,5 +36,4 @@ 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 {};
39
+ export declare function ProductPageWidget({ t, buttonStyling, borderStyling, markets, 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;
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
3
  import 'leaflet/dist/leaflet.css';
3
4
  import 'leaflet.markercluster/dist/MarkerCluster.css';
@@ -18,7 +19,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
18
19
  import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
19
20
  import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
20
21
  import { JOTUL_BRAND_PRIMARY_HEX, R10 } from '../constants';
22
+ import { isExclusiveDealer } from '../utils';
21
23
  const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
24
+ const EMPTY_DEALERS = [];
22
25
  function mapPointsBoundsKey(points, defaultCenter) {
23
26
  const body = points.length === 0
24
27
  ? ''
@@ -52,16 +55,7 @@ function getDealerMapPoint(dealer) {
52
55
  const longitude = readNumber(dealer.longitude);
53
56
  if (latitude == null || longitude == null)
54
57
  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';
58
+ const isExclusive = isExclusiveDealer(dealer);
65
59
  return {
66
60
  dealer,
67
61
  dealerName: getDealerName(dealer),
@@ -73,10 +67,11 @@ function getDealerMapPoint(dealer) {
73
67
  function toAssetSrc(value) {
74
68
  return typeof value === 'string' ? value : value.src;
75
69
  }
76
- function createDealerPinIcon(isExclusive, active, market) {
70
+ function createDealerPinIcon(isExclusive, active, markets) {
77
71
  const size = active ? 48 : 42;
78
72
  const width = Math.round((16 / 20) * size);
79
- const exclusivePin = market === 'NO' ? dealerPinIldstedet : dealerPinExclusive;
73
+ const isNorway = markets?.includes('NO') ?? false;
74
+ const exclusivePin = isNorway ? dealerPinIldstedet : dealerPinExclusive;
80
75
  const pinUrl = isExclusive ? toAssetSrc(exclusivePin) : toAssetSrc(dealerPin);
81
76
  return icon({
82
77
  iconUrl: pinUrl,
@@ -115,7 +110,7 @@ function FocusActiveDealer({ point }) {
115
110
  }, [map, point]);
116
111
  return null;
117
112
  }
118
- function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, clusterBrandFill, clusterBrandLabel, market, activeDealerName, onSelectDealer, onUnavailable, }) {
113
+ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, clusterBrandFill, clusterBrandLabel, markets, activeDealerName, onSelectDealer, onUnavailable, }) {
119
114
  const map = useMap();
120
115
  const markersByDealerRef = useRef(new Map());
121
116
  const pointsRef = useRef(points);
@@ -131,7 +126,7 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
131
126
  for (const p of pointsRef.current) {
132
127
  const marker = markersByDealerRef.current.get(p.dealerName);
133
128
  if (marker != null) {
134
- marker.setIcon(createDealerPinIcon(p.isExclusive, active === p.dealerName, market));
129
+ marker.setIcon(createDealerPinIcon(p.isExclusive, active === p.dealerName, markets));
135
130
  }
136
131
  }
137
132
  }
@@ -161,7 +156,7 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
161
156
  }
162
157
  function makeMarker(point) {
163
158
  const marker = leaf.marker([point.latitude, point.longitude], {
164
- icon: createDealerPinIcon(point.isExclusive, activeNameRef.current === point.dealerName, market),
159
+ icon: createDealerPinIcon(point.isExclusive, activeNameRef.current === point.dealerName, markets),
165
160
  });
166
161
  marker.on('click', () => {
167
162
  onSelectRef.current?.({
@@ -236,9 +231,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
236
231
  }, [map, pointsBoundsKey, clusterThemeKey]);
237
232
  return null;
238
233
  }
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);
234
+ export function ProductPageWidget({ t, buttonStyling, borderStyling, markets, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }) {
235
+ const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
236
+ const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
237
+ const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
238
+ const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
242
239
  const total = dealers.length;
243
240
  const inquiryFormOpen = inquiryValues != null;
244
241
  const [activeDealerName, setActiveDealerName] = useState(null);
@@ -303,13 +300,13 @@ export function ProductPageWidget({ t, buttonStyling, borderStyling, market, isS
303
300
  key: `${fill}\0${label}`,
304
301
  };
305
302
  }, [buttonStyling?.backgroundColor, buttonStyling?.textColor]);
306
- const mapCanvas = (_jsxs(MapContainer, { center: defaultCenter ?? [59.9139, 10.7522], zoom: 6, className: "jwi-h-full jwi-w-full", zoomControl: true, children: [_jsx(TileLayer, { attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noreferrer">OpenStreetMap</a> contributors \u00A9 <a href="https://carto.com/attributions" target="_blank" rel="noreferrer">CARTO</a>', url: OSM_MINIMAL_TILE_URL, maxZoom: 19 }), _jsx(FitMapBounds, { boundsKey: mapBoundsKey, points: mapPoints, defaultCenter: defaultCenter }), _jsx(FocusActiveDealer, { point: activeMapPoint }), _jsx(ClusteredMapMarkers, { points: mapPoints, pointsBoundsKey: mapBoundsKey, clusterThemeKey: mapClusterTheme.key, clusterBrandFill: mapClusterTheme.fill, clusterBrandLabel: mapClusterTheme.label, market: market, activeDealerName: activeDealerName, onUnavailable: () => setClusterUnavailable(true), onSelectDealer: (dealer) => {
303
+ const mapCanvas = (_jsxs(MapContainer, { center: defaultCenter ?? [59.9139, 10.7522], zoom: 6, className: "jwi-h-full jwi-w-full", zoomControl: true, children: [_jsx(TileLayer, { attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noreferrer">OpenStreetMap</a> contributors \u00A9 <a href="https://carto.com/attributions" target="_blank" rel="noreferrer">CARTO</a>', url: OSM_MINIMAL_TILE_URL, maxZoom: 19 }), _jsx(FitMapBounds, { boundsKey: mapBoundsKey, points: mapPoints, defaultCenter: defaultCenter }), _jsx(FocusActiveDealer, { point: activeMapPoint }), _jsx(ClusteredMapMarkers, { points: mapPoints, pointsBoundsKey: mapBoundsKey, clusterThemeKey: mapClusterTheme.key, clusterBrandFill: mapClusterTheme.fill, clusterBrandLabel: mapClusterTheme.label, markets: markets, activeDealerName: activeDealerName, onUnavailable: () => setClusterUnavailable(true), onSelectDealer: (dealer) => {
307
304
  setActiveDealerName(dealer.dealerName);
308
305
  onMapDealerSelect?.(dealer);
309
306
  } }), clusterUnavailable &&
310
307
  mapPoints.map((point) => {
311
308
  const isActive = activeDealerName === point.dealerName;
312
- return (_jsx(Marker, { position: [point.latitude, point.longitude], icon: createDealerPinIcon(point.isExclusive, isActive, market), eventHandlers: {
309
+ return (_jsx(Marker, { position: [point.latitude, point.longitude], icon: createDealerPinIcon(point.isExclusive, isActive, markets), eventHandlers: {
313
310
  click: () => {
314
311
  setActiveDealerName(point.dealerName);
315
312
  onMapDealerSelect?.({
@@ -336,7 +333,7 @@ export function ProductPageWidget({ t, buttonStyling, borderStyling, market, isS
336
333
  function renderSuccessPanel() {
337
334
  return (_jsx("div", { className: "jwi-flex jwi-w-full jwi-items-center jwi-justify-center jwi-bg-white jwi-p-2", children: _jsxs("div", { className: `jwi-flex jwi-w-full jwi-max-w-[520px] jwi-flex-col jwi-items-center jwi-gap-4 ${R10} jwi-bg-white jwi-p-8 jwi-text-center`, children: [_jsx("div", { className: "jwi-text-2xl jwi-font-semibold jwi-text-[#111111]", children: t.inquiryThankYouTitle }), _jsx("div", { className: "jwi-text-sm jwi-leading-6 jwi-text-[#333333]", children: t.inquirySentSuccess }), _jsx("button", { type: "button", onClick: closeMapPopup, className: "jwi-mt-2 jwi-inline-flex jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-md jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-px-5 jwi-py-2.5 jwi-text-sm jwi-font-medium jwi-text-[#111111]", children: t.goBack })] }) }));
338
335
  }
339
- return (_jsxs(_Fragment, { children: [!isMobileViewport && (_jsx(_Fragment, { children: _jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[9999] jwi-flex jwi-items-center jwi-justify-center jwi-bg-black/45 jwi-p-4", onClick: closeMapPopup, children: _jsxs("div", { className: `jwi-relative jwi-flex jwi-scale-100 jwi-flex-col jwi-overflow-hidden ${R10} jwi-bg-white jwi-shadow-[0_20px_60px_rgba(0,0,0,0.25)] jwi-transition-all ${showInquirySuccessScreen
336
+ return (_jsxs(_Fragment, { children: [!isMobileViewport && (_jsx(_Fragment, { children: _jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[2147483647] jwi-flex jwi-items-center jwi-justify-center jwi-bg-black/45 jwi-p-4", onClick: closeMapPopup, children: _jsxs("div", { className: `jwi-relative jwi-flex jwi-scale-100 jwi-flex-col jwi-overflow-hidden ${R10} jwi-bg-white jwi-shadow-[0_20px_60px_rgba(0,0,0,0.25)] jwi-transition-all ${showInquirySuccessScreen
340
337
  ? 'jwi-h-auto jwi-w-[min(92vw,620px)]'
341
- : 'jwi-h-[min(85vh,860px)] jwi-w-[min(96vw,1200px)] md:jwi-flex-row'}`, onClick: (event) => event.stopPropagation(), children: [_jsx("button", { type: "button", onClick: closeMapPopup, className: "jwi-absolute jwi-right-3 jwi-top-3 jwi-z-[1200] jwi-inline-flex jwi-h-9 jwi-w-9 jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-full jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-text-xl jwi-leading-none jwi-text-[#111111] jwi-shadow-[0_2px_8px_rgba(0,0,0,0.12)]", "aria-label": t.closeMap, children: "\u00D7" }), showInquirySuccessScreen ? (renderSuccessPanel()) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-overflow-hidden md:jwi-w-[48%] md:jwi-border-r md:jwi-border-[#ece8df]", children: _jsx("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: showInquiryInMapPopup ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), _jsx(CampaignStatus, { campaign: searchResult?.campaign, t: t }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching ? (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-mr-[-12px] jwi-flex jwi-h-full jwi-flex-col jwi-gap-4 jwi-overflow-y-auto jwi-pr-[12px]", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })) : (_jsxs(_Fragment, { children: [searchResult?.ok && (_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, fitAvailableHeight: true, autoScrollToActive: true, maxHeightClassName: "jwi-max-h-none", t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, market: market, onStartInquiry: onStartInquiry, onSelectDealer: handleDealerFocus })), showMoreButton] }))] })) }) }), _jsx("div", { className: "jwi-relative jwi-h-[45%] jwi-w-full md:jwi-h-full md:jwi-w-[52%]", children: mapCanvas })] }))] }) }) })), isMobileViewport && (_jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[9999] jwi-bg-white", children: _jsxs("div", { className: "jwi-relative jwi-flex jwi-h-full jwi-flex-col", children: [_jsx("div", { className: "jwi-flex jwi-justify-end jwi-bg-white jwi-px-4 jwi-pt-3", children: _jsx("button", { type: "button", onClick: closeMapPopup, className: "jwi-inline-flex jwi-h-9 jwi-w-9 jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-full jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-text-xl jwi-leading-none jwi-text-[#111111]", "aria-label": t.closeMap, children: "\u00D7" }) }), _jsx("div", { className: "jwi-min-h-0 jwi-flex-1 jwi-overflow-y-auto jwi-bg-white jwi-p-4 jwi-pb-24", children: showInquirySuccessScreen ? (renderSuccessPanel()) : showInquiryInMapPopup ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), _jsx(CampaignStatus, { campaign: searchResult?.campaign, t: t }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching ? (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })) : (_jsxs(_Fragment, { children: [searchResult?.ok && (_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, maxHeightClassName: "jwi-max-h-none", autoScrollToActive: true, enableInternalScroll: false, t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, market: market, onStartInquiry: onStartInquiry, onSelectDealer: handleDealerFocus })), showMoreButton] }))] })) }), !showInquiryInMapPopup && !showInquirySuccessScreen && !mobileMapExpanded && (_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded((open) => !open), className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-20 jwi-flex jwi-h-14 jwi-items-center jwi-justify-center jwi-gap-2 jwi-rounded-t-[16px] jwi-border-t jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111] jwi-shadow-[0_-6px_20px_rgba(0,0,0,0.12)]", children: [t.openMap, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(-90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] })), mobileMapExpanded && !showInquiryInMapPopup && !showInquirySuccessScreen && (_jsxs("div", { className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-30 jwi-h-[78vh] jwi-overflow-hidden jwi-rounded-t-[16px] jwi-bg-white jwi-shadow-[0_-12px_36px_rgba(0,0,0,0.22)]", children: [_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded(false), className: "jwi-flex jwi-h-12 jwi-w-full jwi-items-center jwi-justify-center jwi-gap-2 jwi-border-b jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111]", children: [t.closeMapMobile, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] }), _jsx("div", { className: "jwi-h-[calc(78vh-48px)] jwi-w-full", children: mapCanvas })] }))] }) }))] }));
338
+ : 'jwi-h-[min(85vh,860px)] jwi-w-[min(96vw,1200px)] md:jwi-flex-row'}`, onClick: (event) => event.stopPropagation(), children: [_jsx("button", { type: "button", onClick: closeMapPopup, className: "jwi-absolute jwi-right-3 jwi-top-3 jwi-z-[1200] jwi-inline-flex jwi-h-9 jwi-w-9 jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-full jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-text-xl jwi-leading-none jwi-text-[#111111] jwi-shadow-[0_2px_8px_rgba(0,0,0,0.12)]", "aria-label": t.closeMap, children: "\u00D7" }), showInquirySuccessScreen ? (renderSuccessPanel()) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-overflow-hidden md:jwi-w-[48%] md:jwi-border-r md:jwi-border-[#ece8df]", children: _jsx("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: showInquiryInMapPopup ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), _jsx(CampaignStatus, { campaign: searchResult?.campaign, t: t }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching ? (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-mr-[-12px] jwi-flex jwi-h-full jwi-flex-col jwi-gap-4 jwi-overflow-y-auto jwi-pr-[12px]", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })) : (_jsxs(_Fragment, { children: [searchResult?.ok && (_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, fitAvailableHeight: true, autoScrollToActive: true, maxHeightClassName: "jwi-max-h-none", t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, markets: markets, onStartInquiry: onStartInquiry, onSelectDealer: handleDealerFocus })), showMoreButton] }))] })) }) }), _jsx("div", { className: "jwi-relative jwi-h-[45%] jwi-w-full md:jwi-h-full md:jwi-w-[52%]", children: mapCanvas })] }))] }) }) })), isMobileViewport && (_jsx("div", { className: "jwi-fixed jwi-inset-0 jwi-z-[2147483647] jwi-bg-white", children: _jsxs("div", { className: "jwi-relative jwi-flex jwi-h-full jwi-flex-col", children: [_jsx("div", { className: "jwi-flex jwi-justify-end jwi-bg-white jwi-px-4 jwi-pt-3", children: _jsx("button", { type: "button", onClick: closeMapPopup, className: "jwi-inline-flex jwi-h-9 jwi-w-9 jwi-cursor-pointer jwi-items-center jwi-justify-center jwi-rounded-full jwi-border jwi-border-[#d8d2c7] jwi-bg-white jwi-text-xl jwi-leading-none jwi-text-[#111111]", "aria-label": t.closeMap, children: "\u00D7" }) }), _jsx("div", { className: "jwi-min-h-0 jwi-flex-1 jwi-overflow-y-auto jwi-bg-white jwi-p-4 jwi-pb-24", children: showInquirySuccessScreen ? (renderSuccessPanel()) : showInquiryInMapPopup ? (_jsx(InquiryForm, { t: t, buttonStyling: buttonStyling, inquiryValues: inquiryValues, inquiryError: inquiryError, embedded: true, onInquiryClose: onInquiryClose, onInquirySubmit: onInquirySubmit, onInquiryFieldChange: onInquiryFieldChange })) : (_jsxs(_Fragment, { children: [_jsx(LocationSearch, { t: t, isManualSearchEnabled: isManualSearchEnabled, query: query, suggestions: suggestions, suggestionsOpen: suggestionsOpen, isSuggestionsLoading: isSuggestionsLoading, onQueryChange: onQueryChange, onQuerySubmit: onQuerySubmit, onSuggestionSelect: onSuggestionSelect, onDismissSuggestions: onDismissSuggestions }), _jsx(CampaignStatus, { campaign: searchResult?.campaign, t: t }), locationError != null && !isManualSearchEnabled && (_jsx(StatusBanner, { tone: "error", children: locationError })), searchResult?.ok === false && (_jsx(StatusBanner, { tone: "error", children: searchResult.error ?? '' })), isSearching ? (_jsxs("div", { className: "jwi-flex jwi-flex-col", children: [_jsx("div", { className: "jwi-w-full jwi-flex-shrink-0 jwi-border-b jwi-border-[#e6e1d7] jwi-pb-3", children: _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-[pulse_2s_ease-in-out_infinite] jwi-rounded-full jwi-bg-[#ece8df]" }) }), _jsxs("div", { className: "jwi-mt-3 jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] })) : (_jsxs(_Fragment, { children: [searchResult?.ok && (_jsx(DealerList, { dealers: visibleDealers, total: total, selectedDealerName: selectedDealerName, activeDealerName: activeDealerName, maxHeightClassName: "jwi-max-h-none", autoScrollToActive: true, enableInternalScroll: false, t: t, buttonStyling: buttonStyling, borderStyling: borderStyling, markets: markets, onStartInquiry: onStartInquiry, onSelectDealer: handleDealerFocus })), showMoreButton] }))] })) }), !showInquiryInMapPopup && !showInquirySuccessScreen && !mobileMapExpanded && (_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded((open) => !open), className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-20 jwi-flex jwi-h-14 jwi-items-center jwi-justify-center jwi-gap-2 jwi-rounded-t-[16px] jwi-border-t jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111] jwi-shadow-[0_-6px_20px_rgba(0,0,0,0.12)]", children: [t.openMap, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(-90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] })), mobileMapExpanded && !showInquiryInMapPopup && !showInquirySuccessScreen && (_jsxs("div", { className: "jwi-absolute jwi-inset-x-0 jwi-bottom-0 jwi-z-30 jwi-h-[78vh] jwi-overflow-hidden jwi-rounded-t-[16px] jwi-bg-white jwi-shadow-[0_-12px_36px_rgba(0,0,0,0.22)]", children: [_jsxs("button", { type: "button", onClick: () => setMobileMapExpanded(false), className: "jwi-flex jwi-h-12 jwi-w-full jwi-items-center jwi-justify-center jwi-gap-2 jwi-border-b jwi-border-[#e6e1d7] jwi-bg-white jwi-text-sm jwi-font-semibold jwi-text-[#111111]", children: [t.closeMapMobile, _jsx("span", { className: "jwi-inline-flex", style: { transform: 'rotate(90deg)' }, children: _jsx(ArrowRightIcon, { className: "jwi-h-4 jwi-w-4 jwi-shrink-0" }) })] }), _jsx("div", { className: "jwi-h-[calc(78vh-48px)] jwi-w-full", children: mapCanvas })] }))] }) }))] }));
342
339
  }
@@ -14,9 +14,9 @@ type DealerListProps = {
14
14
  t: WidgetStrings;
15
15
  buttonStyling?: JotulWidgetButtonStyling;
16
16
  borderStyling?: JotulWidgetBorderStyling;
17
- market?: string;
17
+ markets?: string[];
18
18
  onStartInquiry: (dealerName: string) => void;
19
19
  onSelectDealer?: (dealerName: string) => void;
20
20
  };
21
- export declare function DealerList({ dealers, total, selectedDealerName, activeDealerName, maxHeightClassName, fitAvailableHeight, autoScrollToActive, enableInternalScroll, headerRight, t, buttonStyling, borderStyling, market, onStartInquiry, onSelectDealer, }: DealerListProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function DealerList({ dealers, total, selectedDealerName, activeDealerName, maxHeightClassName, fitAvailableHeight, autoScrollToActive, enableInternalScroll, headerRight, t, buttonStyling, borderStyling, markets, onStartInquiry, onSelectDealer, }: DealerListProps): import("react/jsx-runtime").JSX.Element;
22
22
  export {};
@@ -6,8 +6,8 @@ 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';
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, }) {
9
+ import { asText, formatDistance, getDealerAddressLines, getDealerKey, getDealerName, isExclusiveDealer, } from '../../utils';
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, markets, onStartInquiry, onSelectDealer, }) {
11
11
  const cardRefs = useRef({});
12
12
  useEffect(() => {
13
13
  if (!autoScrollToActive || !activeDealerName)
@@ -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,16 +30,15 @@ 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
- const badgeImage = market === 'NO' ? ildstedetDealer : exclusiveDealerBadge;
42
- const badgeAlt = market === 'NO' ? 'Ildstedet dealer' : 'Jotul exclusive dealer';
39
+ const isNorway = markets?.includes('NO') ?? false;
40
+ const badgeImage = isNorway ? ildstedetDealer : exclusiveDealerBadge;
41
+ const badgeAlt = isNorway ? 'Ildstedet dealer' : 'Jotul exclusive dealer';
43
42
  return (_jsx("img", { src: typeof badgeImage === 'string'
44
43
  ? badgeImage
45
44
  : badgeImage.src, alt: badgeAlt, className: "jwi-h-auto jwi-w-[40px] jwi-shrink-0 jwi-rounded-full jwi-m-0" }));
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { checkWidgetAuthorization, DEFAULT_WIDGET_LOCALE_TAG, normalizeWidgetLocale, resolveWidgetUiLocale, searchDealersByCoordinates, searchDealersByPostalCode, JotulWidget, type CheckWidgetAuthorizationOptions, type DealerSearchResponse, type JotulWidgetBorderStyling, type JotulWidgetButtonStyling, type JotulWidgetLocale, type JotulWidgetProps, type JotulWidgetStyling, type JotulWidgetType, type WidgetAuthClientResponse, } from './JotulWidget';
1
+ export { checkWidgetAuthorization, DEFAULT_WIDGET_LOCALE_TAG, normalizeWidgetLocale, resolveWidgetUiLocale, searchDealersByCoordinates, searchDealersByPostalCode, JotulWidget, type CheckWidgetAuthorizationOptions, type DealerSearchResponse, type JotulWidgetBorderStyling, type JotulWidgetButtonStyling, type JotulWidgetHandle, type JotulWidgetLocale, type JotulWidgetProps, type JotulWidgetStyling, type JotulWidgetType, type WidgetAuthClientResponse, } from './JotulWidget';
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;
@@ -47,8 +48,9 @@ export type CheckWidgetAuthorizationOptions = {
47
48
  fetcher?: typeof fetch;
48
49
  /** BCP 47 language tag (e.g. `nb-NO`, `en-US`) sent to the API as `locale`. */
49
50
  locale?: string;
50
- /** ISO 3166-1 alpha-2 market/country (e.g. `NO`, `SE`) sent to the API as `market`. */
51
- market?: string;
51
+ /** ISO 3166-1 alpha-2 market(s)/country(ies) (e.g. `["NO", "SE"]`) sent to the API as `market` params. */
52
+ markets?: 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;
@@ -73,6 +75,11 @@ export type WidgetTriggerRenderProps = {
73
75
  className: string;
74
76
  style?: CSSProperties;
75
77
  };
78
+ export type JotulWidgetHandle = {
79
+ open: () => void;
80
+ close: () => void;
81
+ isOpen: boolean;
82
+ };
76
83
  export type JotulWidgetProps = {
77
84
  type?: string;
78
85
  endpoint?: string;
@@ -80,8 +87,9 @@ export type JotulWidgetProps = {
80
87
  productName?: string;
81
88
  /** BCP 47 tag for widget UI strings and API `locale` (default `nb-NO` when omitted). */
82
89
  locale?: string;
83
- /** ISO 3166-1 alpha-2 market filter for dealers and geocoder country bias (`NO`, `SE`, …). */
84
- market?: string;
90
+ /** ISO 3166-1 alpha-2 market(s) to filter dealers across multiple countries (e.g. `["NO", "SE"]`). */
91
+ markets?: string[];
92
+ scope?: JotulWidgetScope;
85
93
  brands?: string[];
86
94
  /** Optional Sanity campaign slug used to limit dealer results to campaign dealers. */
87
95
  campaignSlug?: string;
@@ -90,14 +98,17 @@ export type JotulWidgetProps = {
90
98
  * Optional custom trigger for widgets with an open action (`productPage`, `findDealerDrawer`).
91
99
  * - Pass a ReactNode for simple custom markup.
92
100
  * - Pass a render function to fully control button behavior and bind `onOpen`.
101
+ * - Pass `null` to hide the embedded trigger and control the widget externally via a ref.
93
102
  */
94
- trigger?: ReactNode | ((props: WidgetTriggerRenderProps) => ReactNode);
103
+ trigger?: ReactNode | ((props: WidgetTriggerRenderProps) => ReactNode) | null;
95
104
  /** @deprecated Use `trigger` instead. */
96
105
  productPageTrigger?: ReactNode | ((props: WidgetTriggerRenderProps) => ReactNode);
97
106
  /**
98
107
  * @deprecated Use `trigger` instead.
99
108
  */
100
109
  findDealerDrawerTrigger?: ReactNode | ((props: WidgetTriggerRenderProps) => ReactNode);
110
+ /** Ref handle for imperative open/close control (useful with `trigger={null}`). */
111
+ widgetRef?: React.Ref<JotulWidgetHandle>;
101
112
  };
102
113
  export type DealerRecord = Record<string, unknown>;
103
114
  export type InquiryFormValues = {
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.2",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "sideEffects": [