@terrahq/helpers

0.0.49 • Public • Published

Helpers by Terra

These functions play a crucial role in project development, establishing identity, streamlining processes, and expediting progress. Whether it's preloading assets, integrating reCAPTCHA, or incorporating HubSpot interactions, these simple functions facilitate rapid development, contributing to the sustainable growth of our projects.

npm i @terrahq/helpers

Preload


Images

Under the hood it uses ImagesLoaded, This is an async await operation

import { preloadImages } from "@terrahq/helpers/preloadImages";
await preloadImages("img");

Videos

Under the hood it uses canplaythrough, This is an async await operation

import { preloadVideos } from "@terrahq/helpers/preloadVideos";
await preloadVideos({
    selector: document.querySelectorAll(".js--video"),
    maxTime: 300,
});

Fonts

Under the hood it uses WebFontLoad , This is an async await operation

import { preloadFonts } from "@terrahq/helpers/preloadFonts";

For Google fonts

await preloadFonts({
    provider: "google",
    families: ["DMSans", "Domine"], // Replace with your desired Google font families
});

For custom fonts

await preloadFonts({
    provider: "custom",
    families: ["MyCustomFont"], // Replace with your custom font family names
    urls: ["https://example.com/path/to/mycustomfont.css"], // Replace with the URLs to your custom font CSS files
});

Lottie

Under the hood it uses lottie-web , This is an async await operation

import { preloadLotties } from "@terrahq/helpers/preloadLotties";

# Parameter Type Description
1 payload.onScroll Boolen It defines if the 'lottie-web' should be import on init or on window scroll.
preloadLotties();

preloadLotties({ onScroll: true });

It is understood that each lottie must be formed in the following way

<div class="js--lottie-data" data-src="filename.json" data-autoplay="true" data-name="myLottie"></div>

You can play/pause/etc via javascript, as all loties will live under window.windowLotties['data-name']

window.windowLotties["myLottie"].play();
window.windowLotties["myLottie"].pause();
window.windowLotties["myLottie"].stop();

Vue

This is an async await operation

import { preloadVue } from "@terrahq/helpers/preloadVue";
await preloadVue({
    element: document.querySelector(".js--vue"),
});

In the context of Vue.js development, it is recommended to initialize the loading state within the mounted lifecycle hook of a Vue page by setting window['vueLoaded'] to false. As data is successfully loaded, often achieved through tools like Axios, the loading state is then gracefully transitioned to true by updating the value of window['vueLoaded']. This practice elegantly manages the loading dynamics of the Vue page in harmony with the asynchronous data retrieval process.

MyVueApp.vue
mounted() {
    window['vueLoaded'] = false
},
asyncData(){
    await axios.get("XXXX")
    window['vueLoaded'] = true
}

It is customary for each page to include the tag js--resources-vue. This serves as a visual cue, indicating that the enclosed Vue code should be scrutinized to ensure the proper loading and functioning of Vue components.

Mypage.astro
<div class="js--vue">
    <MyVueApp></MyVueApp>
</div>

Hubspot

Helper to submit directly to Hubspot.

  • This endpoint has a rate limit of 50 requests per 10 seconds.
  • When using this endpoint to integrate custom forms with HubSpot, keep in mind that the available endpoints do not log any API calls. Users will need to store their own logs.
  • In addition to accepting server-side HTTP requests, this endpoint will accept cross-origin AJAX (CORS) requests, allowing you to submit form data directly to HubSpot client-side using JavaScript.
  • This endpoint does not support reCAPTCHA. If reCAPTCHA has been enabled on the form, submissions will not be accepted.
import { submitToHubspot } from "@terrahq/helpers/hubspot";
// option 1
async function handleFormSubmit(formInputs) {
    const { message, success, statusCode } = await useHubSpot(portalId.value, formId.value, formInputs.concat(stepsResults.value));
}
// option 2
const handleFormSubmit = async (formInputs) => {
    const { message, success, statusCode } = await useHubSpot(portalId.value, formId.value, formInputs.concat(stepsResults.value));
};
  • Message (String): Returns a message indicating the status of the submission. If successful, it will be "Thanks for submitting." If there is an error, the message will contain details about the API error.

  • Success (Boolean): Returns true if the submission is successful, and false if there is an error.

  • StatusCode (Integer): Returns the HTTP status code indicating the result of the API request. A status code of 200 indicates success, while other codes such as 400, 300, or 500 correspond to different API errors.

