@mezereon/ui-shopify
Version:
Shopify UI components for Mezereon Xperience
247 lines (213 loc) • 5.65 kB
JavaScript
export function isNumeric(value) {
return !isNaN(parseFloat(value)) && isFinite(value)
}
export function isUndefined(value) {
return typeof value === 'undefined'
}
export function isArray(value) {
return Array.isArray(value)
}
export function isObject(value) {
return value instanceof Object && !isArray(value)
}
export function isEmpty(value) {
const type = typeof val
if ((value !== null && type === 'object') || type === 'function') {
const properties = Object.keys(value)
if (properties.length === 0 || properties.size === 0) {
return true
}
}
return !value
}
export function stripHtml(value) {
if (!value) {
return ''
}
return value.replace(/(<([^>]+)>)/gi, '')
}
export function debounced(delay, fn) {
let timerId
return function (...args) {
if (timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(() => {
fn(...args)
timerId = null
}, delay)
}
}
export function convertCurrency(selector) {
const DoublyGlobalCurrency = window.DoublyGlobalCurrency
if (DoublyGlobalCurrency) {
DoublyGlobalCurrency.convertAll(
DoublyGlobalCurrency.currentCurrency,
selector
)
}
}
export function isAbsoluteUrl(url) {
const r = new RegExp('^(?:[a-z]+:)?//', 'i')
return r.test(url)
}
export function pathCombine(...args) {
const combined = args.reduce((acc, part) => {
// Trim slashes from the beginning and end of each part
const trimmedPart = part.replace(/^\/+|\/+$/g, '')
// If the accumulator is empty (i.e., at the start), return just the trimmed part
if (!acc) {
return trimmedPart
}
// Otherwise, combine the accumulator and trimmed part with a single slash
return `${acc}/${trimmedPart}`
}, '')
if (!isAbsoluteUrl(combined)) {
return `/${combined}`
}
return combined
}
export function toRelativeUrl(absoluteUrl) {
try {
let url = new URL(absoluteUrl)
return url.pathname + url.search + url.hash
} catch (error) {
return absoluteUrl
}
}
/**
* https://github.com/NxtChg/pieces/tree/master/js/vue/vue-css
*/
export function setCustomCSS(tagName, style) {
if (!style) {
return
}
function fail(msg) {
throw new Error(
'css parsing error: ' + msg + ' at "' + css.slice(pos, pos + 60) + '"...'
)
}
const css = style.replace(/<\/?style>/gi, '')
let rule = ''
let pos = 0
let level = 0
let s = document.getElementById(tagName)
if (!s) {
s = document.createElement('style')
s.type = 'text/css'
s.id = 'tagName'
document.getElementsByTagName('head')[0].appendChild(s)
}
function readUntil(delims) {
const org = pos
let c
while ((c = css[pos++])) {
if (c === "'" || c === '"') {
const p = css.indexOf(c, pos)
if (p !== -1) pos = p + 1
else fail('unterminated string')
continue
}
if (level === 0 && delims.includes(c)) break
if (c === '{') {
level++
}
if (c === '}') {
level--
if (level < 0) fail('extra }')
}
}
return css.slice(org, pos - 1)
}
function addSel(s) {
s = s.replace(/^\s+|\s+$/g, '')
rule += s
}
while (pos < css.length) {
const n = readUntil(',;{')
addSel(n + (css[pos - 1] || ''))
switch (css[pos - 1]) {
case ',':
continue
case '{':
rule += readUntil('}') + '}'
break
}
if (rule !== '') {
s.sheet.insertRule(rule, s.sheet.cssRules.length)
rule = ''
}
}
}
export function getValueFromComplex(value) {
if (isEmpty(value)) {
return ''
}
const match = value.match(/(.*)=>(.*)/i)
if (match === null) {
return value
}
return match[2]
}
export function getKeyFromComplex(value) {
if (isEmpty(value)) {
return ''
}
let match = value.match(/(.*),(.*)=>(.*)/i)
if (match === null) {
match = value.match(/(.*)=>(.*)/i)
if (match === null) {
return value
}
return match[1]
}
return match[1]
}
export function round(value, precision) {
var multiplier = Math.pow(10, precision || 0)
return Math.round(value * multiplier) / multiplier
}
/**
* Based on https://github.com/Shopify/theme-scripts/blob/master/packages/theme-currency
*/
export function formatMoney(amount) {
var value = ''
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/
var formatString = window.mz?.moneyFormat || '${{amount}}'
function formatWithDelimiters(number, precision, thousands, decimal) {
thousands = thousands || ','
decimal = decimal || '.'
if (isNaN(number) || number === null) {
return 0
}
number = (number / 1.0).toFixed(precision)
var parts = number.split('.')
var dollarsAmount = parts[0].replace(
/(\d)(?=(\d\d\d)+(?!\d))/g,
'$1' + thousands
)
var centsAmount = parts[1] ? decimal + parts[1] : ''
return dollarsAmount + centsAmount
}
switch (formatString.match(placeholderRegex)[1]) {
case 'amount':
value = formatWithDelimiters(amount, 2)
break
case 'amount_no_decimals':
value = formatWithDelimiters(amount, 0)
break
case 'amount_with_comma_separator':
value = formatWithDelimiters(amount, 2, '.', ',')
break
case 'amount_no_decimals_with_comma_separator':
value = formatWithDelimiters(amount, 0, '.', ',')
break
case 'amount_no_decimals_with_space_separator':
value = formatWithDelimiters(amount, 0, ' ')
break
case 'amount_with_apostrophe_separator':
value = formatWithDelimiters(amount, 2, "'")
break
}
return formatString.replace(placeholderRegex, value)
}