"use strict";(self.webpackChunk_stencil_stencil_site=self.webpackChunk_stencil_stencil_site||[]).push([[96774],{53545:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=n(85893),r=n(11151),i=n(34259),l=n(18679);const o={title:"Store",sidebar_label:"Stencil Store",description:"Store",slug:"/stencil-store"},a="@stencil/store",c={id:"guides/store",title:"Store",description:"Store",source:"@site/versioned_docs/version-v4.16/guides/store.md",sourceDirName:"guides",slug:"/stencil-store",permalink:"/docs/v4.16/stencil-store",draft:!1,unlisted:!1,editUrl:"https://github.com/ionic-team/stencil-site/tree/main/versioned_docs/version-v4.16/guides/store.md",tags:[],version:"v4.16",frontMatter:{title:"Store",sidebar_label:"Stencil Store",description:"Store",slug:"/stencil-store"},sidebar:"docs",previous:{title:"Service Workers",permalink:"/docs/v4.16/service-workers"},next:{title:"Style Guide",permalink:"/docs/v4.16/style-guide"}},d={},h=[{value:"Installation",id:"installation",level:2},{value:"Example",id:"example",level:2},{value:"API",id:"api",level:2},{value:"<code>createStore&lt;T&gt;(initialState)</code>",id:"createstoretinitialstate",level:3},{value:"<code>store.state</code>",id:"storestate",level:3},{value:"<code>store.on(event, listener)</code>",id:"storeonevent-listener",level:3},{value:"<code>store.onChange(propName, listener)</code>",id:"storeonchangepropname-listener",level:3},{value:"<code>store.get(propName)</code>",id:"storegetpropname",level:3},{value:"<code>store.set(propName, value)</code>",id:"storesetpropname-value",level:3},{value:"<code>store.reset()</code>",id:"storereset",level:3},{value:"<code>store.use(...subscriptions)</code>",id:"storeusesubscriptions",level:3},{value:"Testing",id:"testing",level:2}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"stencilstore",children:"@stencil/store"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/ionic-team/stencil-store",children:"Store"})," is a lightweight shared state library by the stencil core team. It implements a simple key/value map that efficiently re-renders components when necessary."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Lightweight"}),"\n",(0,s.jsx)(t.li,{children:"Zero dependencies"}),"\n",(0,s.jsx)(t.li,{children:"Simple API, like a reactive Map"}),"\n",(0,s.jsx)(t.li,{children:"Best performance"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(i.Z,{groupId:"npm2yarn",children:[(0,s.jsx)(l.Z,{value:"npm",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"npm install @stencil/store --save-dev\n"})})}),(0,s.jsx)(l.Z,{value:"yarn",label:"Yarn",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"yarn add @stencil/store --dev\n"})})}),(0,s.jsx)(l.Z,{value:"pnpm",label:"pnpm",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"pnpm add @stencil/store --save-dev\n"})})})]}),"\n",(0,s.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"store.ts:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-tsx",children:"import { createStore } from \"@stencil/store\";\n\nconst { state, onChange } = createStore({\n  clicks: 0,\n  seconds: 0,\n  squaredClicks: 0\n});\n\nonChange('clicks', value => {\n  state.squaredClicks = value ** 2;\n});\n\nexport default state;\n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"component.tsx:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-tsx",children:"import { Component, h } from '@stencil/core';\nimport state from '../store';\n\n@Component({\n  tag: 'app-profile',\n})\nexport class AppProfile {\n\n  componentWillLoad() {\n    setInterval(() => state.seconds++, 1000);\n  }\n\n  render() {\n    return (\n      <div>\n        <p>\n          <MyGlobalCounter />\n          <p>\n            Seconds: {state.seconds}\n            <br />\n            Squared Clicks: {state.squaredClicks}\n          </p>\n        </p>\n      </div>\n    );\n  }\n}\n\nconst MyGlobalCounter = () => {\n  return (\n    <button onClick={() => state.clicks++}>\n      {state.clicks}\n    </button>\n  );\n};\n"})}),"\n",(0,s.jsx)(t.h2,{id:"api",children:"API"}),"\n",(0,s.jsx)(t.h3,{id:"createstoretinitialstate",children:(0,s.jsx)(t.code,{children:"createStore<T>(initialState)"})}),"\n",(0,s.jsxs)(t.p,{children:["Create a new store with the given initial state. The type is inferred from ",(0,s.jsx)(t.code,{children:"initialState"}),", or can be passed as the generic type ",(0,s.jsx)(t.code,{children:"T"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Returns a ",(0,s.jsx)(t.code,{children:"store"})," object with the following properties."]}),"\n",(0,s.jsx)(t.h3,{id:"storestate",children:(0,s.jsx)(t.code,{children:"store.state"})}),"\n",(0,s.jsx)(t.p,{children:"The state object is proxied, I.E. you can directly get and set properties and Store will automatically take care of component re-rendering when the state object is changed."}),"\n",(0,s.jsx)(t.h3,{id:"storeonevent-listener",children:(0,s.jsx)(t.code,{children:"store.on(event, listener)"})}),"\n",(0,s.jsx)(t.p,{children:"Add a listener to the store for a certain action."}),"\n",(0,s.jsx)(t.h3,{id:"storeonchangepropname-listener",children:(0,s.jsx)(t.code,{children:"store.onChange(propName, listener)"})}),"\n",(0,s.jsx)(t.p,{children:"Add a listener that is called when a specific property changes."}),"\n",(0,s.jsx)(t.h3,{id:"storegetpropname",children:(0,s.jsx)(t.code,{children:"store.get(propName)"})}),"\n",(0,s.jsx)(t.p,{children:"Get a property's value from the store."}),"\n",(0,s.jsx)(t.h3,{id:"storesetpropname-value",children:(0,s.jsx)(t.code,{children:"store.set(propName, value)"})}),"\n",(0,s.jsx)(t.p,{children:"Set a property's value in the store."}),"\n",(0,s.jsx)(t.h3,{id:"storereset",children:(0,s.jsx)(t.code,{children:"store.reset()"})}),"\n",(0,s.jsx)(t.p,{children:"Reset the store to its initial state."}),"\n",(0,s.jsx)(t.h3,{id:"storeusesubscriptions",children:(0,s.jsx)(t.code,{children:"store.use(...subscriptions)"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the given subscriptions in the store. A subscription is an object that defines one or more of the properties ",(0,s.jsx)(t.code,{children:"get"}),", ",(0,s.jsx)(t.code,{children:"set"})," or ",(0,s.jsx)(t.code,{children:"reset"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Like any global state library, state should be reset between each spec test.\nUse the ",(0,s.jsx)(t.code,{children:"dispose()"})," API in the ",(0,s.jsx)(t.code,{children:"beforeEach"})," hook."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-ts",children:"import store from '../store';\n\nbeforeEach(() => {\n  store.dispose();\n});\n"})})]})}function u(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},18679:(e,t,n)=>{n.d(t,{Z:()=>l});n(67294);var s=n(90512);const r={tabItem:"tabItem_Ymn6","#":"#_ftL_"};var i=n(85893);function l(e){let{children:t,hidden:n,className:l}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,s.Z)(r.tabItem,l),hidden:n,children:t})}},34259:(e,t,n)=>{n.d(t,{Z:()=>u});var s=n(67294),r=n(90512),i=n(72957),l=n(82262),o=n(51048);const a={tabList:"tabList__CuJ","#":"#_CEXP",tabItem:"tabItem_LNqP"};var c=n(85893);function d(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:o}=e;const d=[],{blockElementScrollPositionUntilNextRender:h}=(0,i.o5)(),p=e=>{const t=e.currentTarget,n=d.indexOf(t),r=o[n].value;r!==s&&(h(t),l(r))},u=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=d.indexOf(e.currentTarget)+1;t=d[n]??d[0];break}case"ArrowLeft":{const n=d.indexOf(e.currentTarget)-1;t=d[n]??d[d.length-1];break}}t?.focus()};return(0,c.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t),children:o.map((e=>{let{value:t,label:n,attributes:i}=e;return(0,c.jsx)("li",{role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,ref:e=>d.push(e),onKeyDown:u,onClick:p,...i,className:(0,r.Z)("tabs__item",a.tabItem,i?.className,{"tabs__item--active":s===t}),children:n??t},t)}))})}function h(e){let{lazy:t,children:n,selectedValue:r}=e;const i=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===r));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,c.jsx)("div",{className:"margin-top--md",children:i.map(((e,t)=>(0,s.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function p(e){const t=(0,l.Y)(e);return(0,c.jsxs)("div",{className:(0,r.Z)("tabs-container",a.tabList),children:[(0,c.jsx)(d,{...t,...e}),(0,c.jsx)(h,{...t,...e})]})}function u(e){const t=(0,o.default)();return(0,c.jsx)(p,{...e,children:(0,l.h)(e.children)},String(t))}},11151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>l});var s=n(67294);const r={},i=s.createContext(r);function l(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]);