Recaptcha

Helper to add recaptcha v3 to our custom forms. It has several functions. 1 st Asynchronously loads the reCAPTCHA script from Google with the specified API key.

import { GET_RECAPTCHA_SCRIPT_FROM_GOOGLE } from "@terrahq/helpers/recaptcha";
var publicKey = "XXXXXXX";
var loadRecaptchaScript = await GET_RECAPTCHA_SCRIPT_FROM_GOOGLE({
    API_KEY: publicKey,
});

2nd Asynchronously retrieves a reCAPTCHA client token by executing the reCAPTCHA challenge.

import { GET_RECAPTCHA_CLIENT_TOKEN } from "@terrahq/helpers/recaptcha";
var google_access_token = await GET_RECAPTCHA_CLIENT_TOKEN({
    API_KEY: publicKey,
    action: "submit",
});

3rd Validates a Google reCAPTCHA token on the server-side using either PHP or Node.js.

import { VALIDATE_RECAPTCHA_SERVER } from "@terrahq/helpers/recaptcha";
var response_from_server = await VALIDATE_RECAPTCHA_SERVER({
    type: "node",
    postUrl: "yoursite.com/api/validate_recaptcha",
    action: "recaptcha_validate",
    google_access_token: google_access_token,
});
Note : you could use these reference as a draft, this is not production ready, samples for Node or PHP

Dig Element

Helper function designed to inspect a specified HTML element for mutations in its styles, classes, data attributes, or the structure of its children.

The function returns a Promise resolving in true or rejecting with error message.

import { digElement } from "@terrahq/helpers/digElement";

4 different ways of implementing it:


# Parameter Type Description
1 element HTMLElement The element to check
2 search.type String The type of search, in this case 'style'
3 search.lookFor Array Array of styles properties to look for
4 intervalFrequency Number Interval frequency in seconds
5 timer Number The duration in seconds after which the interval will be finished
6 callback Function A callback function to execute once the promise is resolved
Promise.all(
    elements.map(async (element) => {
        await digElement({
            element: element,
            search: {
                type: "style",
                lookFor: ["max-height"],
            },
            intervalFrequency: 1500,
            timer: 5000,
            callback: () => console.log("COMPLETED!"),
        });
    })
)
    .then(() => {
        console.log("READY");
    })
    .catch((error) => console.log(error.message));

# Parameter Type Description
1 element HTMLElement The element to check
2 search.type String The type of search, in this case 'class'
3 search.lookFor Array Array of classes to look for
4 intervalFrequency Number Interval frequency in seconds
5 timer Number The duration in seconds after which the interval will be finished
6 callback Function A callback function to execute once the promise is resolved
Promise.all(
    elements.map(async (element) => {
        await digElement({
            element: element,
            search: {
                type: "class",
                lookFor: ["test-class"],
            },
            intervalFrequency: 1500,
            timer: 5000,
            callback: () => console.log("COMPLETED!"),
        });
    })
)
    .then(() => {
        console.log("READY");
    })
    .catch((error) => console.log(error.message));

Here's the information you provided in table format:

# Parameter Type Description
1 element HTMLElement The element to check
2 search.type String The type of search, in this case 'class'
3 search.attribute String The data attribute to check
4 search.lookFor Array Array of possible values for the data attribute
5 intervalFrequency Number Interval frequency in seconds
6 timer Number The duration in seconds after which the interval will be finished
7 callback Function A callback function to execute once the promise is resolved
Promise.all(
    elements.map(async (element) => {
        await digElement({
            element: element,
            search: {
                type: "class",
                attribute: "data-test",
                lookFor: ["value"],
            },
            intervalFrequency: 1500,
            timer: 5000,
            callback: () => console.log("COMPLETED!"),
        });
    })
)
    .then(() => {
        console.log("READY");
    })
    .catch((error) => console.log(error.message));

Here's the information in table format:

