1"use strict";(self.webpackChunkshake=self.webpackChunkshake||[]).push([[2592],{1470:(e,t,n)=>{n.d(t,{A:()=>j});var r=n(6540),s=n(4164),a=n(7559),o=n(3104),i=n(6347),c=n(205),l=n(7485),u=n(1682),d=n(679);function h(e){return r.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)(()=>{const e=t??function(e){return h(e).map(e=>{let{props:{value:t,label:n,attributes:r,default:s}}=e;return{value:t,label:n,attributes:r,default:s}})}(n);return function(e){const t=(0,u.XI)(e,(e,t)=>e.value===t.value);if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some(e=>e.value===t)}function f(e){let{queryString:t=!1,groupId:n}=e;const s=(0,i.W6)(),a=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,l.aZ)(a),(0,r.useCallback)(e=>{if(!a)return;const t=new URLSearchParams(s.location.search);t.set(a,e),s.replace({...s.location,search:t.toString()})},[a,s])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:s}=e,a=p(e),[o,i]=(0,r.useState)(()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find(e=>e.default)??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:a})),[l,u]=f({queryString:n,groupId:s}),[h,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[s,a]=(0,d.Dv)(n);return[s,(0,r.useCallback)(e=>{n&&a.set(e)},[n,a])]}({groupId:s}),v=(()=>{const e=l??h;return m({value:e,tabValues:a})?e:null})();(0,c.A)(()=>{v&&i(v)},[v]);return{selectedValue:o,selectValue:(0,r.useCallback)(e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),b(e)},[u,b,a]),tabValues:a}}var v=n(2303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var k=n(4848);function x(e){let{className:t,block:n,selectedValue:r,selectValue:a,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:l}=(0,o.a_)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),s=i[n].value;s!==r&&(l(t),a(s))},d=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return(0,k.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":n},t),children:i.map(e=>{let{value:t,label:n,attributes:a}=e;return(0,k.jsx)("li",{role:"tab",tabIndex:r===t?0:-1,"aria-selected":r===t,ref:e=>{c.push(e)},onKeyDown:d,onClick:u,...a,className:(0,s.A)("tabs__item",g.tabItem,a?.className,{"tabs__item--active":r===t}),children:n??t},t)})})}function w(e){let{lazy:t,children:n,selectedValue:a}=e;const o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=o.find(e=>e.props.value===a);return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,k.jsx)("div",{className:"margin-top--md",children:o.map((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))})}function y(e){const t=b(e);return(0,k.jsxs)("div",{className:(0,s.A)(a.G.tabs.container,"tabs-container",g.tabList),
1children:[(0,k.jsx)(x,{...t,...e}),(0,k.jsx)(w,{...t,...e})]})}function j(e){const t=(0,v.A)();return(0,k.jsx)(y,{...e,children:h(e.children)},String(t))}},5268:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"ios/shake-ui/overview","title":"Overview","description":"Shake\'s user interface explained and instructions on how to customize it.","source":"@site/docs/ios/shake-ui/overview.md","sourceDirName":"ios/shake-ui","slug":"/ios/shake-ui/overview","permalink":"/docs/ios/shake-ui/overview","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"id":"overview","title":"Overview"},"sidebar":"iosSidebar","previous":{"title":"Import from Instabug","permalink":"/docs/ios/import-from-instabug"},"next":{"title":"Home screen","permalink":"/docs/ios/shake-ui/home-screen"}}');var s=n(4848),a=n(8453),o=n(6025);n(1470),n(9365);const i={id:"overview",title:"Overview"},c=void 0,l={},u=[{value:"Screens",id:"screens",level:2},{value:"Opening Shake",id:"opening-shake",level:2},{value:"Internal feedback collection",id:"internal-feedback-collection",level:3},{value:"Production ticketing system",id:"production-ticketing-system",level:3},{value:"Internal and production crash reporting",id:"internal-and-production-crash-reporting",level:3},{value:"Design and customizations",id:"design-and-customizations",level:2}];function d(e){const t={a:"a",blockquote:"blockquote",h2:"h2",h3:"h3",p:"p",strong:"strong",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsx)(t.p,{children:"Shake's user interface explained and instructions on how to customize it."}),"\n"]}),"\n",(0,s.jsx)("p",{class:"p2 mt-40",children:(0,s.jsxs)(t.p,{children:["You're viewing the iOS docs. Other platforms \u2192 \xa0\n",(0,s.jsx)("a",{href:"/docs/android/shake-ui/overview",children:"Android"}),"\xa0\n",(0,s.jsx)("a",{href:"/docs/react/shake-ui/overview",children:"React Native"}),"\xa0\n",(0,s.jsx)("a",{href:"/docs/flutter/shake-ui/overview",children:"Flutter"}),"\xa0\n",(0,s.jsx)("a",{href:"/docs/web/shake-ui",children:"Web"}),"\xa0"]})}),"\n",(0,s.jsx)(t.h2,{id:"screens",children:"Screens"}),"\n",(0,s.jsx)(t.p,{children:"The Shake UI consists of nine screens, and here's how they're related:"}),"\n",(0,s.jsx)("table",{class:"media-container mt-40 mb-40",children:(0,s.jsx)("img",{alt:"Shake screens structure",width:"544",src:(0,o.Ay)("screens/shake-screens-structure.svg")})}),"\n",(0,s.jsx)(t.h2,{id:"opening-shake",children:"Opening Shake"}),"\n",(0,s.jsx)(t.p,{children:"You can decide to open either Shake's Home screeen or New ticket screen, depending on the flow you want to achieve.\nListed below are some common use cases that show where you might like to add Shake to your app.\nOf course, it's up to you to decide what best suits your app UX."}),"\n",(0,s.jsx)(t.h3,{id:"internal-feedback-collection",children:"Internal feedback collection"}),"\n",(0,s.jsxs)(t.p,{children:["This entry point is often used during internal testing. Your testers or office colleagues are told to invoke Shake whenever they notice a bug or have a suggestion.\nIn this case, instruct Shake to open the ",(0,s.jsx)(t.a,{href:"/docs/ios/shake-ui/new-ticket-screen",children:"New ticket screen"}),":"]}),"\n",(0,s.jsx)("table",{class:"media-container mt-40 mb-40",children:(0,s.jsx)("img",{alt:"Open Shake New ticket screen",width:"520",src:(0,o.Ay)("screens/open-shake-new-ticket-screen-pointer.svg")})}),"\n",(0,s.jsx)(t.h3,{id:"production-ticketing-system",children:"Production ticketing system"}),"\n",(0,s.jsxs)(t.p,{children:["In production, apps usually add Shake under ",(0,s.jsx)(t.strong,{children:"My account or Settings \u2192 Help"}),".\nThere, they have a ",(0,s.jsx)(t.strong,{children:"Submit feedback"})," button that opens Shake's ",(0,s.jsx)(t.a,{href:"/docs/ios/shake-ui/home-screen",children:"Home screen"}),":"]}),"\n",(0,s.jsx)("table",{class:"media-container mt-40 mb-40",children:(0,s.jsx)("img",{alt:"Open Shake Home screen",width:"520",src:(0,o.Ay)("screens/open-shake-home-screen-pointer.svg")})}),"\n",(0,s.jsx)(t.h3,{id:"internal-and-production-crash-reporting",children:"Internal and production crash reporting"}),"\n",(0,s.jsxs)(t.p,{children:["Lastly, Shake can open automatically after your app crashes.\n",(0,s.jsx)(t.a,{href:"/docs/ios/crash-reports/enable",children:"Enable Crashes"})," and ",(0,s.jsx)(t.a,{href:"/docs/ios/crash-reports/ask-for-description",children:"enable the Ask for crash description sheet"}),"\nso your users can describe what happened before your app crashed on them:"]}),"\n",(0,s.jsx)("table",{class:"media-container mt-40 mb-40",children:(0,s.jsx)("img",{alt:"Open Shake New ticket screen after the crash",width:"520",src:(0,o.Ay)("screens/crash-report-options-pointer.svg")})}),"\n",(0,s.jsx)(t.h2,{id:"design-and-customizations",children:"Design and customizations"}),"\n",(0,s.jsx)(t.p,{children:"Shake supports dark and light mode out of the box, there is no need to code anything.\nIts UI will automatically adapt depending on your app design settings."}),"\n",(0,s.jsx)(t.p,{children:"Shake also supports white labeling, you can change its colors and text from the code."}),"\n",(0,s.jsxs)(t.p,{children:["Lastly, Shake mobile UI has been localized to support ",(0,s.jsx)(t.a,{href:"https://help.shakebugs.com/en/articles/3392092-which-languages-has-shake-sdk-been-translated-to",children:"numerous languages"}),".\nYour users whose default device language is set to one of those will automatically use Shake in their native language."]}),"\n",(0,s.jsxs)("p",{class:"p2 mt-80 mb-10",children:["\u26a1\ufe0f Shake is improved every week.\nStumbled upon a\xa0",(0,s.jsx)("a",{href:"https://feedback.shakebugs.com/bugs",children:"bug"}),"?\nWant a\xa0",(0,s.jsx)("a",{href:"https://feedback.shakebugs.com/feature-requests",children:"new feature"}),"\xa0to be added?\nCreate new tickets and upvote existing ones on the Public feedback board."]}),"\n",(0,s.jsx)("p",{})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var r=n(6540);const s={},a=r.createContext(s);function o(e){const t=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(a.Provider,{value:t},e.children)}},9365:(e,t,n)=>{n.d(t,{A:()=>
1o});n(6540);var r=n(4164);const s={tabItem:"tabItem_Ymn6"};var a=n(4848);function o(e){let{children:t,hidden:n,className:o}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,r.A)(s.tabItem,o),hidden:n,children:t})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.