From 682cfae2e892367525ee325dbf9fb28a65ed2979 Mon Sep 17 00:00:00 2001 From: Alex Iglesias Date: Thu, 2 Jun 2022 15:28:39 +0200 Subject: [PATCH] Bundled all original jsDoc comments in the production build --- dist/animations/fade.d.ts | 11 ++++ dist/animations/fade.js | 11 ++++ dist/components/CopyJSONButton.d.ts | 27 ++++++++++ dist/components/CopyJSONButton.js | 29 ++++++++++ dist/components/Debug.js | 1 + dist/components/DisplayController.d.ts | 32 +++++++++++ dist/components/DisplayController.js | 17 ++++++ dist/components/Interaction.d.ts | 28 ++++++++++ dist/components/Interaction.js | 20 +++++++ dist/components/WritableStore.d.ts | 22 ++++++++ dist/components/WritableStore.js | 23 ++++++++ dist/helpers/clearFormField.d.ts | 7 +++ dist/helpers/clearFormField.js | 12 +++++ dist/helpers/cloneNode.d.ts | 4 ++ dist/helpers/cloneNode.js | 4 ++ dist/helpers/extractCommaSeparatedValues.d.ts | 8 +++ dist/helpers/extractNumberSuffix.d.ts | 7 +++ dist/helpers/extractNumberSuffix.js | 7 +++ dist/helpers/findTextNode.d.ts | 4 ++ dist/helpers/findTextNode.js | 4 ++ dist/helpers/getAllParents.d.ts | 4 ++ dist/helpers/getAllParents.js | 4 ++ dist/helpers/getDistanceFromTop.d.ts | 5 ++ dist/helpers/getDistanceFromTop.js | 6 +++ dist/helpers/getFormFieldValue.d.ts | 4 ++ dist/helpers/getFormFieldValue.js | 7 +++ dist/helpers/getHiddenParent.d.ts | 6 +++ dist/helpers/getHiddenParent.js | 6 +++ dist/helpers/getObjectEntries.d.ts | 4 ++ dist/helpers/getObjectEntries.js | 5 ++ dist/helpers/getObjectKeys.d.ts | 5 ++ dist/helpers/getObjectKeys.js | 6 +++ dist/helpers/isScrollable.d.ts | 5 ++ dist/helpers/isScrollable.js | 5 ++ dist/helpers/isVisible.d.ts | 4 ++ dist/helpers/isVisible.js | 5 ++ dist/helpers/queryElement.d.ts | 7 +++ dist/helpers/queryElement.js | 7 +++ dist/helpers/removeChildElements.d.ts | 7 ++- dist/helpers/removeChildElements.js | 5 ++ dist/helpers/removeSpaces.d.ts | 5 ++ dist/helpers/removeSpaces.js | 5 ++ dist/helpers/removeTrailingSlash.d.ts | 15 ++++++ dist/helpers/removeTrailingSlash.js | 15 ++++++ dist/helpers/sameValues.d.ts | 5 ++ dist/helpers/sameValues.js | 6 +++ dist/helpers/selectInputElement.d.ts | 9 ++++ dist/helpers/selectInputElement.js | 11 ++++ dist/helpers/setFormFieldValue.d.ts | 6 +++ dist/helpers/setFormFieldValue.js | 7 +++ dist/helpers/simulateEvent.d.ts | 6 +++ dist/helpers/simulateEvent.js | 6 +++ dist/helpers/throwError.d.ts | 5 ++ dist/helpers/throwError.js | 5 ++ dist/helpers/wait.d.ts | 4 ++ dist/helpers/wait.js | 4 ++ dist/type-guards/isFormField.d.ts | 4 ++ dist/type-guards/isFormField.js | 5 ++ dist/type-guards/isKeyOf.d.ts | 6 +++ dist/type-guards/isKeyOf.js | 6 +++ dist/type-guards/isNotEmpty.d.ts | 12 +++++ dist/type-guards/isNotEmpty.js | 12 +++++ dist/types/Entry.d.ts | 3 ++ dist/types/Instance.d.ts | 3 ++ dist/types/MapEntries.d.ts | 9 ++++ dist/types/PartialExcept.d.ts | 3 ++ dist/types/PickPartial.d.ts | 3 ++ dist/types/PickRequired.d.ts | 3 ++ dist/types/RequiredExcept.d.ts | 3 ++ dist/types/UnionToIntersection.d.ts | 3 ++ dist/types/apis/Greenhouse.d.ts | 54 +++++++++++++++++++ dist/types/apis/Greenhouse.js | 1 + dist/webflow/Webflow.d.ts | 9 ++++ dist/webflow/WebflowElements.d.ts | 18 +++++++ dist/webflow/breakpoints.d.ts | 6 +++ dist/webflow/breakpoints.js | 3 ++ dist/webflow/closeDropdown.d.ts | 5 ++ dist/webflow/closeDropdown.js | 5 ++ dist/webflow/getCollectionElements.d.ts | 8 +++ dist/webflow/getCollectionListWrappers.d.ts | 6 +++ dist/webflow/getCollectionListWrappers.js | 7 +++ dist/webflow/getCurrentBreakpoint.d.ts | 5 ++ dist/webflow/getCurrentBreakpoint.js | 5 ++ dist/webflow/getPublishDate.d.ts | 4 ++ dist/webflow/getPublishDate.js | 4 ++ dist/webflow/getSiteId.d.ts | 3 ++ dist/webflow/getSiteId.js | 3 ++ dist/webflow/restartWebflow.d.ts | 9 +++- dist/webflow/restartWebflow.js | 13 +++++ package.json | 2 +- tsconfig.json | 2 +- 91 files changed, 742 insertions(+), 4 deletions(-) diff --git a/dist/animations/fade.d.ts b/dist/animations/fade.d.ts index 388066c..5e828a2 100644 --- a/dist/animations/fade.d.ts +++ b/dist/animations/fade.d.ts @@ -1,2 +1,13 @@ +/** + * Fade in an element + * @param element + * @param display Display property, flex by default + * @returns An awaitable promise + */ export declare const fadeIn: (element: HTMLElement, display?: string) => Promise; +/** + * Fade out an element + * @param element + * @returns An awaitable promise + */ export declare const fadeOut: (element: HTMLElement) => Promise; diff --git a/dist/animations/fade.js b/dist/animations/fade.js index 813b1d4..1492ffb 100644 --- a/dist/animations/fade.js +++ b/dist/animations/fade.js @@ -1,3 +1,9 @@ +/** + * Fade in an element + * @param element + * @param display Display property, flex by default + * @returns An awaitable promise + */ export const fadeIn = (element, display = 'flex') => { return new Promise((resolve) => { element.style.opacity = '0'; @@ -14,6 +20,11 @@ export const fadeIn = (element, display = 'flex') => { })(); }); }; +/** + * Fade out an element + * @param element + * @returns An awaitable promise + */ export const fadeOut = (element) => { return new Promise((resolve) => { element.style.opacity = '1'; diff --git a/dist/components/CopyJSONButton.d.ts b/dist/components/CopyJSONButton.d.ts index aee906f..fb4cc5d 100644 --- a/dist/components/CopyJSONButton.d.ts +++ b/dist/components/CopyJSONButton.d.ts @@ -17,11 +17,38 @@ export declare class CopyJSONButton { notificationDuration?: number; successCSSClass?: string; }); + /** + * Inits the component. + */ private init; + /** + * Creates a hidden button that will serve as the copy trigger. + * @returns The new button element. + */ private createHiddenTrigger; + /** + * Handles click events: triggers a copy command on the element. + */ private handleClick; + /** + * Handles the copy event, transfers the JSON data to the user's clipboard. + * @param e + */ private handleCopy; + /** + * Triggers a `success`/`error` notification on the button. + * If the `successCSSClass` is specific, it adds/removes on the button. + * @param state `success` or `error` + */ private triggerNotification; + /** + * Updates the JSON data to be copied. + * @param newCopyData + */ updateCopyData(newCopyData: Record): void; + /** + * Updates the button's text content. + * @param newText The new text to be displayed. + */ updateTextContent(newText: string): void; } diff --git a/dist/components/CopyJSONButton.js b/dist/components/CopyJSONButton.js index 7067fc8..5164c7f 100644 --- a/dist/components/CopyJSONButton.js +++ b/dist/components/CopyJSONButton.js @@ -26,11 +26,18 @@ export class CopyJSONButton { this.hiddenTrigger = this.createHiddenTrigger(); this.init(); } + /** + * Inits the component. + */ init() { const { element, hiddenTrigger } = this; element.addEventListener('click', () => this.handleClick()); hiddenTrigger.addEventListener('copy', (e) => this.handleCopy(e)); } + /** + * Creates a hidden button that will serve as the copy trigger. + * @returns The new button element. + */ createHiddenTrigger() { const { element } = this; const button = document.createElement('button'); @@ -48,20 +55,34 @@ export class CopyJSONButton { (element.parentElement || document.body).appendChild(button); return button; } + /** + * Handles click events: triggers a copy command on the element. + */ handleClick() { this.hiddenTrigger.focus(); document.execCommand('copy'); } + /** + * Handles the copy event, transfers the JSON data to the user's clipboard. + * @param e + */ handleCopy(e) { try { + // Copy starter form JSON to clipboard e.clipboardData?.setData('application/json', JSON.stringify(this.copyData).trim()); e.preventDefault(); + // Trigger notification this.triggerNotification('success'); } catch { this.triggerNotification('error'); } } + /** + * Triggers a `success`/`error` notification on the button. + * If the `successCSSClass` is specific, it adds/removes on the button. + * @param state `success` or `error` + */ triggerNotification(state) { const { notificationActive, notificationDuration, originalText, element, successCSSClass, successText, errorText } = this; if (notificationActive) @@ -77,9 +98,17 @@ export class CopyJSONButton { this.notificationActive = false; }, notificationDuration); } + /** + * Updates the JSON data to be copied. + * @param newCopyData + */ updateCopyData(newCopyData) { this.copyData = newCopyData; } + /** + * Updates the button's text content. + * @param newText The new text to be displayed. + */ updateTextContent(newText) { this.textNode.textContent = newText; this.originalText = newText; diff --git a/dist/components/Debug.js b/dist/components/Debug.js index 477326c..c0081ba 100644 --- a/dist/components/Debug.js +++ b/dist/components/Debug.js @@ -1,3 +1,4 @@ +// Constants const alertTypes = ['info', 'error']; export class Debug { static alertsActivated = false; diff --git a/dist/components/DisplayController.d.ts b/dist/components/DisplayController.d.ts index e4a85d5..591290a 100644 --- a/dist/components/DisplayController.d.ts +++ b/dist/components/DisplayController.d.ts @@ -1,11 +1,32 @@ import type { InteractionParams } from './Interaction'; export interface DisplayControllerParams { + /** + * The main element. Accepts both an HTMLElement or a string selector. + */ element: HTMLElement | string; + /** + * If the display must be controlled thorugh a Webflow interaction. + */ interaction?: InteractionParams; + /** + * The display property of the element when displayed. + * Not applicable when interaction parameters ara passed to the instance, as it's assumed that the Webflow interaction will set the display property. + * Defaults to `block`. + */ displayProperty?: typeof DisplayController['displayProperties'][number]; + /** + * If set to true, the element will be straitgh showed / hidden without any transition. + */ noTransition?: boolean; + /** + * If set to true, the element will be set to `display: none`. + */ startsHidden?: boolean; } +/** + * Controls showing/hiding an element. + * Works with Webflow interactions, built-in fade animations or no animations at all. + */ export declare class DisplayController { private readonly interaction; private readonly noTransition; @@ -14,7 +35,18 @@ export declare class DisplayController { readonly element: HTMLElement; static readonly displayProperties: readonly ["block", "flex", "grid", "inline-block", "inline"]; constructor({ element, interaction, displayProperty, noTransition, startsHidden }: DisplayControllerParams); + /** + * @returns If the element is visible + */ isVisible: () => boolean; + /** + * Displays the element + * @returns An awaitable promise + */ show(): Promise; + /** + * Hides the element + * @returns An awaitable promise + */ hide(): Promise; } diff --git a/dist/components/DisplayController.js b/dist/components/DisplayController.js index 97b8cef..1ba4aed 100644 --- a/dist/components/DisplayController.js +++ b/dist/components/DisplayController.js @@ -3,6 +3,10 @@ import { fadeIn, fadeOut } from '../animations/fade'; import { isVisible } from '../helpers/isVisible'; import { queryElement } from '../helpers'; import { Debug } from '.'; +/** + * Controls showing/hiding an element. + * Works with Webflow interactions, built-in fade animations or no animations at all. + */ export class DisplayController { interaction; noTransition; @@ -11,6 +15,7 @@ export class DisplayController { element; static displayProperties = ['block', 'flex', 'grid', 'inline-block', 'inline']; constructor({ element, interaction, displayProperty, noTransition, startsHidden }) { + // Store properties this.element = typeof element === 'string' ? queryElement(element, HTMLElement) || @@ -18,6 +23,7 @@ export class DisplayController { : element; this.noTransition = noTransition; this.displayProperty = displayProperty || 'block'; + // Visibility check if (startsHidden) { this.element.style.display = 'none'; this.visible = false; @@ -29,7 +35,14 @@ export class DisplayController { this.interaction = new Interaction({ element, duration }); } } + /** + * @returns If the element is visible + */ isVisible = () => this.visible; + /** + * Displays the element + * @returns An awaitable promise + */ async show() { if (this.visible) return; @@ -41,6 +54,10 @@ export class DisplayController { await fadeIn(this.element, this.displayProperty); this.visible = true; } + /** + * Hides the element + * @returns An awaitable promise + */ async hide() { if (!this.visible) return; diff --git a/dist/components/Interaction.d.ts b/dist/components/Interaction.d.ts index a0f0833..ad95cc8 100644 --- a/dist/components/Interaction.d.ts +++ b/dist/components/Interaction.d.ts @@ -1,5 +1,13 @@ export interface InteractionParams { + /** + * The element that has a Webflow Ix2 Click interaction binded to it. + */ element: HTMLElement | string; + /** + * The duration of the interaction. + * If a single number is passed, it will be used for both first and second interactions. + * If an object is passed, you can specify the duration for each interaction. + */ duration?: number | Partial; } export declare class Interaction { @@ -11,9 +19,29 @@ export declare class Interaction { first: number; second: number; }; + /** + * Acts as the controller for a Webflow Interaction. + * It accepts an element that will be clicked when required (firing a Mouse Click interaction). + * @param element Element that has the Mouse Click interaction. + * @param duration Optionally, the duration can be explicitly set so the trigger methods will return an awaitable Promise. + */ constructor({ element, duration }: InteractionParams); + /** + * Trigger the interaction + * @param click Perform first or second click + * @returns True if the interaction was fired + */ trigger(click?: 'first' | 'second'): Promise; + /** + * @returns If the interaction is active + */ isActive: () => boolean; + /** + * @returns If the interaction is running + */ isRunning: () => boolean; + /** + * @returns A promise that fulfills when the current running interaction has finished + */ untilFinished: () => Promise | undefined; } diff --git a/dist/components/Interaction.js b/dist/components/Interaction.js index 87fbed7..3e8b88c 100644 --- a/dist/components/Interaction.js +++ b/dist/components/Interaction.js @@ -7,6 +7,12 @@ export class Interaction { running = false; runningPromise; duration; + /** + * Acts as the controller for a Webflow Interaction. + * It accepts an element that will be clicked when required (firing a Mouse Click interaction). + * @param element Element that has the Mouse Click interaction. + * @param duration Optionally, the duration can be explicitly set so the trigger methods will return an awaitable Promise. + */ constructor({ element, duration }) { this.element = typeof element === 'string' @@ -18,6 +24,11 @@ export class Interaction { second: typeof duration === 'number' ? duration : duration?.second ?? 0, }; } + /** + * Trigger the interaction + * @param click Perform first or second click + * @returns True if the interaction was fired + */ async trigger(click) { if ((click === 'first' && this.active) || (click === 'second' && !this.active)) return false; @@ -31,7 +42,16 @@ export class Interaction { this.active = click === 'first'; return true; } + /** + * @returns If the interaction is active + */ isActive = () => this.active; + /** + * @returns If the interaction is running + */ isRunning = () => this.running; + /** + * @returns A promise that fulfills when the current running interaction has finished + */ untilFinished = () => this.runningPromise; } diff --git a/dist/components/WritableStore.d.ts b/dist/components/WritableStore.d.ts index eb74dc3..e6fd30b 100644 --- a/dist/components/WritableStore.d.ts +++ b/dist/components/WritableStore.d.ts @@ -1,9 +1,31 @@ +/** + * Writable Store that runs callbacks every time the provided value is updated. + */ export declare class WritableStore { private value; private subscribeCallbacks; + /** + * @param value The initial value of the store. + */ constructor(value: T); + /** + * @returns The current value + */ get(): T; + /** + * Sets a new value + * @param newValue + */ set(newValue: T): void; + /** + * Exposes the current value and accepts a new value as an update. + * @param callback + */ update(callback: (value: T) => T): void; + /** + * Subscribes the callback to run every time the store value changes. + * @param callback It receives the current value. + * @returns An unsubscribe method. + */ subscribe(callback: (value: T) => void): () => void; } diff --git a/dist/components/WritableStore.js b/dist/components/WritableStore.js index 94106be..3b8fe0b 100644 --- a/dist/components/WritableStore.js +++ b/dist/components/WritableStore.js @@ -1,19 +1,42 @@ +/** + * Writable Store that runs callbacks every time the provided value is updated. + */ export class WritableStore { value; subscribeCallbacks = []; + /** + * @param value The initial value of the store. + */ + // eslint-disable-next-line no-useless-constructor constructor(value) { this.value = value; } + /** + * @returns The current value + */ get() { return this.value; } + /** + * Sets a new value + * @param newValue + */ set(newValue) { this.value = newValue; this.subscribeCallbacks.forEach((callback) => callback(newValue)); } + /** + * Exposes the current value and accepts a new value as an update. + * @param callback + */ update(callback) { this.set(callback(this.value)); } + /** + * Subscribes the callback to run every time the store value changes. + * @param callback It receives the current value. + * @returns An unsubscribe method. + */ subscribe(callback) { this.subscribeCallbacks.push(callback); callback(this.value); diff --git a/dist/helpers/clearFormField.d.ts b/dist/helpers/clearFormField.d.ts index 7407829..a42ee6b 100644 --- a/dist/helpers/clearFormField.d.ts +++ b/dist/helpers/clearFormField.d.ts @@ -1,3 +1,10 @@ import { simulateEvent } from './simulateEvent'; import type { FormField } from '../types'; +/** + * Clears the form field's value and emits an input and changed event. + * If the field is a checkbox or a radio, it will unselect it. + * @param field The `FormField` to clear. + * @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system. + * You can omit certain events from being dispatched by passing them in an array. + */ export declare const clearFormField: (field: FormField, omitEvents?: Parameters['1']) => void; diff --git a/dist/helpers/clearFormField.js b/dist/helpers/clearFormField.js index d5247bf..bb8a92f 100644 --- a/dist/helpers/clearFormField.js +++ b/dist/helpers/clearFormField.js @@ -1,15 +1,25 @@ import { FORM_CSS_CLASSES } from '../webflow/css'; import { simulateEvent } from './simulateEvent'; const { radioInput: radioInputCSSClass, checkboxOrRadioFocus: focusCSSClass, checkboxOrRadioChecked: checkedCSSClass, } = FORM_CSS_CLASSES; +/** + * Clears the form field's value and emits an input and changed event. + * If the field is a checkbox or a radio, it will unselect it. + * @param field The `FormField` to clear. + * @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system. + * You can omit certain events from being dispatched by passing them in an array. + */ export const clearFormField = (field, omitEvents = []) => { const { type } = field; if (field instanceof HTMLInputElement && ['checkbox', 'radio'].includes(type)) { if (!field.checked) return; + // Reset the field's value field.checked = false; + // Emit DOM events simulateEvent(field, ['click', 'input', 'change'].filter((event) => !omitEvents.includes(event))); if (type === 'checkbox') return; + // Clear custom radio button classes const { parentElement } = field; if (!parentElement) return; @@ -19,6 +29,8 @@ export const clearFormField = (field, omitEvents = []) => { radioInput.classList.remove(focusCSSClass, checkedCSSClass); return; } + // Reset the field's value field.value = ''; + // Emit DOM events simulateEvent(field, ['input', 'change'].filter((eventKey) => !omitEvents.includes(eventKey))); }; diff --git a/dist/helpers/cloneNode.d.ts b/dist/helpers/cloneNode.d.ts index 023d4ea..451bdfd 100644 --- a/dist/helpers/cloneNode.d.ts +++ b/dist/helpers/cloneNode.d.ts @@ -1 +1,5 @@ +/** + * Clone a node that has the same type as the original one + * @param node + */ export declare const cloneNode: (node: T, deep?: boolean) => T; diff --git a/dist/helpers/cloneNode.js b/dist/helpers/cloneNode.js index 454f8c0..bc7287c 100644 --- a/dist/helpers/cloneNode.js +++ b/dist/helpers/cloneNode.js @@ -1 +1,5 @@ +/** + * Clone a node that has the same type as the original one + * @param node + */ export const cloneNode = (node, deep = true) => node.cloneNode(deep); diff --git a/dist/helpers/extractCommaSeparatedValues.d.ts b/dist/helpers/extractCommaSeparatedValues.d.ts index b3f41f0..dc6a123 100644 --- a/dist/helpers/extractCommaSeparatedValues.d.ts +++ b/dist/helpers/extractCommaSeparatedValues.d.ts @@ -1,2 +1,10 @@ +/** + * Convert a string of comma separated values to an array of values. + * + * @param string Comma separated string. + * @param compareSource Acts as a type guard for making sure the extracted values match the compared source. + * @param defaultValue Is set when there is no matching results after comparing with the source. + * @param filterEmpty Defines if empty values should be filtered out of the returned array. Defaults to `true`. + */ export declare function extractCommaSeparatedValues(string: string | null | undefined, compareSource?: undefined, defaultValue?: undefined, filterEmpty?: boolean): string[]; export declare function extractCommaSeparatedValues(string: string | null | undefined, compareSource: readonly SourceKey[], defaultValue?: DefaultKey | undefined, filterEmpty?: boolean): SourceKey[]; diff --git a/dist/helpers/extractNumberSuffix.d.ts b/dist/helpers/extractNumberSuffix.d.ts index 50fc4d2..0803bfe 100644 --- a/dist/helpers/extractNumberSuffix.d.ts +++ b/dist/helpers/extractNumberSuffix.d.ts @@ -1 +1,8 @@ +/** + * Finds if a string is suffixed by `-X` and returns the value of `X`. + * @example `click-2` will return `2`. + * @example `click` will return `undefined`. + * @param string The string to extract. + * @returns The number suffix, if found. + */ export declare const extractNumberSuffix: (string: string) => number | undefined; diff --git a/dist/helpers/extractNumberSuffix.js b/dist/helpers/extractNumberSuffix.js index 8a69a49..5050b0e 100644 --- a/dist/helpers/extractNumberSuffix.js +++ b/dist/helpers/extractNumberSuffix.js @@ -1,3 +1,10 @@ +/** + * Finds if a string is suffixed by `-X` and returns the value of `X`. + * @example `click-2` will return `2`. + * @example `click` will return `undefined`. + * @param string The string to extract. + * @returns The number suffix, if found. + */ export const extractNumberSuffix = (string) => { const splitValue = string.split('-'); const suffix = parseInt(splitValue[splitValue.length - 1]); diff --git a/dist/helpers/findTextNode.d.ts b/dist/helpers/findTextNode.d.ts index 8d3665f..1e7a9df 100644 --- a/dist/helpers/findTextNode.d.ts +++ b/dist/helpers/findTextNode.d.ts @@ -1 +1,5 @@ +/** + * Finds the first child text node of an element + * @param element The element to search into. + */ export declare const findTextNode: (element: HTMLElement) => ChildNode | undefined; diff --git a/dist/helpers/findTextNode.js b/dist/helpers/findTextNode.js index 1fd0690..522c1d3 100644 --- a/dist/helpers/findTextNode.js +++ b/dist/helpers/findTextNode.js @@ -1,3 +1,7 @@ +/** + * Finds the first child text node of an element + * @param element The element to search into. + */ export const findTextNode = (element) => { let textNode; for (const node of element.childNodes) { diff --git a/dist/helpers/getAllParents.d.ts b/dist/helpers/getAllParents.d.ts index e6d3cab..bdda32b 100644 --- a/dist/helpers/getAllParents.d.ts +++ b/dist/helpers/getAllParents.d.ts @@ -1 +1,5 @@ +/** + * Returns a list of all parents of an element, excepting the `` and `` tags. + * @param element + */ export declare const getAllParents: (element: Element) => HTMLElement[]; diff --git a/dist/helpers/getAllParents.js b/dist/helpers/getAllParents.js index 6fa997c..7a18994 100644 --- a/dist/helpers/getAllParents.js +++ b/dist/helpers/getAllParents.js @@ -1,3 +1,7 @@ +/** + * Returns a list of all parents of an element, excepting the `` and `` tags. + * @param element + */ export const getAllParents = (element) => { const parents = []; const storeParents = ({ parentElement }) => { diff --git a/dist/helpers/getDistanceFromTop.d.ts b/dist/helpers/getDistanceFromTop.d.ts index e346f0b..4e16dc6 100644 --- a/dist/helpers/getDistanceFromTop.d.ts +++ b/dist/helpers/getDistanceFromTop.d.ts @@ -1 +1,6 @@ +/** + * Get the distance between an element and the top of the window + * @param element + * @returns The distance in pixels + */ export declare const getDistanceFromTop: (element: Element) => number; diff --git a/dist/helpers/getDistanceFromTop.js b/dist/helpers/getDistanceFromTop.js index 31ee675..8fb8d29 100644 --- a/dist/helpers/getDistanceFromTop.js +++ b/dist/helpers/getDistanceFromTop.js @@ -1,5 +1,11 @@ +/** + * Get the distance between an element and the top of the window + * @param element + * @returns The distance in pixels + */ export const getDistanceFromTop = (element) => { const rect = element.getBoundingClientRect(); + // prettier-ignore const scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop; return rect.top + scrollTop; }; diff --git a/dist/helpers/getFormFieldValue.d.ts b/dist/helpers/getFormFieldValue.d.ts index c87a08a..297eafa 100644 --- a/dist/helpers/getFormFieldValue.d.ts +++ b/dist/helpers/getFormFieldValue.d.ts @@ -1,2 +1,6 @@ import type { FormField } from '../types/FormField'; +/** + * Gets the value of a given input element. + * @param {FormField} input + */ export declare const getFormFieldValue: (input: FormField) => string; diff --git a/dist/helpers/getFormFieldValue.js b/dist/helpers/getFormFieldValue.js index c1810d9..989572e 100644 --- a/dist/helpers/getFormFieldValue.js +++ b/dist/helpers/getFormFieldValue.js @@ -1,9 +1,16 @@ +/** + * Gets the value of a given input element. + * @param {FormField} input + */ export const getFormFieldValue = (input) => { let { value } = input; + // Perform actions depending on input type if (input.type === 'checkbox') value = input.checked.toString(); if (input.type === 'radio') { + // Get the checked radio const checkedOption = input.closest('form')?.querySelector(`input[name="${input.name}"]:checked`); + // If exists, set its value value = checkedOption instanceof HTMLInputElement ? checkedOption.value : ''; } return value.toString(); diff --git a/dist/helpers/getHiddenParent.d.ts b/dist/helpers/getHiddenParent.d.ts index 8a9daf0..cb38d55 100644 --- a/dist/helpers/getHiddenParent.d.ts +++ b/dist/helpers/getHiddenParent.d.ts @@ -1 +1,7 @@ +/** + * @returns The first hidden parent element, or the element itself (if hidden). + * If the element is already visible, the function returns `undefined`. + * + * @param element The reference element. + */ export declare const getHiddenParent: (element: HTMLElement) => HTMLElement | undefined; diff --git a/dist/helpers/getHiddenParent.js b/dist/helpers/getHiddenParent.js index bb1bf20..4e00073 100644 --- a/dist/helpers/getHiddenParent.js +++ b/dist/helpers/getHiddenParent.js @@ -1,4 +1,10 @@ import { isVisible } from '.'; +/** + * @returns The first hidden parent element, or the element itself (if hidden). + * If the element is already visible, the function returns `undefined`. + * + * @param element The reference element. + */ export const getHiddenParent = (element) => { if (isVisible(element)) return; diff --git a/dist/helpers/getObjectEntries.d.ts b/dist/helpers/getObjectEntries.d.ts index 7ad3223..8102085 100644 --- a/dist/helpers/getObjectEntries.d.ts +++ b/dist/helpers/getObjectEntries.d.ts @@ -1,2 +1,6 @@ import type { Entry } from '../types/Entry'; +/** + * Gets type safe `Object.entries()`. + * @param object + */ export declare const getObjectEntries: >>(object: T) => Entry[]; diff --git a/dist/helpers/getObjectEntries.js b/dist/helpers/getObjectEntries.js index e213349..69b0696 100644 --- a/dist/helpers/getObjectEntries.js +++ b/dist/helpers/getObjectEntries.js @@ -1 +1,6 @@ +/** + * Gets type safe `Object.entries()`. + * @param object + */ +// prettier-ignore export const getObjectEntries = (object) => Object.entries(object); diff --git a/dist/helpers/getObjectKeys.d.ts b/dist/helpers/getObjectKeys.d.ts index f8d80f1..4613b1f 100644 --- a/dist/helpers/getObjectKeys.d.ts +++ b/dist/helpers/getObjectKeys.d.ts @@ -1 +1,6 @@ +/** + * Gets the keys of an object with inferred typing. + * @param object + * @returns + */ export declare const getObjectKeys: >(object: T) => (keyof T)[]; diff --git a/dist/helpers/getObjectKeys.js b/dist/helpers/getObjectKeys.js index dfd024f..c2d3513 100644 --- a/dist/helpers/getObjectKeys.js +++ b/dist/helpers/getObjectKeys.js @@ -1 +1,7 @@ +/** + * Gets the keys of an object with inferred typing. + * @param object + * @returns + */ +// prettier-ignore export const getObjectKeys = (object) => Object.keys(object); diff --git a/dist/helpers/isScrollable.d.ts b/dist/helpers/isScrollable.d.ts index f1f8d90..e7e1e14 100644 --- a/dist/helpers/isScrollable.d.ts +++ b/dist/helpers/isScrollable.d.ts @@ -1 +1,6 @@ +/** + * Check if an element is scrollable + * @param element + * @returns True or false + */ export declare const isScrollable: (element: Element) => boolean; diff --git a/dist/helpers/isScrollable.js b/dist/helpers/isScrollable.js index 4055dc2..4246805 100644 --- a/dist/helpers/isScrollable.js +++ b/dist/helpers/isScrollable.js @@ -1,3 +1,8 @@ +/** + * Check if an element is scrollable + * @param element + * @returns True or false + */ export const isScrollable = (element) => { const { overflow } = getComputedStyle(element); return overflow === 'auto' || overflow === 'scroll'; diff --git a/dist/helpers/isVisible.d.ts b/dist/helpers/isVisible.d.ts index bed1af6..e319b2f 100644 --- a/dist/helpers/isVisible.d.ts +++ b/dist/helpers/isVisible.d.ts @@ -1 +1,5 @@ +/** + * Checks if an element is visible + * @param element + */ export declare const isVisible: (element: HTMLElement) => boolean; diff --git a/dist/helpers/isVisible.js b/dist/helpers/isVisible.js index 36df2ef..c847368 100644 --- a/dist/helpers/isVisible.js +++ b/dist/helpers/isVisible.js @@ -1 +1,6 @@ +/** + * Checks if an element is visible + * @param element + */ +// prettier-ignore export const isVisible = (element) => !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); diff --git a/dist/helpers/queryElement.d.ts b/dist/helpers/queryElement.d.ts index f9a6924..488d48c 100644 --- a/dist/helpers/queryElement.d.ts +++ b/dist/helpers/queryElement.d.ts @@ -1,2 +1,9 @@ import type { Instance } from '../types/Instance'; +/** + * Query an element and make sure it's the correct type + * @param selector Selector string + * @param instance Instance target of the element type. Example: HTMLElement + * @param scope The scope context where to query. Defaults to document + * @returns The queried element or undefined + */ export declare const queryElement: (selector: string, instance: Instance, scope?: ParentNode) => T | undefined; diff --git a/dist/helpers/queryElement.js b/dist/helpers/queryElement.js index 5e87e6e..64edf40 100644 --- a/dist/helpers/queryElement.js +++ b/dist/helpers/queryElement.js @@ -1,3 +1,10 @@ +/** + * Query an element and make sure it's the correct type + * @param selector Selector string + * @param instance Instance target of the element type. Example: HTMLElement + * @param scope The scope context where to query. Defaults to document + * @returns The queried element or undefined + */ export const queryElement = (selector, instance, scope = document) => { const element = scope.querySelector(selector); if (element instanceof instance) diff --git a/dist/helpers/removeChildElements.d.ts b/dist/helpers/removeChildElements.d.ts index 3258f8f..0704811 100644 --- a/dist/helpers/removeChildElements.d.ts +++ b/dist/helpers/removeChildElements.d.ts @@ -1 +1,6 @@ -export declare const removeChildElements: (element: Element, selector?: string | undefined) => void; +/** + * Remove all child elements from a parent element + * @param element Parent element + * @param selector Optional: only remove the elements that match this selector + */ +export declare const removeChildElements: (element: Element, selector?: string) => void; diff --git a/dist/helpers/removeChildElements.js b/dist/helpers/removeChildElements.js index 80bb65b..636ee65 100644 --- a/dist/helpers/removeChildElements.js +++ b/dist/helpers/removeChildElements.js @@ -1,3 +1,8 @@ +/** + * Remove all child elements from a parent element + * @param element Parent element + * @param selector Optional: only remove the elements that match this selector + */ export const removeChildElements = (element, selector) => { const childElements = element.querySelectorAll(selector || '*'); childElements.forEach((childElement) => childElement.remove()); diff --git a/dist/helpers/removeSpaces.d.ts b/dist/helpers/removeSpaces.d.ts index 2dd036f..5cf94da 100644 --- a/dist/helpers/removeSpaces.d.ts +++ b/dist/helpers/removeSpaces.d.ts @@ -1 +1,6 @@ +/** + * Removes all the spaces of a string. + * @param string + * @returns The string without spaces. Example: "The quick brown fox" => "Thequickbrownfox" + */ export declare const removeSpaces: (string: string) => string; diff --git a/dist/helpers/removeSpaces.js b/dist/helpers/removeSpaces.js index 2054725..942a9cb 100644 --- a/dist/helpers/removeSpaces.js +++ b/dist/helpers/removeSpaces.js @@ -1 +1,6 @@ +/** + * Removes all the spaces of a string. + * @param string + * @returns The string without spaces. Example: "The quick brown fox" => "Thequickbrownfox" + */ export const removeSpaces = (string) => string.replace(/\s/g, ''); diff --git a/dist/helpers/removeTrailingSlash.d.ts b/dist/helpers/removeTrailingSlash.d.ts index 23b119e..a598755 100644 --- a/dist/helpers/removeTrailingSlash.d.ts +++ b/dist/helpers/removeTrailingSlash.d.ts @@ -1 +1,16 @@ +/** + * Removes the trailing slash from a URL string. + * + * @example + * ``` + * This: + * https://www.finsweet.com/attributes/attractions/capri-island/ + * + * Becomes: + * https://www.finsweet.com/attributes/attractions/capri-island + * ``` + * + * @param value The value to mutate. + * @returns A new string without a trailing slash. + */ export declare const removeTrailingSlash: (value: string) => string; diff --git a/dist/helpers/removeTrailingSlash.js b/dist/helpers/removeTrailingSlash.js index 4c62751..a9eb7c7 100644 --- a/dist/helpers/removeTrailingSlash.js +++ b/dist/helpers/removeTrailingSlash.js @@ -1 +1,16 @@ +/** + * Removes the trailing slash from a URL string. + * + * @example + * ``` + * This: + * https://www.finsweet.com/attributes/attractions/capri-island/ + * + * Becomes: + * https://www.finsweet.com/attributes/attractions/capri-island + * ``` + * + * @param value The value to mutate. + * @returns A new string without a trailing slash. + */ export const removeTrailingSlash = (value) => value.replace(/\/+$/, ''); diff --git a/dist/helpers/sameValues.d.ts b/dist/helpers/sameValues.d.ts index 6fb13d8..632dc32 100644 --- a/dist/helpers/sameValues.d.ts +++ b/dist/helpers/sameValues.d.ts @@ -1 +1,6 @@ +/** + * Compares if two arrays have the same exact values. + * @param array1 + * @param array2 + */ export declare const sameValues: (array1: unknown[], array2: unknown[]) => boolean; diff --git a/dist/helpers/sameValues.js b/dist/helpers/sameValues.js index 6108d9c..24f23ac 100644 --- a/dist/helpers/sameValues.js +++ b/dist/helpers/sameValues.js @@ -1 +1,7 @@ +/** + * Compares if two arrays have the same exact values. + * @param array1 + * @param array2 + */ +// prettier-ignore export const sameValues = (array1, array2) => array1.every((key) => array2.includes(key)) && array2.every((key) => array1.includes(key)); diff --git a/dist/helpers/selectInputElement.d.ts b/dist/helpers/selectInputElement.d.ts index 587f137..6c937c2 100644 --- a/dist/helpers/selectInputElement.d.ts +++ b/dist/helpers/selectInputElement.d.ts @@ -1 +1,10 @@ +/** + * **DEPRECATED: Please use the new `setFormFieldValue` method instead.** + * + * + * Selects a custom radio or checkbox element + * @param element Element to select + * @param select - Defaults to true. If set to false, the input element will be unselected. + * @returns The value of the element: Boolean for checkboxes and string for radios + */ export declare const selectInputElement: (element: HTMLInputElement, select?: boolean) => string | boolean; diff --git a/dist/helpers/selectInputElement.js b/dist/helpers/selectInputElement.js index e5c2a27..3c61021 100644 --- a/dist/helpers/selectInputElement.js +++ b/dist/helpers/selectInputElement.js @@ -1,7 +1,18 @@ import { simulateEvent } from './simulateEvent'; +/** + * **DEPRECATED: Please use the new `setFormFieldValue` method instead.** + * + * + * Selects a custom radio or checkbox element + * @param element Element to select + * @param select - Defaults to true. If set to false, the input element will be unselected. + * @returns The value of the element: Boolean for checkboxes and string for radios + */ export const selectInputElement = (element, select = true) => { if (select !== element.checked) { + // Set the new checked value element.checked = select; + // Emit DOM events simulateEvent(element, ['click', 'input', 'change']); } return element.type === 'checkbox' ? element.checked : element.value; diff --git a/dist/helpers/setFormFieldValue.d.ts b/dist/helpers/setFormFieldValue.d.ts index 836b179..7901453 100644 --- a/dist/helpers/setFormFieldValue.d.ts +++ b/dist/helpers/setFormFieldValue.d.ts @@ -1,2 +1,8 @@ import type { FormField } from '..'; +/** + * Sets a value to a FormField element and emits `click`, `input` and `change` Events. + * + * @param element The FormField to update. + * @param value `boolean` for Checkboxes and Radios, `string` for the rest. + */ export declare const setFormFieldValue: (element: FormField, value: string | boolean) => void; diff --git a/dist/helpers/setFormFieldValue.js b/dist/helpers/setFormFieldValue.js index 2497546..28eec85 100644 --- a/dist/helpers/setFormFieldValue.js +++ b/dist/helpers/setFormFieldValue.js @@ -1,4 +1,10 @@ import { simulateEvent } from '.'; +/** + * Sets a value to a FormField element and emits `click`, `input` and `change` Events. + * + * @param element The FormField to update. + * @param value `boolean` for Checkboxes and Radios, `string` for the rest. + */ export const setFormFieldValue = (element, value) => { const { type } = element; const isRadio = type === 'radio'; @@ -17,5 +23,6 @@ export const setFormFieldValue = (element, value) => { return; element.value = value.toString(); } + // Emit DOM events simulateEvent(element, ['click', 'input', 'change']); }; diff --git a/dist/helpers/simulateEvent.d.ts b/dist/helpers/simulateEvent.d.ts index fe471dc..b23a905 100644 --- a/dist/helpers/simulateEvent.d.ts +++ b/dist/helpers/simulateEvent.d.ts @@ -1,3 +1,9 @@ declare type AllowedEvent = keyof DocumentEventMap | 'w-close'; +/** + * Dispatches a custom event that bubbles from the target. + * @param target The element where the event will originate. + * @param events The event name or an array of event names. + * @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. + */ export declare const simulateEvent: (target: EventTarget, events: AllowedEvent | Array) => boolean; export {}; diff --git a/dist/helpers/simulateEvent.js b/dist/helpers/simulateEvent.js index aa7acac..9b811c5 100644 --- a/dist/helpers/simulateEvent.js +++ b/dist/helpers/simulateEvent.js @@ -1,3 +1,9 @@ +/** + * Dispatches a custom event that bubbles from the target. + * @param target The element where the event will originate. + * @param events The event name or an array of event names. + * @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. + */ export const simulateEvent = (target, events) => { if (!Array.isArray(events)) events = [events]; diff --git a/dist/helpers/throwError.d.ts b/dist/helpers/throwError.d.ts index 3189ea2..9c2cc86 100644 --- a/dist/helpers/throwError.d.ts +++ b/dist/helpers/throwError.d.ts @@ -1 +1,6 @@ +/** + * Displays an alert and throw an exception. + * @param message + * @returns The generic argument to assure type safety when querying DOM Elements. + */ export declare const throwError: (message: string) => T; diff --git a/dist/helpers/throwError.js b/dist/helpers/throwError.js index 1e85b0b..c4d07e0 100644 --- a/dist/helpers/throwError.js +++ b/dist/helpers/throwError.js @@ -1,3 +1,8 @@ +/** + * Displays an alert and throw an exception. + * @param message + * @returns The generic argument to assure type safety when querying DOM Elements. + */ export const throwError = (message) => { throw new Error(message); }; diff --git a/dist/helpers/wait.d.ts b/dist/helpers/wait.d.ts index 77a8f73..dfe1e15 100644 --- a/dist/helpers/wait.d.ts +++ b/dist/helpers/wait.d.ts @@ -1 +1,5 @@ +/** + * @returns Awaitable promise for waiting X time. + * @param time + */ export declare const wait: (time: number) => Promise; diff --git a/dist/helpers/wait.js b/dist/helpers/wait.js index 47d88a9..0f7648e 100644 --- a/dist/helpers/wait.js +++ b/dist/helpers/wait.js @@ -1 +1,5 @@ +/** + * @returns Awaitable promise for waiting X time. + * @param time + */ export const wait = (time) => new Promise((resolve) => setTimeout(resolve, time)); diff --git a/dist/type-guards/isFormField.d.ts b/dist/type-guards/isFormField.d.ts index 60380ce..153bcb0 100644 --- a/dist/type-guards/isFormField.d.ts +++ b/dist/type-guards/isFormField.d.ts @@ -1,2 +1,6 @@ import type { FormField } from '../types/FormField'; +/** + * Checks if an element is a form field element + * @param element + */ export declare const isFormField: (element: Element | EventTarget | null) => element is FormField; diff --git a/dist/type-guards/isFormField.js b/dist/type-guards/isFormField.js index 908b00c..3d16ff7 100644 --- a/dist/type-guards/isFormField.js +++ b/dist/type-guards/isFormField.js @@ -1 +1,6 @@ +/** + * Checks if an element is a form field element + * @param element + */ +// prettier-ignore export const isFormField = (element) => element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement; diff --git a/dist/type-guards/isKeyOf.d.ts b/dist/type-guards/isKeyOf.d.ts index 08364de..7930ae4 100644 --- a/dist/type-guards/isKeyOf.d.ts +++ b/dist/type-guards/isKeyOf.d.ts @@ -1 +1,7 @@ +/** + * Check if a key is included in a readonly array + * @param key + * @param source readonly array of strings + * @returns True/false + */ export declare const isKeyOf: (key: string | null | undefined, source: readonly T[]) => key is T; diff --git a/dist/type-guards/isKeyOf.js b/dist/type-guards/isKeyOf.js index 9a16948..cd14490 100644 --- a/dist/type-guards/isKeyOf.js +++ b/dist/type-guards/isKeyOf.js @@ -1 +1,7 @@ +/** + * Check if a key is included in a readonly array + * @param key + * @param source readonly array of strings + * @returns True/false + */ export const isKeyOf = (key, source) => !!key && source.includes(key); diff --git a/dist/type-guards/isNotEmpty.d.ts b/dist/type-guards/isNotEmpty.d.ts index 5d2d6df..cba4214 100644 --- a/dist/type-guards/isNotEmpty.d.ts +++ b/dist/type-guards/isNotEmpty.d.ts @@ -1 +1,13 @@ +/** + * Makes sure a value is not `null` or `undefined`. + * Useful for type safety when filtering empty elements from an array. Check out the example for more in-depth explanation. + * @param value The value to type-check. + * @example ```typescript + * const items = [1, null, 4, undefined, 8]; + * + * const filteredItemsError: number[] = items.filter((item) => value !== undefined && value !== null); // Type '(number | null | undefined)[]' is not assignable to type 'number[]'. + * + * const filteredItemsSuccess: number[] = items.filter(isNotEmpty); // Success! + * ``` + */ export declare const isNotEmpty: (value: T | null | undefined) => value is T; diff --git a/dist/type-guards/isNotEmpty.js b/dist/type-guards/isNotEmpty.js index c7d830f..16832bb 100644 --- a/dist/type-guards/isNotEmpty.js +++ b/dist/type-guards/isNotEmpty.js @@ -1 +1,13 @@ +/** + * Makes sure a value is not `null` or `undefined`. + * Useful for type safety when filtering empty elements from an array. Check out the example for more in-depth explanation. + * @param value The value to type-check. + * @example ```typescript + * const items = [1, null, 4, undefined, 8]; + * + * const filteredItemsError: number[] = items.filter((item) => value !== undefined && value !== null); // Type '(number | null | undefined)[]' is not assignable to type 'number[]'. + * + * const filteredItemsSuccess: number[] = items.filter(isNotEmpty); // Success! + * ``` + */ export const isNotEmpty = (value) => value !== undefined && value !== null; diff --git a/dist/types/Entry.d.ts b/dist/types/Entry.d.ts index 9b63567..772344e 100644 --- a/dist/types/Entry.d.ts +++ b/dist/types/Entry.d.ts @@ -1,3 +1,6 @@ +/** + * Defines a typed object entry + */ export declare type Entry = { [K in keyof T]: [K, T[K]]; }[keyof T]; diff --git a/dist/types/Instance.d.ts b/dist/types/Instance.d.ts index 871dda1..44cbbb3 100644 --- a/dist/types/Instance.d.ts +++ b/dist/types/Instance.d.ts @@ -1,3 +1,6 @@ +/** + * Declares the instance of an object + */ export declare type Instance = { new (): T; prototype: T; diff --git a/dist/types/MapEntries.d.ts b/dist/types/MapEntries.d.ts index 9c05604..ee0581d 100644 --- a/dist/types/MapEntries.d.ts +++ b/dist/types/MapEntries.d.ts @@ -1 +1,10 @@ +/** + * Converts a `Map` type to its equivalent when performing `[...map.entries()]`. + * @example ```typescript + * const map: MapType = new Map(['key', 'value']); + * const entries = [...map.entries()]; // Same type as MapEntries + * + * typeof entries === MapEntries + * ``` + */ export declare type MapEntries = MapToConvert extends Map ? [Key, Value][] : never; diff --git a/dist/types/PartialExcept.d.ts b/dist/types/PartialExcept.d.ts index 87af1f9..4cc2e28 100644 --- a/dist/types/PartialExcept.d.ts +++ b/dist/types/PartialExcept.d.ts @@ -1 +1,4 @@ +/** + * The picked keys will become Required and the rest of the interface will become Partial. + */ export declare type PartialExcept = Partial> & Required>; diff --git a/dist/types/PickPartial.d.ts b/dist/types/PickPartial.d.ts index 75b751e..bc8f6d3 100644 --- a/dist/types/PickPartial.d.ts +++ b/dist/types/PickPartial.d.ts @@ -1 +1,4 @@ +/** + * The picked keys will become Partial and the rest of the interface will stay the same. + */ export declare type PickPartial = Omit & Partial>; diff --git a/dist/types/PickRequired.d.ts b/dist/types/PickRequired.d.ts index 20f6ae4..024bee5 100644 --- a/dist/types/PickRequired.d.ts +++ b/dist/types/PickRequired.d.ts @@ -1 +1,4 @@ +/** + * The picked keys will become required and the rest of the interface will stay the same. + */ export declare type PickRequired = Omit & Required>; diff --git a/dist/types/RequiredExcept.d.ts b/dist/types/RequiredExcept.d.ts index ff5dc38..ddfbd84 100644 --- a/dist/types/RequiredExcept.d.ts +++ b/dist/types/RequiredExcept.d.ts @@ -1 +1,4 @@ +/** + * The picked keys will become Partial and the rest of the interface will become Required. + */ export declare type RequiredExcept = Required> & Partial>; diff --git a/dist/types/UnionToIntersection.d.ts b/dist/types/UnionToIntersection.d.ts index 337d572..2d2c97c 100644 --- a/dist/types/UnionToIntersection.d.ts +++ b/dist/types/UnionToIntersection.d.ts @@ -1 +1,4 @@ +/** + * Converts a union like `Interface1 | Interface2` to an intersection `Interface1 & Interface2`. + */ export declare type UnionToIntersection = (Union extends unknown ? (k: Union) => void : never) extends (k: infer Intersection) => void ? Intersection : never; diff --git a/dist/types/apis/Greenhouse.d.ts b/dist/types/apis/Greenhouse.d.ts index 578d9ab..64a0a9c 100644 --- a/dist/types/apis/Greenhouse.d.ts +++ b/dist/types/apis/Greenhouse.d.ts @@ -1,18 +1,35 @@ +/** + * Endpoint response for: https://boards-api.greenhouse.io/v1/boards/{board_token}/departments + */ export interface DepartmentsResponse { departments: Department[]; } +/** + * Endpoint response for: https://boards-api.greenhouse.io/v1/boards/{board_token}/jobs + */ export interface JobsResponse { jobs: Job[] | JobWithContent[]; meta: { total: number; }; } +/** + * Endpoint response for: https://boards-api.greenhouse.io/v1/boards/{board_token}/jobs/{job_id} + */ export interface JobUniqueResponse { job: JobWithContent | JobWithQuestions; } +/** + * Endpoint response for: https://boards-api.greenhouse.io/v1/boards/{board_token}/offices + */ export interface OfficesResponse { offices: Office[]; } +/** + * Job application details. + * This is the result of the /{board_token}/jobs endpoint. + * This could be extended by calling the endpoint with ?content=true resulting on JobWithContent being returned. + */ export interface Job { id: number; internal_job_id: number; @@ -26,22 +43,42 @@ export interface Job { }; data_compliance: DataCompliance[]; } +/** + * For organizations with GDPR rules configured and operating with a legal basis of + * explicit consent, the response may contain data_compliance objects. + * These objects will include whether a response is required and the data retention + * period in days as configured by the appropriate rule. + */ interface DataCompliance { type: 'gdpr'; requires_consent: boolean; retention_period: number | null; } +/** + * Job with details. + * This is the result of calling any endpoint with ?content=true or /jobs/{job_id} + */ export interface JobWithContent extends Job { content: string; departments: Department[]; offices: Office[]; } +/** + * Job with application questions. + * This is the result of calling the /jobs/{job_id} endpoint with ?questions=true + */ export interface JobWithQuestions extends JobWithContent { questions: Question[]; compliance: ComplianceQuestions[]; location_questions: Question[]; demographic_questions: DemographicQuestions | null; } +/** + * Please note that it is possible for multiple fields to be aggregated beneath a single question. + * The “Resume” field is a prime example, with both an input_file and textarea type accepted. + * If marked as required, then we expect at least one of these fields to contain a valid + * value when your form is submitted to the application submission endpoint. + */ export interface Question { label: string; description: string | null; @@ -62,11 +99,24 @@ interface ComplianceQuestions { questions: Question[]; type: string; } +/** + * For organizations using Greenhouse Inclusion, the response may contain demographic questions. + * Each question contains an array of answer options that may be rendered based on + * the question ‘type’ defined in the table above. The candidate must select an + * answer option for questions with required set to true. If an answer option + * is selected that has free_form set to true, the candidate must be + * allowed to type a free-form response. This free-form response + * is only required if no other answer options have been + * selected by the candidate. + */ interface DemographicQuestions { header: string; description: string; questions: Question[]; } +/** + * Organization department. Could include a parent department and a list of sub-departments. + */ export interface Department { id: number; name: string; @@ -74,6 +124,10 @@ export interface Department { child_ids: number[]; jobs: Job[]; } +/** + * List of all the organization’s departments and jobs. Could include a + * parent office and a list of sub-offices + */ export interface Office { id: number; name: string; diff --git a/dist/types/apis/Greenhouse.js b/dist/types/apis/Greenhouse.js index cb0ff5c..838c62f 100644 --- a/dist/types/apis/Greenhouse.js +++ b/dist/types/apis/Greenhouse.js @@ -1 +1,2 @@ +// ENDPOINT RESPONSES export {}; diff --git a/dist/webflow/Webflow.d.ts b/dist/webflow/Webflow.d.ts index b813511..4c1e9f5 100644 --- a/dist/webflow/Webflow.d.ts +++ b/dist/webflow/Webflow.d.ts @@ -1,3 +1,6 @@ +/** + * Callback type for the Webflow.push() method. + */ declare type Callback = () => unknown; export declare type WebflowModule = 'ix2' | 'commerce' | 'lottie' | 'lightbox' | 'slider' | 'tabs'; interface WebflowCommerce { @@ -54,12 +57,18 @@ interface WebflowIx2 { }; }; } +/** + * Includes methods of the Webflow.js object + */ export interface Webflow extends Pick { destroy: () => void; ready: () => void; env: () => boolean; require: (key: Key) => (Key extends 'commerce' ? WebflowCommerce : Key extends 'lightbox' ? WebflowLightbox : Key extends 'slider' ? WebflowSlider : Key extends 'tabs' ? WebflowTabs : WebflowIx2) | undefined; } +/** + * Declare it globally + */ declare global { interface Window { Webflow?: Webflow | Callback[]; diff --git a/dist/webflow/WebflowElements.d.ts b/dist/webflow/WebflowElements.d.ts index d6efaed..a575e75 100644 --- a/dist/webflow/WebflowElements.d.ts +++ b/dist/webflow/WebflowElements.d.ts @@ -1,3 +1,6 @@ +/** + * CMS + */ export declare type CollectionListWrapperElement = HTMLDivElement; export declare type CollectionListElement = HTMLDivElement; export declare type CollectionItemElement = HTMLDivElement; @@ -5,21 +8,36 @@ export declare type CollectionEmptyElement = HTMLDivElement; export declare type PaginationWrapperElement = HTMLDivElement; export declare type PaginationButtonElement = HTMLAnchorElement; export declare type PageCountElement = HTMLDivElement; +/** + * Forms + */ export declare type FormBlockElement = HTMLDivElement; export declare type FormSuccessElement = HTMLDivElement; export declare type FormErrorElement = HTMLDivElement; +/** + * Sliders + */ export declare type SliderElement = HTMLDivElement; export declare type SliderMaskElement = HTMLDivElement; export declare type SlideElement = HTMLDivElement; export declare type SliderArrowElement = HTMLDivElement; export declare type SliderNavElement = HTMLDivElement; export declare type SliderDotElement = HTMLDivElement; +/** + * Tabs + */ export declare type TabsElement = HTMLDivElement; export declare type TabsMenuElement = HTMLDivElement; export declare type TabLinkElement = HTMLDivElement; export declare type TabsContentElement = HTMLDivElement; export declare type TabPaneElement = HTMLDivElement; +/** + * Rich Text Block + */ export declare type RichTextBlockElement = HTMLDivElement; +/** + * Dropdowns + */ export declare type Dropdown = HTMLDivElement; export declare type DropdownToggle = HTMLDivElement; export declare type DropdownList = HTMLElement; diff --git a/dist/webflow/breakpoints.d.ts b/dist/webflow/breakpoints.d.ts index 9264053..ba6ebca 100644 --- a/dist/webflow/breakpoints.d.ts +++ b/dist/webflow/breakpoints.d.ts @@ -1,4 +1,10 @@ +/** + * The default Webflow Breakpoint names. + */ export declare type WebflowBreakpoint = 'main' | 'medium' | 'small' | 'tiny'; declare type WebflowBreakpoints = Map; +/** + * Defines the default media queries for Webflow's breakpoints. + */ export declare const WEBFLOW_BREAKPOINTS: WebflowBreakpoints; export {}; diff --git a/dist/webflow/breakpoints.js b/dist/webflow/breakpoints.js index 5528f49..65936e2 100644 --- a/dist/webflow/breakpoints.js +++ b/dist/webflow/breakpoints.js @@ -1,3 +1,6 @@ +/** + * Defines the default media queries for Webflow's breakpoints. + */ export const WEBFLOW_BREAKPOINTS = new Map([ ['tiny', '(max-width: 479px)'], ['small', '(max-width: 767px)'], diff --git a/dist/webflow/closeDropdown.d.ts b/dist/webflow/closeDropdown.d.ts index 077bd55..ff5a74a 100644 --- a/dist/webflow/closeDropdown.d.ts +++ b/dist/webflow/closeDropdown.d.ts @@ -1,2 +1,7 @@ import type { DropdownToggle } from './WebflowElements'; +/** + * Closes a dropdown. + * @param dropdownToggle A {@link DropdownToggle} element. + * @param focusToggle Defaults to `true`. + */ export declare const closeDropdown: (dropdownToggle: DropdownToggle, focusToggle?: boolean) => void; diff --git a/dist/webflow/closeDropdown.js b/dist/webflow/closeDropdown.js index b2865f0..b6e932f 100644 --- a/dist/webflow/closeDropdown.js +++ b/dist/webflow/closeDropdown.js @@ -1,4 +1,9 @@ import { simulateEvent } from '../helpers'; +/** + * Closes a dropdown. + * @param dropdownToggle A {@link DropdownToggle} element. + * @param focusToggle Defaults to `true`. + */ export const closeDropdown = (dropdownToggle, focusToggle = true) => { if (focusToggle) dropdownToggle.focus(); diff --git a/dist/webflow/getCollectionElements.d.ts b/dist/webflow/getCollectionElements.d.ts index 86a1d24..e4a4c7c 100644 --- a/dist/webflow/getCollectionElements.d.ts +++ b/dist/webflow/getCollectionElements.d.ts @@ -1,4 +1,12 @@ import type { CollectionEmptyElement, CollectionItemElement, CollectionListElement, CollectionListWrapperElement, PageCountElement, PaginationButtonElement, PaginationWrapperElement } from '..'; +/** + * This helper is intended to allow users setting the selectors to either the `Collection List Wrapper` or the `Collection List` elements. + * This way there will never be any misunderstanding about the setup. + * @param reference The element or selector of the element. + * @param target The requested element/elements. It can be either the `Collection List Wrapper`, the `Collection List` or all the `Collection Item` elements. + * @param page The page document. + * @returns The specified collection element/elements. + */ export declare function getCollectionElements(reference: string | Element, target: 'pageCount', page?: Document): PageCountElement | null | undefined; export declare function getCollectionElements(reference: string | Element, target: 'next' | 'previous', page?: Document): PaginationButtonElement | null | undefined; export declare function getCollectionElements(reference: string | Element, target: 'pagination', page?: Document): PaginationWrapperElement | null | undefined; diff --git a/dist/webflow/getCollectionListWrappers.d.ts b/dist/webflow/getCollectionListWrappers.d.ts index 5de1840..7c868d3 100644 --- a/dist/webflow/getCollectionListWrappers.d.ts +++ b/dist/webflow/getCollectionListWrappers.d.ts @@ -1,2 +1,8 @@ import type { CollectionListWrapperElement } from '..'; +/** + * Queries `Collection List Wrapper` elements and makes sure they are unique. + * @param selectors The selectors used for the query. If an empty array is provided, all `Collection List Wrapper` elements will be returned. + * @param page The document where to perform the query. + * @returns A unique list of `Collection List Wrapper` elements. + */ export declare const getCollectionListWrappers: (selectors: Array, page?: Document) => CollectionListWrapperElement[]; diff --git a/dist/webflow/getCollectionListWrappers.js b/dist/webflow/getCollectionListWrappers.js index eff8fff..1d1b865 100644 --- a/dist/webflow/getCollectionListWrappers.js +++ b/dist/webflow/getCollectionListWrappers.js @@ -1,5 +1,12 @@ import { CMS_CSS_CLASSES, getCollectionElements } from '.'; +/** + * Queries `Collection List Wrapper` elements and makes sure they are unique. + * @param selectors The selectors used for the query. If an empty array is provided, all `Collection List Wrapper` elements will be returned. + * @param page The document where to perform the query. + * @returns A unique list of `Collection List Wrapper` elements. + */ export const getCollectionListWrappers = (selectors, page = document) => { + // Make sure the selectors are valid. selectors = selectors.filter((selector) => selector); const selector = selectors.join(', ') || `.${CMS_CSS_CLASSES.wrapper}`; const referenceElements = [...page.querySelectorAll(selector)]; diff --git a/dist/webflow/getCurrentBreakpoint.d.ts b/dist/webflow/getCurrentBreakpoint.d.ts index 8aaeefa..ab9972d 100644 --- a/dist/webflow/getCurrentBreakpoint.d.ts +++ b/dist/webflow/getCurrentBreakpoint.d.ts @@ -1,2 +1,7 @@ import type { WebflowBreakpoint } from './breakpoints'; +/** + * Checks the current breakpoint based on the window media. + * + * @returns A {@link WebflowBreakpoint} string. + */ export declare const getCurrentBreakpoint: () => WebflowBreakpoint; diff --git a/dist/webflow/getCurrentBreakpoint.js b/dist/webflow/getCurrentBreakpoint.js index 9d61882..d218340 100644 --- a/dist/webflow/getCurrentBreakpoint.js +++ b/dist/webflow/getCurrentBreakpoint.js @@ -1,4 +1,9 @@ import { WEBFLOW_BREAKPOINTS } from './breakpoints'; +/** + * Checks the current breakpoint based on the window media. + * + * @returns A {@link WebflowBreakpoint} string. + */ export const getCurrentBreakpoint = () => { for (const [breakpoint, mediaQuery] of WEBFLOW_BREAKPOINTS) { if (window.matchMedia(mediaQuery).matches) { diff --git a/dist/webflow/getPublishDate.d.ts b/dist/webflow/getPublishDate.d.ts index 4c9467c..1818b9a 100644 --- a/dist/webflow/getPublishDate.d.ts +++ b/dist/webflow/getPublishDate.d.ts @@ -1 +1,5 @@ +/** + * Extracts the publish date of a Webflow site + * @returns A Date object, if found + */ export declare const getPublishDate: () => Date | undefined; diff --git a/dist/webflow/getPublishDate.js b/dist/webflow/getPublishDate.js index a2d749d..b3b8fb0 100644 --- a/dist/webflow/getPublishDate.js +++ b/dist/webflow/getPublishDate.js @@ -1,3 +1,7 @@ +/** + * Extracts the publish date of a Webflow site + * @returns A Date object, if found + */ export const getPublishDate = () => { const publishDatePrefix = 'Last Published:'; for (const node of document.childNodes) { diff --git a/dist/webflow/getSiteId.d.ts b/dist/webflow/getSiteId.d.ts index f9d65a5..df5c323 100644 --- a/dist/webflow/getSiteId.d.ts +++ b/dist/webflow/getSiteId.d.ts @@ -1 +1,4 @@ +/** + * @returns The Webflow Site ID of the website + */ export declare const getSiteId: () => string | null; diff --git a/dist/webflow/getSiteId.js b/dist/webflow/getSiteId.js index dabdcda..f04cb9b 100644 --- a/dist/webflow/getSiteId.js +++ b/dist/webflow/getSiteId.js @@ -1 +1,4 @@ +/** + * @returns The Webflow Site ID of the website + */ export const getSiteId = () => document.documentElement.getAttribute('data-wf-site'); diff --git a/dist/webflow/restartWebflow.d.ts b/dist/webflow/restartWebflow.d.ts index 04bae8f..53f5571 100644 --- a/dist/webflow/restartWebflow.d.ts +++ b/dist/webflow/restartWebflow.d.ts @@ -1,2 +1,9 @@ import type { WebflowModule } from './Webflow'; -export declare const restartWebflow: (modules?: WebflowModule[] | undefined) => Promise; +/** + * Restarts the Webflow JS library. + * + * @param modules An array of {@link WebflowModule} to restart. If passed, only those modules will be restarted instead of the whole `Webflow` instance. + * + * @returns An awaitable promise that is fulfilled when the library has been correctly reinitialized. + */ +export declare const restartWebflow: (modules?: WebflowModule[]) => Promise; diff --git a/dist/webflow/restartWebflow.js b/dist/webflow/restartWebflow.js index 5696553..334104d 100644 --- a/dist/webflow/restartWebflow.js +++ b/dist/webflow/restartWebflow.js @@ -1,14 +1,23 @@ import { getSiteId } from '.'; +/** + * Restarts the Webflow JS library. + * + * @param modules An array of {@link WebflowModule} to restart. If passed, only those modules will be restarted instead of the whole `Webflow` instance. + * + * @returns An awaitable promise that is fulfilled when the library has been correctly reinitialized. + */ export const restartWebflow = async (modules) => { const { Webflow } = window; if (!Webflow || !('destroy' in Webflow) || !('ready' in Webflow) || !('require' in Webflow)) return; if (modules && !modules.length) return; + // Global if (!modules) { Webflow.destroy(); Webflow.ready(); } + // IX2 if (!modules || modules.includes('ix2')) { const ix2 = Webflow.require('ix2'); if (ix2) { @@ -21,6 +30,7 @@ export const restartWebflow = async (modules) => { await Promise.all(stateEntries.map((state) => store.dispatch(actions.eventStateChanged(...state)))); } } + // Commerce if (!modules || modules.includes('commerce')) { const commerce = Webflow.require('commerce'); const siteId = getSiteId(); @@ -29,10 +39,13 @@ export const restartWebflow = async (modules) => { commerce.init({ siteId, apiUrl: 'https://render.webflow.com' }); } } + // Lightbox if (modules?.includes('lightbox')) Webflow.require('lightbox')?.ready(); + // Slider if (modules?.includes('slider')) Webflow.require('slider')?.redraw(); + // Tabs if (modules?.includes('tabs')) Webflow.require('tabs')?.redraw(); return new Promise((resolve) => Webflow.push(() => resolve(undefined))); diff --git a/package.json b/package.json index 0d9360d..f00708d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@finsweet/ts-utils", - "version": "0.33.0", + "version": "0.33.1", "description": "Typescript utils for custom Webflow projects.", "type": "module", "main": "dist/index.js", diff --git a/tsconfig.json b/tsconfig.json index 8b475c5..6923c80 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - "removeComments": true /* Do not emit comments to output. */, + // "removeComments": true /* Do not emit comments to output. */, // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */,