UNPKG

@postnord/web-components

Version:
217 lines (209 loc) 7.05 kB
/*! * Built with Stencil * By PostNord. */ 'use strict'; var index = require('./index-CfUQZtlH.js'); const byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 0x100).toString(16).slice(1)); } function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } let getRandomValues; const rnds8 = new Uint8Array(16); function rng() { if (!getRandomValues) { if (typeof crypto === 'undefined' || !crypto.getRandomValues) { throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); } getRandomValues = crypto.getRandomValues.bind(crypto); } return getRandomValues(rnds8); } const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); var native = { randomUUID }; function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { throw new Error('Random bytes length must be >= 16'); } rnds[6] = (rnds[6] & 0x0f) | 0x40; rnds[8] = (rnds[8] & 0x3f) | 0x80; return unsafeStringify(rnds); } function v4(options, buf, offset) { if (native.randomUUID && true && true) { return native.randomUUID(); } return _v4(options); } const SE = 'SE'; const DK = 'DK'; const FI = 'FI'; const NO = 'NO'; const sv = 'sv'; const en = 'en'; const da = 'da'; const fi = 'fi'; const no = 'no'; const markets = [SE, DK, FI, NO]; const languages = [sv, en, da, fi, no]; const marketMap = { SE: [sv, en], DK: [da, en], FI: [fi, sv, en], NO: [no, en], }; const humanReadableFileSize = { KB: 1024, MB: 1024 * 1024, GB: 1024 * 1024, TB: 1024 * 1024 * 1024, }; const getBytesFromHumanReadableFileSize = function (sizeString) { const fileSizeChecker = /(\d+\.?\d*)\s?([a-zA-Z]{2})?$/; if (fileSizeChecker.test(sizeString)) { const matches = sizeString.match(fileSizeChecker); const unit = (matches[2] || '').toLocaleUpperCase(); const size = parseInt(matches[1]); if (unit && humanReadableFileSize[unit]) { const baseSize = humanReadableFileSize[unit]; return size * baseSize; } return size; } return 0; }; function isSmallScreen() { return window.innerWidth / 16 < 55; } function reduceMotion() { const { matches } = window.matchMedia('(prefers-reduced-motion: reduce)'); return matches; } const uuidv4 = () => v4(); function getTopbarHeight() { return document?.querySelector('pn-topbar')?.offsetHeight || 0; } function getMenuHeight() { return isSmallScreen() ? document?.querySelector('pn-side-menu')?.offsetHeight || 0 : 0; } function getMenuWidth() { return isSmallScreen() ? 0 : document?.querySelector('pn-side-menu')?.offsetWidth || 0; } function getTotalHeightOffset() { const totalOffset = getTopbarHeight() + getMenuHeight(); return totalOffset > window.scrollY ? totalOffset - window.scrollY : 0; } /** * @param {HTMLElement} host Use the `this.hostElement` property. * * @description The `awaitTopbar` function can be used to wait for the topbar to be available. * * The function will also setup listeners for any market/language changes from the topbar and updates the host element with the `setAttribute` function. * * Remember to use a Stencil `@Prop` named `market` and/or `language` to take advantage of the auto update feature. * * @returns The pnTopbar object. */ async function awaitTopbar(host) { const topbar = () => window.pnTopbar; function finishSetup(fallBack) { const data = fallBack || topbar(); host.market = data.market; host.language = data.language; if (data.hasLoaded) { topbar().onChangeMarket = (market) => (host.market = market); topbar().onChangeLanguage = (language) => (host.language = language); } return data; } return await new Promise(resolve => { // If the pntopbar script does not exist. Resolve with default values. if (!document.querySelector('pn-topbar')) return resolve(finishSetup({ hasLoaded: false, market: host.market || SE, language: host.language || en })); if (topbar()?.hasLoaded) return resolve(finishSetup()); window.addEventListener('topbarLoaded', () => resolve(finishSetup())); }); } /** * @description Apply the Ripple effect quick and easy. * * @example * ```css * // CSS * pn-component-name { `@include pn-ripple($blue700) } * ``` * * ```js * // tsx * onClick((e) => ripple(e, this.hostElement, '.pn-ripple-container')) * ``` * @param event The MouseEvent from a onClick handler. * @param host The hostElement of the component (root element). * @param rippleClass Append the ripple event to this selector instead of the host element. */ const ripple = (event, host, rippleClass) => { if (reduceMotion()) return; const { left, top, width, height } = host.getBoundingClientRect(); const { clientX = 0, clientY = 0 } = event || {}; const elSize = width > height ? width : height; const element = document.createElement(index.transformTag('div')); element.classList.add('pn-ripple'); element.style.height = `${elSize * 2}px`; element.style.width = `${elSize * 2}px`; element.style.left = clientX > 0 ? `${clientX - left}px` : `50%`; element.style.top = clientY > 0 ? `${clientY - top}px` : `50%`; if (rippleClass) host.querySelector(rippleClass).appendChild(element); else host.appendChild(element); setTimeout(() => element.remove(), 400); }; exports.setTagTransformer = index.setTagTransformer; exports.DK = DK; exports.FI = FI; exports.NO = NO; exports.SE = SE; exports.awaitTopbar = awaitTopbar; exports.da = da; exports.en = en; exports.fi = fi; exports.getBytesFromHumanReadableFileSize = getBytesFromHumanReadableFileSize; exports.getMenuHeight = getMenuHeight; exports.getMenuWidth = getMenuWidth; exports.getTopbarHeight = getTopbarHeight; exports.getTotalHeightOffset = getTotalHeightOffset; exports.isSmallScreen = isSmallScreen; exports.languages = languages; exports.marketMap = marketMap; exports.markets = markets; exports.no = no; exports.reduceMotion = reduceMotion; exports.ripple = ripple; exports.sv = sv; exports.uuidv4 = uuidv4;