# Parameter Type Description
1 element HTMLElement The element to check
2 search.type String The type of search, in this case 'hasChildren'
3 intervalFrequency Number Interval frequency in seconds
4 timer Number The duration in seconds after which the interval will be finished
5 callback Function A callback function to execute once the promise is resolved
Promise.all(
    elements.map(async (element) => {
        await digElement({
            element: element,
            search: {
                type: "hasChildren",
            },
            intervalFrequency: 1500,
            timer: 5000,
            callback: () => console.log("COMPLETED!"),
        });
    })
)
    .then(() => {
        console.log("READY");
    })
    .catch((error) => console.log(error.message));

Manipulate Scroll

Helper function designed to enable/disable scrolling in your website.

import { manipulateScroll } from "@terrahq/helpers/manipulateScroll";
manipulateScroll("block");
manipulateScroll("scroll");

Google Scripts Detection

This utility function, hasGoogleScripts, is designed to asynchronously check for the presence of Google Analytics and Google Tag Manager scripts on a webpage. It returns a promise that resolves with a boolean value indicating whether the specified Google scripts are detected within a given timeframe.

import { hasGoogleScripts } from "@terrahq/helpers/hasGoogleScripts";

Function Signature

async hasGoogleScripts(options = { detect: ['analytics', 'gtm'], maxTime: 5000 })

  • options: Optional configuration object.
    • detect: Array specifying which Google scripts to detect. Default is ['analytics', 'gtm'].
    • maxTime: Maximum time in milliseconds to wait for script detection. Default is 5000.

Usage

The function can be used with await inside an async function, or with .then() for promise handling. Here's an example using .then() for handling the detection result:

await hasGoogleScripts().then((detected) => {
    if (detected) {
        // Code to execute if the specified Google scripts are detected, e.g., load GTM
        this.loadGTM();
    } else {
        // Code to execute if the scripts are not detected within the specified time
        console.log("Google Scripts not detected");
    }
});

Accessible Tab Nav

It handles focus on 'skip to main content' and/or anchor to section enter keydown.

import { accessibleTabNav } from "@terrahq/helpers/accessibleTabNav";
# Parameter Type Description
1 focusableElements Array It specifies which types of elements will be included as focusables within the focus target

Trigger elements must include:

  • class: 'js--trigger-focus'

  • data-focus-target='${focusTargetID}'


Target elements must include:

  • id: '${focusTargetID}'

HTML - Example 1:

//header.php

<main id="swup">
    <button class="js--trigger-focus" data-focus-target="main-content" tabindex="1">Skip to Main Content</button>
    <div id="main-content">...</div>
    ...
</main>

HTML - Example 2:

//card-a.php

<a href="test" class="c--card-a js--trigger-focus" data-focus-target="3">
    <div class="c--card-a__ft-items">
        <h2 class="c--card-a__ft-items__title">Title</h2>
        <p class="c--card-a__ft-items__subtitle">Subtitle</p>
        <div class="c--card-a__ft-items__btn">Link</div>
    </div>
</a>

//random-module.php

<span id="3" class="js--invisible-span" style="position: relative; display:block;"></span>
<section class="">
    <div class="f--container">Content</div>
</section>

JavaScript:

accessibleTabNav();

accessibleTabNav({
    focusableElements: ["a", "button"],
});

scrollYis

This function checks if the current vertical scroll position (window.scrollY) of the window is equal to a specified distance. It is typically used in scenarios where you need to verify if the window has been scrolled to a particular vertical position.

import { scrollYis } from "@terrahq/helpers/scrollYis";

if (scrollYis({ distance: 30 })) {
    console.log("The scroll position is exactly 30 pixels or more from the top.");
} else {
    console.log("The scroll position is below 30 pixels.");
}

hasQueryParameter

This function checks if a specific query parameter is present in the URL of the current window location and retrieves its value if it exists. It is particularly useful for accessing and manipulating URL parameters dynamically in client-side applications.

import { hasQueryParameter } from "@terrahq/helpers/hasQueryParameter";

let result = hasQueryParameter({ name: 'user' });
if (result) {
    console.log(`Query parameter 'user' has the value: ${result}`);
} else {
    console.log("Query parameter 'user' is not present in the URL.");
}

Readme

Keywords

none

Package Sidebar

Install

npm i @terrahq/helpers

Weekly Downloads

10

Version

0.0.49

License

none

Unpacked Size

1.61 MB

Total Files

107

Last publish

Collaborators

  • elisabetperez
  • alberto.terrahq
  • nereaterrahq
  • andresclua