Bundle data was carrying localized strings (name, usage, items, description, imageAlt, badge) directly, so EN visitors saw German copy on the bundle page and home grid. Strings are now keyed under bundle.<id>.<field> in the i18n catalogue (DE + EN); src/api/bundles.js keeps only structural data + i18n key references. HomePage builds a localizedBundles computed that resolves the keys through t() before passing to the Bundles design-system component, so the existing component stays agnostic of i18n. BundlePage exposes a `bundleCopy` computed for the same reason, and resolvedItems now maps over `itemKeys` instead of static labels. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 line
9.4 KiB
JavaScript
1 line
9.4 KiB
JavaScript
import{A as e,B as t,C as n,G as r,M as i,S as a,T as o,b as s,c,dt as l,ft as u,i as d,j as f,l as p,m,o as h,p as g,r as _,s as v,u as y,ut as b,x}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{a as ee,o as S,t as C}from"./runtime-dom.esm-bundler-CXLmyuFK.js";import{t as w}from"./Icon-BCo6-bGH.js";import{t as T}from"./IconButton-Cw1KbfUO.js";import{t as E}from"./i18n-XDSWEyNo.js";import{t as D}from"./Badge-DiccZCC_.js";import{t as O}from"./_plugin-vue_export-helper-0vLWKQyu.js";var k=[`aria-label`],A=[`placeholder`,`aria-label`],j=[`aria-label`],te=[`aria-label`],ne=[`href`,`aria-selected`,`data-active`,`onMousemove`,`onClick`],re=[`src`,`alt`],ie={class:`flex-1 min-w-0`},M={key:0},N={class:`inline-flex items-center gap-1.5`},P={class:`inline-flex items-center gap-1.5`},F={class:`inline-flex items-center gap-1.5`},I=O({__name:`Search`,props:{modelValue:{type:Boolean,default:!1},products:{type:Array,default:()=>[]},tone:{type:String,default:`brand`,validator:e=>[`brand`,`paper`,`cream`].includes(e)},limit:{type:Number,default:12},emptyPreview:{type:Number,default:6},placeholder:{type:String,default:``}},emits:[`update:modelValue`,`select`],setup(O,{emit:I}){let L=O,R=I,{t:z}=E(),B={brand:{surface:`bg-brand text-cream`,border:`border-cream-line`,inputIcon:`text-cream/70`,input:`text-cream placeholder:text-cream/50`,closeBtn:`text-cream/70 hover:text-cream hover:bg-cream-wash`,hint:`text-cream/60`,kbd:`bg-cream-wash text-cream border-cream-line`,mediaBg:`bg-cream`,title:`text-cream`,meta:`text-cream/70`,price:`text-accent`,noResults:`text-cream/70`,rowActive:`bg-cream-wash`,rowHover:`hover:bg-cream-wash/60`,eyebrowCream:!0},paper:{surface:`bg-paper text-ink`,border:`border-line`,inputIcon:`text-muted`,input:`text-ink placeholder:text-muted`,closeBtn:`text-muted hover:text-brand hover:bg-brand-wash`,hint:`text-muted`,kbd:`bg-cream text-ink border-line`,mediaBg:`bg-cream`,title:`text-ink`,meta:`text-muted`,price:`text-brand`,noResults:`text-muted`,rowActive:`bg-brand-soft-wash`,rowHover:`hover:bg-brand-wash`,eyebrowCream:!1},cream:{surface:`bg-cream text-brand`,border:`border-line`,inputIcon:`text-brand/70`,input:`text-ink placeholder:text-muted`,closeBtn:`text-muted hover:text-brand hover:bg-brand-wash`,hint:`text-muted`,kbd:`bg-paper text-ink border-line`,mediaBg:`bg-paper`,title:`text-ink`,meta:`text-muted`,price:`text-brand`,noResults:`text-muted`,rowActive:`bg-brand-soft-wash`,rowHover:`hover:bg-brand-wash`,eyebrowCream:!1}},V=h(()=>B[L.tone]),H=t(``),U=t(0),W=t(null),G=t(null);function K(e){return(e||``).toString().toLowerCase().normalize(`NFKD`).replace(/[̀-ͯ]/g,``).replace(/ß/g,`ss`)}function q(e,t){if(!t.length)return 0;let n=[{val:K(e.title),weight:5},{val:K(e.brand),weight:3},{val:K(e.size),weight:2},{val:K(e.category),weight:2},{val:(e.keywords||[]).map(K).join(` `),weight:3},{val:K(e.id),weight:1}],r=0;for(let e of t){let t=!1;for(let i of n)i.val&&i.val.includes(e)&&(t=!0,r+=i.weight,i.val.startsWith(e)&&(r+=Math.ceil(i.weight/2)));if(!t)return 0}return r}let J=h(()=>{let e=K(H.value).trim();if(!e)return L.products.slice(0,L.emptyPreview);let t=e.split(/\s+/).filter(Boolean);return L.products.map(e=>({p:e,score:q(e,t)})).filter(({score:e})=>e>0).sort((e,t)=>t.score-e.score).slice(0,L.limit).map(({p:e})=>e)});e(()=>L.modelValue,async e=>{e&&(H.value=``,U.value=0,await s(),W.value?.focus())}),e(J,()=>{U.value=0}),e(()=>L.modelValue,e=>{typeof document>`u`||(document.documentElement.style.overflow=e?`hidden`:``)}),x(()=>{typeof document<`u`&&(document.documentElement.style.overflow=``)});let Y=t(0);function X(){if(typeof window>`u`||!window.visualViewport)return;let e=window.visualViewport;Y.value=Math.max(0,Math.round(window.innerHeight-(e.height+e.offsetTop)))}a(()=>{X(),typeof window<`u`&&window.visualViewport&&(window.visualViewport.addEventListener(`resize`,X),window.visualViewport.addEventListener(`scroll`,X))}),x(()=>{typeof window<`u`&&window.visualViewport&&(window.visualViewport.removeEventListener(`resize`,X),window.visualViewport.removeEventListener(`scroll`,X))});function Z(){R(`update:modelValue`,!1)}function ae(){H.value=``,s(()=>W.value?.focus())}function Q(e){let t=J.value[e];t&&R(`select`,t),Z()}function oe(e){if(e.key===`Escape`){e.preventDefault(),Z();return}J.value.length&&(e.key===`ArrowDown`?(e.preventDefault(),U.value=(U.value+1)%J.value.length,$()):e.key===`ArrowUp`?(e.preventDefault(),U.value=(U.value-1+J.value.length)%J.value.length,$()):e.key===`Enter`&&(e.preventDefault(),Q(U.value)))}function $(){s(()=>{(G.value?.querySelector(`[data-active="true"]`))?.scrollIntoView({block:`nearest`})})}function se(e){return typeof e.price==`number`?`€ ${e.price.toFixed(2).replace(`.`,`,`)}`:e.price?`€ ${e.price}`:``}function ce(e,t,n){n.metaKey||n.ctrlKey||n.shiftKey||n.button===1||(n.preventDefault(),Q(e))}return(e,t)=>(n(),c(d,{to:`body`},[m(C,{"enter-active-class":`transition duration-base ease-out`,"enter-from-class":`opacity-0`,"enter-to-class":`opacity-100`,"leave-active-class":`transition duration-base ease-out`,"leave-from-class":`opacity-100`,"leave-to-class":`opacity-0`},{default:f(()=>[O.modelValue?(n(),y(`div`,{key:0,class:`fixed inset-0 z-[60] font-sans`,role:`dialog`,"aria-modal":`true`,"aria-label":r(z)(`search.label`),onKeydown:oe},[v(`div`,{class:`hidden md:block absolute inset-0 bg-ink/50`,onClick:Z}),m(C,{"enter-active-class":`transition duration-slow ease-out`,"enter-from-class":`md:opacity-0 md:-translate-y-2 translate-y-4`,"enter-to-class":`md:opacity-100 md:translate-y-0 translate-y-0`,"leave-active-class":`transition duration-base ease-out`,"leave-from-class":`md:opacity-100 translate-y-0`,"leave-to-class":`md:opacity-0 translate-y-4`,appear:``},{default:f(()=>[i(v(`div`,{class:b([`relative flex flex-col h-full w-full`,`md:absolute md:left-1/2 md:top-[12vh] md:h-auto`,`md:-translate-x-1/2 md:max-h-[76vh] md:w-[min(640px,92vw)]`,`md:rounded-lg md:shadow-lg md:border`,V.value.surface,V.value.border])},[v(`div`,{class:b([`shrink-0 flex items-center gap-3 px-5 md:px-4 pt-5 md:pt-3 pb-3 border-b`,V.value.border]),style:{"padding-top":`calc(env(safe-area-inset-top) + 1.25rem)`}},[m(w,{name:`search`,size:20,class:b([`shrink-0`,V.value.inputIcon])},null,8,[`class`]),i(v(`input`,{ref_key:`inputRef`,ref:W,"onUpdate:modelValue":t[0]||=e=>H.value=e,type:`search`,autocomplete:`off`,autocorrect:`off`,autocapitalize:`none`,spellcheck:`false`,enterkeyhint:`search`,placeholder:O.placeholder||r(z)(`search.placeholder`),"aria-label":r(z)(`search.label`),class:b([`search-input flex-1 min-w-0 bg-transparent border-0 outline-none text-[17px] md:text-[15px]`,V.value.input])},null,10,A),[[ee,H.value]]),H.value?(n(),c(D,{key:0,as:`button`,variant:`accent`,class:`shrink-0`,"aria-label":r(z)(`search.clear`),onClick:ae},{default:f(()=>[g(u(r(z)(`search.clear`)),1)]),_:1},8,[`aria-label`])):p(``,!0),v(`button`,{type:`button`,class:b([`shrink-0 inline-flex items-center justify-center w-10 h-10 rounded-pill transition-colors`,V.value.closeBtn]),"aria-label":r(z)(`menu.close`),onClick:Z},[m(w,{name:`close`,size:20})],10,j)],2),v(`div`,{ref_key:`listRef`,ref:G,class:`flex-1 overflow-y-auto py-2`,style:{"padding-bottom":`calc(env(safe-area-inset-bottom) + 0.5rem)`},role:`listbox`,"aria-label":r(z)(`search.results`)},[!H.value.trim()&&J.value.length?(n(),y(`p`,{key:0,class:b([`eyebrow px-5 md:px-4 pt-2 pb-1`,V.value.eyebrowCream?`text-cream/70`:``])},u(r(z)(`search.suggested`)),3)):p(``,!0),J.value.length?p(``,!0):(n(),y(`p`,{key:1,class:b([`px-5 md:px-4 py-10 text-center text-sm`,V.value.noResults])},u(r(z)(`search.noResults`)),3)),(n(!0),y(_,null,o(J.value,(e,t)=>(n(),y(`a`,{key:e.id,href:e.href||`#`,role:`option`,"aria-selected":t===U.value,"data-active":t===U.value,class:b([`flex items-center gap-4 px-5 md:px-4 py-3 transition-colors`,t===U.value?V.value.rowActive:V.value.rowHover]),onMousemove:e=>U.value=t,onClick:n=>ce(t,e,n)},[v(`div`,{class:b([`shrink-0 w-14 h-14 rounded-sm overflow-hidden flex items-center justify-center`,V.value.mediaBg])},[e.image?(n(),y(`img`,{key:0,src:e.image,alt:e.title,loading:`lazy`,decoding:`async`,class:`w-full h-full object-contain p-2`},null,8,re)):p(``,!0)],2),v(`div`,ie,[v(`p`,{class:b([`text-[15px] font-semibold leading-tight truncate`,V.value.title])},u(e.title),3),e.size?(n(),y(`p`,{key:0,class:b([`text-[13px] truncate`,V.value.meta])},[g(u(e.size),1),e.brand?(n(),y(`span`,M,` · `+u(e.brand),1)):p(``,!0)],2)):p(``,!0)]),v(`span`,{class:b([`shrink-0 text-[14px] font-semibold`,V.value.price])},u(se(e)),3)],42,ne))),128))],8,te),v(`div`,{class:b([`hidden md:flex shrink-0 items-center gap-4 px-4 py-2 border-t text-[11px]`,V.value.border,V.value.hint])},[v(`span`,N,[v(`kbd`,{class:b([`px-1.5 py-0.5 rounded-sm border font-mono text-[11px]`,V.value.kbd])},`↑`,2),v(`kbd`,{class:b([`px-1.5 py-0.5 rounded-sm border font-mono text-[11px]`,V.value.kbd])},`↓`,2),g(` `+u(r(z)(`search.hint.navigate`)),1)]),v(`span`,P,[v(`kbd`,{class:b([`px-1.5 py-0.5 rounded-sm border font-mono text-[11px]`,V.value.kbd])},`↵`,2),g(` `+u(r(z)(`search.hint.select`)),1)]),v(`span`,F,[v(`kbd`,{class:b([`px-1.5 py-0.5 rounded-sm border font-mono text-[11px]`,V.value.kbd])},`esc`,2),g(` `+u(r(z)(`search.hint.close`)),1)])],2)],2),[[S,O.modelValue]])]),_:1}),O.modelValue?(n(),y(`div`,{key:0,class:`md:hidden fixed right-5 z-[70]`,style:l({bottom:`calc(${Y.value}px + env(safe-area-inset-bottom) + 1.25rem)`})},[m(T,{icon:`close`,variant:`float`,size:`lg`,"icon-stroke-width":2,"aria-label":r(z)(`menu.close`),onClick:Z},null,8,[`aria-label`])],4)):p(``,!0)],40,k)):p(``,!0)]),_:1})]))}},[[`__scopeId`,`data-v-4f4fb8cb`]]);export{I as t}; |