UNPKG

storybook-mobile-addon

Version:

This addon offers suggestions on how you can improve the HTML, CSS and UX of your components to be more mobile-friendly.

152 lines (145 loc) 24.2 kB
import e,{Fragment,useRef,useEffect,useState,cloneElement,useMemo}from'react';import {addons,types,useAddonState,useChannel}from'storybook/manager-api';import {AddonPanel}from'storybook/internal/components';import {styled}from'storybook/theming';import {createScheduler}from'lrt';import {STORY_RENDERED}from'storybook/internal/core-events';var M="storybook/mobile-addon",O="storybook/mobile-addon",z=`${M}/panel`,$="storybook/viewport",A="reset",q="mobile1";var se=t=>{let o=[];for(;t.parentNode;){let n=0,s=0;for(let l=0;l<t.parentNode.childNodes.length;l++){let i=t.parentNode.childNodes[l];i.nodeName===t.nodeName&&(i===t&&(s=n),n++);}t.hasAttribute("id")&&t.id!==""?o.unshift(`${t.nodeName.toLowerCase()}#${t.id}`):t.classList.toString()!==""&&t.tagName!=="BODY"?o.unshift(`${t.nodeName.toLowerCase()}.${t.classList.toString()}`):n>1?o.unshift(`${t.nodeName.toLowerCase()}:eq(${s})`):o.unshift(t.nodeName.toLowerCase()),t=t.parentNode;}let r=["html","body","div#root"];return o.filter(n=>!r.includes(n)).join(" > ")},f=se;var d=(t,o)=>Array.from(t.querySelectorAll(o)),N=(t,o)=>{let r=[];try{r=Array.from(t[o].cssRules);}catch{}return r},F=t=>t.nodeName==="A"?"a":t.nodeName==="BUTTON"?"button":`${t.nodeName.toLowerCase()}[role="button"]`,H=(t,o)=>t.map(r=>{let n="";if(r.labels&&r.labels[0])n=r.labels[0].textContent;else if(r.parentElement.nodeName==="LABEL")n=r.parentElement.textContent;else if(r.id){let s=o.querySelector(`label[for="${r.id}"]`);s&&(n=s.textContent);}return {labelText:n,path:f(r),type:r.type}}),le={email:true,number:true,password:true,search:true,tel:true,text:true,url:true},ae=t=>{let r=d(t,"input").filter(n=>{let s=n.getAttribute("type"),l=n.getAttribute("autocomplete");return le[s]&&!l});return H(r,t)},ue=t=>{let o=d(t,'input[type="number"]');return H(o,t)},pe=t=>{let o=d(t,'input[type="text"]').concat(d(t,"input:not([type])")).filter(r=>!r.getAttribute("inputmode"));return H(o,t)},V=t=>({autocomplete:ae(t),inputType:pe(t),inputTypeNumber:ue(t)}),de=(t,o)=>o.top<=t.bottom&&o.bottom>=t.top&&o.left<=t.right&&o.right>=t.left,me=({bounding:{height:t,width:o},close:r,el:n})=>({close:r,height:Math.floor(t),html:n.innerHTML,path:f(n),text:n.textContent,type:n.nodeName==="A"?"a":n.nodeName==="BUTTON"?"button":`${n.nodeName.toLowerCase()}[role="button"]`,width:Math.floor(o)}),w=32,T=8,ce=({height:t,width:o})=>t<w||o<w;function*he(t){let o=d(t,"button").concat(d(t,'[role="button"]')).concat(d(t,"a")),r=Array.from(new Set(o)).map(i=>[i,i.getBoundingClientRect()]),{length:n}=o,s=[],l=[];for(let i=0;i<n;i++){let a=o[i],u=a.getBoundingClientRect(),c={bottom:u.bottom+T,left:u.left-T,right:u.right+T,top:u.top-T},p=r.filter(([m,k])=>m!==a&&de(c,k)),v=ce(u);if(v||p.length>0){let m=me({bounding:u,close:p,el:a});v&&s.push(m),p.length>0&&l.push(m);}yield i;}return {tooClose:l,underMinSize:s}}function*ge(t){let o=d(t,"button").concat(d(t,'[role="button"]')),r=d(t,"a"),n=o.concat(r),{length:s}=n,l=[];for(let i=0;i<s;i++){let a=n[i];getComputedStyle(a)["-webkit-tap-highlight-color"]==="rgba(0, 0, 0, 0)"&&l.push({html:a.innerHTML,path:f(a),text:a.textContent,type:F(a)}),yield i;}return l}var B=600;function*ye(t){let o=d(t,"img"),{length:r}=o,n=[];for(let s=0;s<r;s++){let l=o[s],i=l.getAttribute("srcset"),a=l.getAttribute("src");!i&&a&&(a.endsWith("svg")||(Number.parseInt(getComputedStyle(l).width,10)>B||l.naturalWidth>B)&&n.push({alt:l.alt,path:f(l),src:l.src})),yield s;}return n}function*fe(t){let o=/url\(".*?(.png|.jpg|.jpeg)"\)/,r=d(t,"#root *").filter(u=>{let p=getComputedStyle(u)["background-image"];return p&&o.test(p)&&u.clientWidth>200});if(r.length===0)return [];let n=new Map;Object.keys(t.styleSheets).forEach(u=>{N(t.styleSheets,u).forEach(c=>{if(c)try{r.forEach(p=>{p.matches(c.selectorText)&&n.set(p,(n.get(p)||[]).concat(c));});}catch{}});});let s=/-webkit-min-device-pixel-ratio|min-resolution|image-set/,l=[],i=Array.from(n.entries()),{length:a}=i;for(let u=0;u<a;u++){let[c,p]=i[u];if(p&&p.some(m=>!s.test(m))){let m=getComputedStyle(c).backgroundImage,k=/url\("(.*)"\)/.test(m)?m.match(/url\("(.*)"\)/)[1]:void 0;l.push({path:f(c),src:k});}yield u;}return l}var be=(t,o)=>{let r=t.styleSheets,n=[],s=/:active$/;return Object.keys(r).forEach(l=>{N(r,l).forEach(i=>{if(i&&i.selectorText&&s.test(i.selectorText)){let a=i.selectorText.replace(s,"");try{o.matches(a)&&n.push(i);}catch{}}});}),n};function*Se(t){let o=d(t,"button").concat(d(t,'[role="button"]')),r=d(t,"a"),n=o.concat(r),{length:s}=n,l=[];for(let i=0;i<s;i++){let a=n[i];be(t,a).length>0&&l.push({html:a.innerHTML,path:f(a),text:a.textContent,type:F(a)}),yield i;}return l}var Te=(t,o)=>{let r=t.styleSheets,n=[];return Object.keys(r).forEach(s=>{N(r,s).forEach(i=>{if(i)try{o.matches(i.selectorText)&&n.push(i.cssText);}catch{}});}),n};function*ve(t){let o=d(t,"#root *"),{length:r}=o,n=[];for(let s=0;s<r;s++){let l=o[s],a=Te(t,l).find(u=>/100vh/.test(u));a&&n.push({css:a,el:l,path:f(l)}),yield s;}return n}var S=t=>{let o=createScheduler({chunkBudget:100}),r=o.runTask(t);return {abort:()=>o.abortTask(r),task:r}},j=(t,o,r)=>{let n={active:S(Se(t)),backgroundImg:S(fe(t)),height:S(ve(t)),srcset:S(ye(t)),tapHighlight:S(ge(t)),touchTarget:S(he(t))},s=Object.keys(n),l=s.length;return s.forEach(i=>{n[i].task.then(a=>{o(u=>({...u,[i]:a})),--l===0&&r(true);});}),()=>s.forEach(i=>n[i].abort())};var E="#0965df",xe="#bd4700",Y=` padding: .25rem .5rem; font-weight: bold; display:inline-block; border-radius: 10px; margin-bottom: 1rem; svg { margin-right: .25rem; display: inline-block; height: .7rem; line-height: 1; position: relative; top: .03rem; letter-spacing: .01rem; } `,we=styled.div` color: ${xe}; background-color: hsl(41, 100%, 92%); ${Y} `,C=()=>e.createElement(we,null,e.createElement("svg",{"aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 576 512",xmlns:"http://www.w3.org/2000/svg"},e.createElement("path",{d:"M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z",fill:"currentColor"})),"warning"),Ee=styled.div` background-color: hsla(214, 92%, 45%, 0.1); color: ${E}; ${Y} `,W=()=>e.createElement(Ee,null,e.createElement("svg",{"aria-hidden":"true",className:"svg-inline--fa fa-magic fa-w-16 fa-5x","data-icon":"magic","data-prefix":"fas",focusable:"false",role:"img",viewBox:"0 0 512 512",xmlns:"http://www.w3.org/2000/svg"},e.createElement("path",{className:"",d:"M224 96l16-32 32-16-32-16-16-32-16 32-32 16 32 16 16 32zM80 160l26.66-53.33L160 80l-53.34-26.67L80 0 53.34 53.33 0 80l53.34 26.67L80 160zm352 128l-26.66 53.33L352 368l53.34 26.67L432 448l26.66-53.33L512 368l-53.34-26.67L432 288zm70.62-193.77L417.77 9.38C411.53 3.12 403.34 0 395.15 0c-8.19 0-16.38 3.12-22.63 9.38L9.38 372.52c-12.5 12.5-12.5 32.76 0 45.25l84.85 84.85c6.25 6.25 14.44 9.37 22.62 9.37 8.19 0 16.38-3.12 22.63-9.37l363.14-363.15c12.5-12.48 12.5-32.75 0-45.24zM359.45 203.46l-50.91-50.91 86.6-86.6 50.91 50.91-86.6 86.6z",fill:"currentColor"})),"hint"),y=styled.div` padding: 1rem; `,L=styled.div` display: inline-block; padding-top: 0.25rem; height: 2rem; min-width: 1rem; width: auto; background-color: hsla(0, 0%, 50%, 0.1); border-radius: 3px; li { list-style-type: none; } img, svg { max-height: 2rem !important; min-height: 1rem !important; width: auto !important; } `,G=styled.img` height: 4rem; width: auto; max-width: 100%; background-color: hsla(0, 0%, 0%, 0.2); `,h=styled.li` margin-bottom: 0.5rem; ${t=>t.noStyle?"list-style-type: none;":""}; `,Le=styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr)); font-size: ${t=>t.theme.typography.size.s2}px; p { line-height: 1.4; } h3 { font-size: ${t=>t.theme.typography.size.s2}px; font-weight: bold; margin-bottom: 0.5rem; margin-top: 0; } code { background: hsla(0, 0%, 50%, 0.1); border-radius: 3px; } summary { cursor: pointer; display: block; margin-right: 1rem; padding: 0.2rem 0.3rem; border-radius: 5px; color: ${E}; &:focus { outline: none; box-shadow: 0 0 0 3px ${t=>t.theme.color.mediumlight}; } } ul { padding-left: 1.25rem; max-height: 12rem; overflow: auto; padding-bottom: 0.5rem; li { margin-bottom: 0.3rem; } } a { text-decoration: none; color: ${E}; &:hover { border-bottom: 1px solid ${E}; } } > div { border-bottom: 1px solid ${t=>t.theme.color.medium}; border-right: 1px solid ${t=>t.theme.color.medium}; } `,_=styled.div` display: flex; align-items: center; padding: 0 0.75rem; grid-column: 1 / -1; height: 2.875rem; `,U=styled.button` margin-left: 0.5rem; border-radius: 3px; padding: 0.2rem 0.5rem; cursor: pointer; font-family: inherit; color: inherit; font-size: 100%; background-color: transparent; appearance: none; box-shadow: none; border: 1px solid; &:hover { background-color: hsla(0, 0%, 0%, 0.15); } `,X=styled.div` cursor: progress; display: inline-block; overflow: hidden; position: relative; margin-right: 0.7rem; height: 1.25rem; width: 1.25rem; border-width: 2px; border-style: solid; border-radius: 50%; border-color: rgba(97, 97, 97, 0.29); border-top-color: rgb(100, 100, 100); animation: spinner 0.7s linear infinite; mix-blend-mode: difference; @keyframes spinner { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } `,b="Learn more",Ce=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(W,null),e.createElement("h3",null,e.createElement("code",null,":active")," styles on iOS"),e.createElement("p",null,e.createElement("code",null,":active")," styles will only appear in iOS"," ",e.createElement("a",{href:"https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari",rel:"noopener noreferrer",target:"_blank"},"if a touch listener is added to the element or one of its ancestors"),". Once activated in this manner, ",e.createElement("code",null,":active")," styles (along with ",e.createElement("code",null,":hover")," styles) will be applied immediately in iOS when a user taps, possibly creating a confusing UX. (On Android, ",e.createElement("code",null,":active")," styles are applied with a slight delay to allow the user to use gestures like scroll without necessarily activating ",e.createElement("code",null,":active")," ","styles.)"),e.createElement("ul",null,t.map((o,r)=>e.createElement(h,{key:r},e.createElement("code",null,o.type)," with content\xA0\xA0",o.text?e.createElement("b",null,o.text):o.html?e.createElement(L,{dangerouslySetInnerHTML:{__html:o.html}}):"[no text found]"))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("p",{style:{marginTop:"1rem"}},e.createElement("a",{href:"https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari/33681490#33681490",rel:"noopener noreferrer",target:"_blank"},"Relevant Stack Overflow thread")))),Ie=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(W,null),e.createElement("h3",null,"Tap style removed from tappable element"),e.createElement("p",null,"These elements have an invisible"," ",e.createElement("code",null,"-webkit-tap-highlight-color"),". While this might be intentional, please verify that they have appropriate tap indication styles added through other means."),e.createElement("ul",null,t.map((o,r)=>e.createElement(h,{key:r},e.createElement("code",null,o.type)," with content\xA0\xA0",o.text?e.createElement("b",null,o.text):o.html?e.createElement(L,{dangerouslySetInnerHTML:{__html:o.html}}):"[no text found]"))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("p",null,"Some stylesheets remove the tap indication highlight shown on iOS and Android browsers by adding the code"," ",e.createElement("code",null,"-webkit-tap-highlight-color: transparent"),". In order to maintain a good mobile experience, tap styles should be added via appropriate ",e.createElement("code",null,":active")," CSS styles (though, note that"," ",e.createElement("a",{href:"https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari",rel:"noopener noreferrer",target:"_blank"},e.createElement("code",null,":active")," styles work inconsistently in iOS"),") , or via JavaScript on the ",e.createElement("code",null,"touchstart")," event."))),Me=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(C,null),e.createElement("h3",null,"Input with no ",e.createElement("code",null,"autocomplete")," attribute"),e.createElement("p",null,"Most textual inputs should have an explicit"," ",e.createElement("code",null,"autocomplete")," attribute."),e.createElement("p",null,"If you truly want to disable autocomplete, try using a"," ",e.createElement("a",{href:"https://bugs.chromium.org/p/chromium/issues/detail?id=468153#c164",rel:"noopener noreferrer",target:"_blank"},"semantically valid but unique value rather than"," ",e.createElement("code",null,'autocomplete="off"')),", which doesn't work in Chrome."),e.createElement("p",null,"Note: ",e.createElement("code",null,"autocomplete")," is styled as"," ",e.createElement("code",null,"autoComplete")," in JSX."),e.createElement("ul",null,t.map((o,r)=>e.createElement(h,{key:r},e.createElement("code",null,'input type="',o.type,'"')," and label"," ",e.createElement("b",null,o.labelText||"[no label found]")))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("ul",null,e.createElement("li",null,e.createElement("a",{href:"https://developers.google.com/web/updates/2015/06/checkout-faster-with-autofill",rel:"noopener noreferrer",target:"_blank"},"Autocomplete documentation by Google")),e.createElement("li",null,e.createElement("a",{href:"https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete",rel:"noopener noreferrer",target:"_blank"},"Autocomplete documentation by Mozilla"))))),Ae=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(W,null),e.createElement("h3",null,"Plain input type ",e.createElement("code",null,"text")," detected"),e.createElement("p",null,"This will render the default text keyboard on mobile (which could very well be what you want!) If you haven't already, take a moment to make sure this is correct. You can use"," ",e.createElement("a",{href:"https://better-mobile-inputs.netlify.com/",rel:"noopener noreferrer",target:"_blank"},"this tool")," ","to explore keyboard options."),e.createElement("ul",null,t.map((o,r)=>e.createElement(h,{key:r},e.createElement("code",null,'input type="',o.type,'"')," and label"," ",e.createElement("b",null,o.labelText||"[no label found]")))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("p",null,e.createElement("a",{href:"https://css-tricks.com/better-form-inputs-for-better-mobile-user-experiences/",rel:"noopener noreferrer",target:"_blank"},"Article reviewing the importance of using correct input types on the mobile web from CSS Tricks.")))),Ne=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(W,null),e.createElement("h3",null,"Input type ",e.createElement("code",null,"number")," detected"),e.createElement("p",null,e.createElement("code",null,'<input type="text" inputmode="decimal"/>')," ","could give you improved usability over"," ",e.createElement("code",null,'<input type="number" />'),"."),e.createElement("p",null,"Note: ",e.createElement("code",null,"inputmode")," is styled as ",e.createElement("code",null,"inputMode")," ","in JSX."," "),e.createElement("ul",null,t.map((o,r)=>e.createElement(h,{key:r},e.createElement("code",null,'input type="',o.type,'"')," and label"," ",e.createElement("b",null,o.labelText||"[no label found]")))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("p",null,e.createElement("a",{href:"https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/",rel:"noopener noreferrer",target:"_blank"},"Overview of the issues with"," ",e.createElement("code",null,'input type="number"')," from gov.uk.")))),He=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(W,null),e.createElement("h3",null,"Usage of ",e.createElement("code",null,"100vh")," CSS"),e.createElement("p",null,e.createElement("a",{href:"https://chanind.github.io/javascript/2019/09/28/avoid-100vh-on-mobile-web.html",rel:"noopener noreferrer",target:"_blank"},"Viewport units are tricky on mobile.")," ","On some mobile browers, depending on scroll position,"," ",e.createElement("code",null,"100vh")," might take up more than 100% of screen height due to browser chrome like the address bar."),e.createElement("ul",null,t.map(({path:o},r)=>e.createElement(h,{key:r},e.createElement("code",null,o))))),Pe=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(C,null),e.createElement("h3",null,"Non-dynamic background image"),e.createElement("p",null,"Downloading larger-than-necessary images hurts performance for users on mobile. You can use"," ",e.createElement("a",{href:"https://developer.mozilla.org/en-US/docs/Web/CSS/image-set",rel:"noopener noreferrer",target:"_blank"},e.createElement("code",null,"image-set"))," ","to serve an appropriate background image based on the user's device resolution."),e.createElement("ul",null,t.map(({alt:o,src:r},n)=>e.createElement(h,{key:n,noStyle:true},e.createElement("div",null,e.createElement(G,{alt:o,src:r}))))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("ul",null,e.createElement("li",null,e.createElement("a",{href:"https://css-tricks.com/responsive-images-css/",rel:"noopener noreferrer",target:"_blank"},"Article discussing responsive background images in greater detail, including the interaction of"," ",e.createElement("code",null,"image-set")," with media queries, from CSS Tricks."))))),_e=({warnings:t})=>!t||t.length===0?null:e.createElement(y,null,e.createElement(C,null),e.createElement("h3",null,"Large image without ",e.createElement("code",null,"srcset")),e.createElement("p",null,"Downloading larger-than-necessary images hurts performance for users on mobile. You can use ",e.createElement("code",null,"srcset")," to customize image sizes for different device resolutions and sizes."),e.createElement("ul",null,t.map(({alt:o,src:r},n)=>e.createElement(h,{key:n,noStyle:true},e.createElement("div",null,e.createElement(G,{alt:o,src:r}))))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("ul",null,e.createElement("li",null,e.createElement("a",{href:"https://cloudfour.com/thinks/responsive-images-the-simple-way",rel:"noopener noreferrer",target:"_blank"},"Summary of the why and how of responsive images")),e.createElement("li",null,e.createElement("a",{href:"https://www.responsivebreakpoints.com/",rel:"noopener noreferrer",target:"_blank"},"A tool to generate responsive images"))))),De=({warnings:t})=>{if(!t)return null;let{tooClose:o,underMinSize:r}=t;return r.length===0&&o.length===0?null:e.createElement(y,null,e.createElement(C,null),r.length>0&&e.createElement("div",null,e.createElement("h3",null,"Small touch target"),e.createElement("p",null,"With heights and/or widths of less than ",w,"px, these tappable elements could be difficult for users to press:"),e.createElement("ul",null,r.map((n,s)=>e.createElement(h,{key:s},e.createElement("code",null,n.type)," with content\xA0\xA0",n.text?e.createElement("b",null,n.text):n.html?e.createElement(L,{dangerouslySetInnerHTML:{__html:n.html}}):"[no text found]")))),o.length>0&&e.createElement("div",null,e.createElement("h3",{style:{marginTop:r.length>0?".5rem":"0"}},"Touch targets close together"," "),e.createElement("p",null,"These tappable elements are less than"," ",T,"px from at least one other tappable element:"),e.createElement("ul",null,o.map((n,s)=>e.createElement(h,{key:s},e.createElement("code",null,n.type)," with content\xA0\xA0",n.text?e.createElement("b",null,n.text):n.html?e.createElement(L,{dangerouslySetInnerHTML:{__html:n.html}}):"[no text found]")))),e.createElement("details",null,e.createElement("summary",null,b),e.createElement("ul",null,e.createElement("li",null,e.createElement("a",{href:"https://www.nngroup.com/articles/touch-target-size/",rel:"noopener noreferrer",target:"_blank"},"Touch target size article from the Nielsen Norman Group")),e.createElement("li",null,e.createElement("a",{href:"https://web.dev/accessible-tap-targets/",rel:"noopener noreferrer",target:"_blank"},"Tap target size recommendations from Google")))))},Oe=t=>`${t} issue${t!==1?"s":""} found`,D=()=>e.createElement(_,null,e.createElement(X,null),e.createElement("span",null,"Running scan...")),ze=({container:t})=>{let[o,r]=useState(void 0),[n,s]=useState(false),[l,i]=useState(0);useEffect(()=>(s(false),r(V(t)),j(t,r,s)),[t,l]);let a=useMemo(()=>o?Object.keys(o).reduce((p,v)=>{let m=o[v],k=Array.isArray(m)?+(m.length>0):Object.keys(m).map(I=>m[I]).reduce((I,re)=>I+ +(re.length>0),0);return p+k},0):0,[o]);if(!o)return e.createElement(D,null);let u=()=>i(p=>p+1);if(a===0&&n)return e.createElement(_,null,e.createElement("span",null,"Scan complete! No issues found."),e.createElement(U,{onClick:u,type:"button"},"Rescan"));let c=Oe(a);return e.createElement(Le,null,e.createElement(_,null,n?e.createElement(e.Fragment,null,e.createElement("span",null,"Scan complete! ",c,"."),e.createElement(U,{onClick:u,type:"button"},"Rescan")):e.createElement(e.Fragment,null,e.createElement(X,null),e.createElement("span",null,a>0?`Running scan - ${c} so far`:"Running scan","..."))),e.createElement(De,{warnings:o.touchTarget}),e.createElement(Me,{warnings:o.autocomplete}),e.createElement(Ae,{warnings:o.inputType}),e.createElement(Ne,{warnings:o.inputTypeNumber}),e.createElement(Ie,{warnings:o.tapHighlight}),e.createElement(Ce,{warnings:o.active}),e.createElement(_e,{warnings:o.srcset}),e.createElement(Pe,{warnings:o.backgroundImg}),e.createElement(He,{warnings:o.height}))},J=ze;var Z=2e3,Q=()=>{let t=document.querySelector("#storybook-preview-iframe");return t?t.contentDocument:null},Fe=({active:t,storyId:o})=>{let[r,n]=useState(void 0),s=useRef(null);useEffect(()=>{n(void 0);let i=()=>{let a=Q();s.current&&clearTimeout(s.current),!a||!a.body?s.current=window.setTimeout(i,Z):n(a.body.innerHTML);};return s.current&&clearTimeout(s.current),s.current=window.setTimeout(i,Z),()=>clearTimeout(s.current)},[o]);let l=Q();return t?!r||!l?e.createElement(D,null):e.createElement(J,{container:l}):null},R=Fe;var Ge=({children:t})=>{let[o,r]=useState("");return useChannel({[STORY_RENDERED]:(...n)=>{r(String(n));}}),cloneElement(t,{storyId:o})},ee=Ge;var Ze=({active:t})=>{let[o,r]=useAddonState($),n=useRef(null);return useEffect(()=>{n.current&&!t?(r({selected:n.current}),n.current=null):t&&(!o||o.selected===A)&&(n.current=A,r({selected:q}));},[t]),null},te=Ze;var et=({active:t})=>e.createElement(Fragment,{key:"storybook-mobile-addon"},e.createElement(te,{active:t}),e.createElement(AddonPanel,{active:t},e.createElement(ee,null,e.createElement(R,{active:t})))),oe=et;addons.register(M,()=>{addons.add(z,{match:({viewMode:t})=>!!t?.match(/^story$/),paramKey:O,render:({active:t})=>e.createElement(oe,{active:t}),title:"Mobile",type:types.PANEL});});//# sourceMappingURL=manager.js.map //# sourceMappingURL=manager.js.map