{"version":3,"file":"price-element-section.min.js","mappings":"yBAQA,MAAMA,qBAAqBC,YACzB,6BAAkBC,GAChB,MAAO,CACL,yBACA,gBACA,gBACA,qBACA,uBACA,iBAEJ,CAmDO,iBAAAC,GACLC,KAAKC,uBAELD,KAAKE,QACP,CAEO,wBAAAC,CAAyBC,EAAeC,EAAkBC,GAC/DN,KAAKC,uBAEDD,KAAKO,aAAeF,IAAaC,GACnCN,KAAKE,QAET,CAEQ,oBAAAD,GACDD,KAAKQ,aACRR,KAAKS,aAAa,CAAEC,KAAM,SAC1BV,KAAKQ,WAAWG,UAAY,sHAEhC,CAEQ,MAAAT,GACN,MAAMU,EAAYZ,KAAKQ,WAAWK,cAAc,OAIhD,IAAKb,KAAKc,QAAQC,UAA6C,KAAjCf,KAAKc,QAAQC,SAASC,QACxB,cAA1BhB,KAAKc,QAAQC,UAAsD,SAA1Bf,KAAKc,QAAQC,WACrDf,KAAKc,QAAQG,eAAiBjB,KAAKc,QAAQI,eAI5C,OAHAN,EAAUO,YAAc,GACxBP,EAAUQ,gBAAgB,mBAC1BR,EAAUQ,gBAAgB,QAI5B,MAAMC,EAAQC,SAAStB,KAAKc,QAAQC,SAAU,IAC9C,GAAc,IAAVM,EAEF,YADAT,EAAUO,YAAc,QAI1B,MAAMI,EAAcF,EAAQ,IAAO,EAAI,EACjCG,EAAiC,SAA1BxB,KAAKc,QAAQW,SAAsB,IAAM,GAChDC,EAAS1B,KAAKc,QAAQI,eAEtBS,EAASJ,EAAa,eAAiB,2BAE7C,IAAIK,EAAW,IAEe,SAA1B5B,KAAKc,QAAQe,UAEY,UAA1B7B,KAAKc,QAAQe,UAAsD,QAA9B7B,KAAKc,QAAQG,gBACnDW,EAAW,IAAM5B,KAAKc,QAAQG,cAGhC,MAEMa,EC3GH,SAAqBC,EAAOC,GACZ,iBAAVD,IACTA,EAAQA,EAAME,QAAQ,IAAK,KAE7B,IAAIZ,EAAQ,GACZ,MAAMa,EAAmB,sBACnBC,EAAeH,GAfH,cAiBlB,SAASI,EACPC,EACAC,EACAC,EACAC,GAEA,QAJS,IAATF,IAAAA,EAAY,QACH,IAATC,IAAAA,EAAY,UACL,IAAPC,IAAAA,EAAU,KAENC,MAAMJ,IAAqB,MAAVA,EACnB,OAAO,EAKT,MAAMK,GAFNL,GAAUA,EAAS,KAAOM,QAAQL,IAEbM,MAAM,KAO3B,OANsBF,EAAM,GAAGT,QAC7B,2BACA,KAAKM,MAEaG,EAAM,GAAKF,EAAUE,EAAM,GAAK,GAGtD,CAEA,OAAQP,EAAaU,MAAMX,GAAkB,IAC3C,IAAK,SACHb,EAAQe,EAAqBL,EAAO,GACpC,MACF,IAAK,qBACHV,EAAQe,EAAqBL,EAAO,GACpC,MACF,IAAK,8BACHV,EAAQe,EAAqBL,EAAO,EAAG,IAAK,KAC5C,MACF,IAAK,0CACHV,EAAQe,EAAqBL,EAAO,EAAG,IAAK,KAIhD,OAAOI,EAAaF,QAAQC,EAAkBb,EAChD,CD6DsByB,CAAYzB,EAFf,CAACG,EAAME,EAAQC,EAAQC,GAAUmB,KAAK,KAGrDnC,EAAUO,YAAcW,EAEpB9B,KAAKc,QAAQkC,iBAAmB3B,GAClCT,EAAUqC,aAAa,aAAc,CAACjD,KAAKc,QAAQkC,gBAAiBlB,GAAWiB,KAAK,MAKpFnC,EAAUqC,aAAa,OAAQ,SAE/BrC,EAAUQ,gBAAgB,cAC1BR,EAAUQ,gBAAgB,QAE9B,EASG8B,eAAeC,IAAI,kBACtBD,eAAeE,OAAO,gBAAiBxD","sources":["webpack://lange/./sections/price-element/price-element/index.ts","webpack://lange/../node_modules/@shopify/theme-currency/currency.js"],"sourcesContent":["import type { CustomElement } from '@integrabeauty/custom-elements';\nimport { formatMoney } from '@shopify/theme-currency';\nimport html from './index.html';\nimport styles from './index.scss';\n\n/**\n * Accepts a price in subunits and then renders it in the appropriate format.\n */\nclass PriceElement extends HTMLElement implements CustomElement {\n  public static get observedAttributes() {\n    return [\n      'data-aria-label-prefix',\n      'data-subunits',\n      'data-negative',\n      'data-currency-code',\n      'data-currency-symbol',\n      'data-show-code'\n    ];\n  }\n\n  declare readonly dataset: {\n    /**\n     * When set the \"aria-label\" of the component will be set to `ariaLabelPrefix price`\n     *\n     * This allows to handle sales prices in an accessible way. The strikethrough HTML element\n     * usually used to mark the original price vs sales price has very poor accessibility support\n     * across browsers. To remediate this we can replace a price set like `<s>$28</s> $20` with a\n     * `Original price: $28; Sales price: $20` using \"aria-label\"s on both price elements.\n     */\n    ariaLabelPrefix: string;\n\n    /**\n     * The ISO code of the currency. All uppercase.\n     *\n     * @example \"USD\"\n     */\n    currencyCode: string;\n\n    /**\n     * The symbol of the currency.\n     *\n     * @example \"$\"\n     */\n    currencySymbol: string;\n\n    /**\n     * To show/hide the value.\n     */\n    hide: string;\n\n    /**\n     * Boolean value representing this numerical value represents a discount and therefore should be\n     * preceded with \"-\" to visually indicate the value removed from the cart totals when applied.\n     */\n    negative: string;\n\n    /**\n     * If true will display the currency code even for USD. If false will not display the currency\n     * code regardless of the currency. The default (not set) is to show only the codes of\n     * currencies other than USD.\n     */\n    showCode: string;\n\n    /**\n     * The value to render in the subunit of the currency.\n     */\n    subunits: string;\n  };\n\n  public connectedCallback() {\n    this.initializeShadowRoot();\n\n    this.render();\n  }\n\n  public attributeChangedCallback(_name: string, oldValue: string, newValue: string) {\n    this.initializeShadowRoot();\n\n    if (this.isConnected && oldValue !== newValue) {\n      this.render();\n    }\n  }\n\n  private initializeShadowRoot() {\n    if (!this.shadowRoot) {\n      this.attachShadow({ mode: 'open' });\n      this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n    }\n  }\n\n  private render() {\n    const container = this.shadowRoot.querySelector('div');\n\n    // For cases where there is no attribute, or there is an attribute and it is an empty string, we\n    // do not hide the container, but we do ensure it has no text\n    if (!this.dataset.subunits || this.dataset.subunits.trim() === '' ||\n      this.dataset.subunits === 'undefined' || this.dataset.subunits === 'null' ||\n      !this.dataset.currencyCode || !this.dataset.currencySymbol) {\n      container.textContent = '';\n      container.removeAttribute('aria-label');\n      container.removeAttribute('role');\n      return;\n    }\n\n    const value = parseInt(this.dataset.subunits, 10);\n    if (value === 0) {\n      container.textContent = 'FREE';\n      return;\n    }\n\n    const hasDecimal = (value / 100) % 1 > 0;\n    const sign = this.dataset.negative === 'true' ? '-' : '';\n    const symbol = this.dataset.currencySymbol;\n\n    const amount = hasDecimal ? '{{ amount }}' : '{{ amount_no_decimals }}';\n\n    let currency = '';\n    // we only display the currency code if the `showCode` is explicitly set to true\n    if (this.dataset.showCode === 'true' ||\n      // or if `showCode` wasn't set and the currency is different than 'USD'\n      (this.dataset.showCode !== 'false' && this.dataset.currencyCode !== 'USD')) {\n      currency = ' ' + this.dataset.currencyCode;\n    }\n\n    const format = [sign, symbol, amount, currency].join('');\n\n    const formatted = formatMoney(value, format);\n    container.textContent = formatted;\n\n    if (this.dataset.ariaLabelPrefix && value) {\n      container.setAttribute('aria-label', [this.dataset.ariaLabelPrefix, formatted].join(' '));\n      // this is a workaround for a pretty complicated a11y issue with NVDA and WCAG standards while\n      // it may look strange it actually works well in VoiceOver and NVDA screen readers and is\n      // allowed by the accessibility standards, see:\n      // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/img_role#using_roleimg_to_confer_meaning_that_is_obscured_or_implied\n      container.setAttribute('role', 'img');\n    } else {\n      container.removeAttribute('aria-label');\n      container.removeAttribute('role');\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'price-element': PriceElement;\n  }\n}\n\nif (!customElements.get('price-element')) {\n  customElements.define('price-element', PriceElement);\n}\n","/**\n * Currency Helpers\n * -----------------------------------------------------------------------------\n * A collection of useful functions that help with currency formatting\n *\n * Current contents\n * - formatMoney - Takes an amount in cents and returns it as a formatted dollar value.\n *\n */\n\nconst moneyFormat = '${{amount}}';\n\n/**\n * Format money values based on your shop currency settings\n * @param  {Number|string} cents - value in cents or dollar amount e.g. 300 cents\n * or 3.00 dollars\n * @param  {String} format - shop money_format setting\n * @return {String} value - formatted value\n */\nexport function formatMoney(cents, format) {\n  if (typeof cents === 'string') {\n    cents = cents.replace('.', '');\n  }\n  let value = '';\n  const placeholderRegex = /\\{\\{\\s*(\\w+)\\s*\\}\\}/;\n  const formatString = format || moneyFormat;\n\n  function formatWithDelimiters(\n    number,\n    precision = 2,\n    thousands = ',',\n    decimal = '.'\n  ) {\n    if (isNaN(number) || number == null) {\n      return 0;\n    }\n\n    number = (number / 100.0).toFixed(precision);\n\n    const parts = number.split('.');\n    const dollarsAmount = parts[0].replace(\n      /(\\d)(?=(\\d\\d\\d)+(?!\\d))/g,\n      `$1${thousands}`\n    );\n    const centsAmount = parts[1] ? decimal + parts[1] : '';\n\n    return dollarsAmount + centsAmount;\n  }\n\n  switch (formatString.match(placeholderRegex)[1]) {\n    case 'amount':\n      value = formatWithDelimiters(cents, 2);\n      break;\n    case 'amount_no_decimals':\n      value = formatWithDelimiters(cents, 0);\n      break;\n    case 'amount_with_comma_separator':\n      value = formatWithDelimiters(cents, 2, '.', ',');\n      break;\n    case 'amount_no_decimals_with_comma_separator':\n      value = formatWithDelimiters(cents, 0, '.', ',');\n      break;\n  }\n\n  return formatString.replace(placeholderRegex, value);\n}\n"],"names":["PriceElement","HTMLElement","observedAttributes","connectedCallback","this","initializeShadowRoot","render","attributeChangedCallback","_name","oldValue","newValue","isConnected","shadowRoot","attachShadow","mode","innerHTML","container","querySelector","dataset","subunits","trim","currencyCode","currencySymbol","textContent","removeAttribute","value","parseInt","hasDecimal","sign","negative","symbol","amount","currency","showCode","formatted","cents","format","replace","placeholderRegex","formatString","formatWithDelimiters","number","precision","thousands","decimal","isNaN","parts","toFixed","split","match","formatMoney","join","ariaLabelPrefix","setAttribute","customElements","get","define"],"sourceRoot":""}