@finsweet/webflow-apps-utils 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/stores/index.d.ts +1 -0
  2. package/dist/stores/index.js +1 -0
  3. package/dist/stores/isPreviewMode.d.ts +1 -0
  4. package/dist/stores/isPreviewMode.js +2 -0
  5. package/dist/types/dom.d.ts +1 -0
  6. package/dist/types/dom.js +1 -0
  7. package/dist/types/index.d.ts +1 -0
  8. package/dist/types/index.js +1 -0
  9. package/dist/types/webflow.d.ts +1 -1
  10. package/dist/ui/components/layout/Layout.svelte +4 -2
  11. package/dist/ui/components/layout/Layout.svelte.d.ts +2 -0
  12. package/dist/ui/components/text/Text.svelte +4 -2
  13. package/dist/ui/components/text/types.d.ts +22 -0
  14. package/dist/ui/icons/ChevronIcon.svelte +1 -1
  15. package/dist/utils/constants.d.ts +5 -0
  16. package/dist/utils/constants.js +11 -0
  17. package/dist/utils/helpers/dom.d.ts +37 -0
  18. package/dist/utils/helpers/dom.js +104 -0
  19. package/dist/utils/helpers/encodeDecodeConfigs.d.ts +13 -0
  20. package/dist/utils/helpers/encodeDecodeConfigs.js +20 -0
  21. package/dist/utils/helpers/events.d.ts +19 -0
  22. package/dist/utils/helpers/events.js +28 -0
  23. package/dist/utils/helpers/forms.d.ts +22 -0
  24. package/dist/utils/helpers/forms.js +82 -0
  25. package/dist/utils/helpers/guards.d.ts +124 -0
  26. package/dist/utils/helpers/guards.js +107 -0
  27. package/dist/utils/helpers/index.d.ts +8 -0
  28. package/dist/utils/helpers/index.js +8 -0
  29. package/dist/utils/helpers/parseCSV.d.ts +6 -0
  30. package/dist/utils/helpers/parseCSV.js +29 -0
  31. package/dist/utils/helpers/string.d.ts +23 -0
  32. package/dist/utils/helpers/string.js +33 -0
  33. package/dist/utils/helpers/wait.d.ts +13 -0
  34. package/dist/utils/helpers/wait.js +27 -0
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/index.js +1 -0
  37. package/dist/utils/webflow/CopyJSONButton.d.ts +54 -0
  38. package/dist/utils/webflow/CopyJSONButton.js +117 -0
  39. package/dist/utils/webflow/DisplayController.d.ts +55 -0
  40. package/dist/utils/webflow/DisplayController.js +91 -0
  41. package/dist/utils/webflow/Interaction.d.ts +47 -0
  42. package/dist/utils/webflow/Interaction.js +52 -0
  43. package/dist/utils/webflow/index.d.ts +4 -0
  44. package/dist/utils/webflow/index.js +4 -0
  45. package/dist/utils/webflow/webflow.d.ts +32 -0
  46. package/dist/utils/webflow/webflow.js +90 -0
  47. package/package.json +5 -6
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Check if value is a string
3
+ */
4
+ export const isString = (value) => typeof value === 'string';
5
+ /**
6
+ * Check if value is a number
7
+ */
8
+ export const isNumber = (value) => typeof value === 'number';
9
+ /**
10
+ * Check if value is a boolean
11
+ */
12
+ export const isBoolean = (value) => typeof value === 'boolean';
13
+ /**
14
+ * Check if value undefined
15
+ */
16
+ export const isUndefined = (value) => value === undefined;
17
+ /**
18
+ * Makes sure a value is not `null` or `undefined`.
19
+ * Useful for type safety when filtering empty elements from an array. Check out the example for more in-depth explanation.
20
+ * @param value The value to type-check.
21
+ * @example ```typescript
22
+ * const items = [1, null, 4, undefined, 8];
23
+ *
24
+ * const filteredItemsError: number[] = items.filter((item) => value !== undefined && value !== null); // Type '(number | null | undefined)[]' is not assignable to type 'number[]'.
25
+ *
26
+ * const filteredItemsSuccess: number[] = items.filter(isNotEmpty); // Success!
27
+ * ```
28
+ */
29
+ export const isNotEmpty = (value) => value !== undefined && value !== null;
30
+ /**
31
+ * Check if a key is included in a readonly array
32
+ * @param key
33
+ * @param source readonly array of strings
34
+ * @returns True/false
35
+ */
36
+ export const isKeyOf = (key, source) => !!key && source.includes(key);
37
+ /**
38
+ * Gets the keys of an object with inferred typing.
39
+ * @param object
40
+ * @returns
41
+ */
42
+ export const getObjectKeys = (object) => Object.keys(object);
43
+ /**
44
+ * Gets type safe `Object.entries()`.
45
+ * @param object
46
+ */
47
+ export const getObjectEntries = (object) => Object.entries(object);
48
+ /**
49
+ * @returns `true` if the target is an instance of Element type.
50
+ * @param target
51
+ */
52
+ export const isElement = (target) => target instanceof Element;
53
+ /**
54
+ * @returns `true` if the target is an instance of HTMLElement type.
55
+ * @param target
56
+ */
57
+ export const isHTMLElement = (target) => target instanceof HTMLElement;
58
+ /**
59
+ * @returns `true` if the target is an instance of HTMLVideoElement type.
60
+ * @param target
61
+ */
62
+ export const isHTMLVideoElement = (target) => target instanceof HTMLVideoElement;
63
+ /**
64
+ * @returns `true` if the target is an instance of HTMLInputElement type.
65
+ * @param target
66
+ */
67
+ export const isHTMLInputElement = (target) => target instanceof HTMLInputElement;
68
+ /**
69
+ * @returns `true` if the target is an instance of HTMLSelectElement type.
70
+ * @param target
71
+ */
72
+ export const isHTMLSelectElement = (target) => target instanceof HTMLSelectElement;
73
+ /**
74
+ * @returns `true` if the target is an instance of HTMLTextAreaElement type.
75
+ * @param target
76
+ */
77
+ export const isHTMLTextAreaElement = (target) => target instanceof HTMLTextAreaElement;
78
+ /**
79
+ * Checks if an element is a form field element
80
+ * @param element
81
+ */
82
+ export const isFormField = (element) => isHTMLInputElement(element) || isHTMLSelectElement(element) || isHTMLTextAreaElement(element);
83
+ /**
84
+ * @returns `true` if the target is an instance of HTMLAnchorElement type.
85
+ * @param target
86
+ */
87
+ export const isHTMLAnchorElement = (target) => target instanceof HTMLAnchorElement;
88
+ /**
89
+ * @returns `true` if the target is an instance of HTMLOptionElement type.
90
+ * @param target
91
+ */
92
+ export const isHTMLOptionElement = (target) => target instanceof HTMLOptionElement;
93
+ /**
94
+ * @returns `true` if the target is an instance of HTMLImageElement type.
95
+ * @param target
96
+ */
97
+ export const isHTMLImageElement = (target) => target instanceof HTMLImageElement;
98
+ /**
99
+ * @returns `true` if the target is an instance of HTMLButtonElement type.
100
+ * @param target
101
+ */
102
+ export const isHTMLButtonElement = (target) => target instanceof HTMLButtonElement;
103
+ /**
104
+ * @returns `true` if the target is an instance of File type.
105
+ * @param target
106
+ */
107
+ export const isFile = (target) => target instanceof File;
@@ -1,10 +1,18 @@
1
1
  export * from './capitalizeFirstLetter';
2
2
  export * from './cleanupTooltipMessage';
3
+ export * from './encodeDecodeConfigs';
3
4
  export * from './goto';
5
+ export * from './dom';
6
+ export * from './events';
7
+ export * from './forms';
4
8
  export * from './getTimeNow';
5
9
  export * from './minifyCode';
6
10
  export * from './noop';
11
+ export * from './guards';
7
12
  export * from './numbers';
13
+ export * from './parseCSV';
14
+ export * from './string';
8
15
  export * from './objectsToModuleExports';
9
16
  export * from './trimText';
10
17
  export * from './toHumanReadableList';
18
+ export * from './wait';
@@ -1,10 +1,18 @@
1
1
  export * from './capitalizeFirstLetter';
2
2
  export * from './cleanupTooltipMessage';
3
+ export * from './encodeDecodeConfigs';
3
4
  export * from './goto';
5
+ export * from './dom';
6
+ export * from './events';
7
+ export * from './forms';
4
8
  export * from './getTimeNow';
5
9
  export * from './minifyCode';
6
10
  export * from './noop';
11
+ export * from './guards';
7
12
  export * from './numbers';
13
+ export * from './parseCSV';
14
+ export * from './string';
8
15
  export * from './objectsToModuleExports';
9
16
  export * from './trimText';
10
17
  export * from './toHumanReadableList';
18
+ export * from './wait';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Parse CSV data
3
+ * @param csvText CSV data as string
4
+ * @returns Parsed CSV data as an array of objects
5
+ */
6
+ export declare const parseCSV: <Result extends Record<string, string>>(csvText: string) => Promise<Result[]>;
@@ -0,0 +1,29 @@
1
+ import { parse } from 'csv-parse/browser/esm';
2
+ /**
3
+ * Parse CSV data
4
+ * @param csvText CSV data as string
5
+ * @returns Parsed CSV data as an array of objects
6
+ */
7
+ export const parseCSV = async (csvText) => {
8
+ return new Promise((resolve, reject) => {
9
+ const results = [];
10
+ parse(csvText, {
11
+ columns: true,
12
+ skip_empty_lines: true,
13
+ trim: true
14
+ })
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ .on('readable', function () {
17
+ let record;
18
+ while ((record = this.read()) !== null) {
19
+ results.push(record);
20
+ }
21
+ })
22
+ .on('error', (error) => {
23
+ reject(error);
24
+ })
25
+ .on('end', () => {
26
+ resolve(results);
27
+ });
28
+ });
29
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Removes the trailing slash from a URL string.
3
+ *
4
+ * @example
5
+ * ```
6
+ * This:
7
+ * https://www.finsweet.com/attributes/attractions/capri-island/
8
+ *
9
+ * Becomes:
10
+ * https://www.finsweet.com/attributes/attractions/capri-island
11
+ * ```
12
+ *
13
+ * @param value The value to mutate.
14
+ * @returns A new string without a trailing slash.
15
+ */
16
+ export declare const removeTrailingSlash: (value: string) => string;
17
+ /**
18
+ * Convert a string of comma separated values to an array of values.
19
+ *
20
+ * @param string Comma separated string.
21
+ * @param filterEmpty Defines if empty values should be filtered out of the returned array. Defaults to `true`.
22
+ */
23
+ export declare const extractCommaSeparatedValues: (string: string | null | undefined, filterEmpty?: boolean) => string[];
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Removes the trailing slash from a URL string.
3
+ *
4
+ * @example
5
+ * ```
6
+ * This:
7
+ * https://www.finsweet.com/attributes/attractions/capri-island/
8
+ *
9
+ * Becomes:
10
+ * https://www.finsweet.com/attributes/attractions/capri-island
11
+ * ```
12
+ *
13
+ * @param value The value to mutate.
14
+ * @returns A new string without a trailing slash.
15
+ */
16
+ export const removeTrailingSlash = (value) => value.replace(/\/+$/, '');
17
+ /**
18
+ * Convert a string of comma separated values to an array of values.
19
+ *
20
+ * @param string Comma separated string.
21
+ * @param filterEmpty Defines if empty values should be filtered out of the returned array. Defaults to `true`.
22
+ */
23
+ export const extractCommaSeparatedValues = (string, filterEmpty = true) => {
24
+ if (!string)
25
+ return [];
26
+ const items = string.split(',').reduce((accumulatedValue, currentValue) => {
27
+ const value = currentValue.trim();
28
+ if (!filterEmpty || value)
29
+ accumulatedValue.push(value);
30
+ return accumulatedValue;
31
+ }, []);
32
+ return items;
33
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @returns Awaitable promise for waiting X time.
3
+ * @param time
4
+ */
5
+ export declare const wait: (time: number) => Promise<unknown>;
6
+ /**
7
+ * @returns A promise that resolves once Webflow has fully loaded.
8
+ */
9
+ export declare const waitWebflowReady: () => Promise<unknown>;
10
+ /**
11
+ * @returns A promise that resolves once the DOM is ready.
12
+ */
13
+ export declare const waitDOMReady: () => Promise<unknown>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @returns Awaitable promise for waiting X time.
3
+ * @param time
4
+ */
5
+ export const wait = (time) => new Promise((resolve) => setTimeout(resolve, time));
6
+ /**
7
+ * @returns A promise that resolves once Webflow has fully loaded.
8
+ */
9
+ export const waitWebflowReady = async () => {
10
+ return new Promise((resolve) => {
11
+ window.Webflow ||= [];
12
+ window.Webflow.push(resolve);
13
+ });
14
+ };
15
+ /**
16
+ * @returns A promise that resolves once the DOM is ready.
17
+ */
18
+ export const waitDOMReady = async () => {
19
+ return new Promise((resolve) => {
20
+ if (document.readyState === 'loading') {
21
+ document.addEventListener('DOMContentLoaded', resolve);
22
+ }
23
+ else {
24
+ resolve(undefined);
25
+ }
26
+ });
27
+ };
@@ -7,4 +7,5 @@ export * from './custom-code';
7
7
  export * from './diff-mapper';
8
8
  export * from './helpers';
9
9
  export * from './logger';
10
+ export * from './webflow';
10
11
  export * from './webflow-canvas';
@@ -7,4 +7,5 @@ export * from './custom-code';
7
7
  export * from './diff-mapper';
8
8
  export * from './helpers';
9
9
  export * from './logger';
10
+ export * from './webflow';
10
11
  export * from './webflow-canvas';
@@ -0,0 +1,54 @@
1
+ export declare class CopyJSONButton {
2
+ private readonly element;
3
+ private readonly hiddenTrigger;
4
+ private readonly successCSSClass?;
5
+ private readonly textNode;
6
+ private copyData;
7
+ private successText;
8
+ private errorText;
9
+ private notificationDuration;
10
+ private notificationActive;
11
+ private originalText;
12
+ constructor({ element, copyData, successText, errorText, notificationDuration, successCSSClass }: {
13
+ element: HTMLElement;
14
+ copyData: Record<string, unknown>;
15
+ successText?: string;
16
+ errorText?: string;
17
+ notificationDuration?: number;
18
+ successCSSClass?: string;
19
+ });
20
+ /**
21
+ * Inits the component.
22
+ */
23
+ private init;
24
+ /**
25
+ * Creates a hidden button that will serve as the copy trigger.
26
+ * @returns The new button element.
27
+ */
28
+ private createHiddenTrigger;
29
+ /**
30
+ * Handles click events: triggers a copy command on the element.
31
+ */
32
+ private handleClick;
33
+ /**
34
+ * Handles the copy event, transfers the JSON data to the user's clipboard.
35
+ * @param e
36
+ */
37
+ private handleCopy;
38
+ /**
39
+ * Triggers a `success`/`error` notification on the button.
40
+ * If the `successCSSClass` is specific, it adds/removes on the button.
41
+ * @param state `success` or `error`
42
+ */
43
+ private triggerNotification;
44
+ /**
45
+ * Updates the JSON data to be copied.
46
+ * @param newCopyData
47
+ */
48
+ updateCopyData(newCopyData: Record<string, unknown>): void;
49
+ /**
50
+ * Updates the button's text content.
51
+ * @param newText The new text to be displayed.
52
+ */
53
+ updateTextContent(newText: string): void;
54
+ }
@@ -0,0 +1,117 @@
1
+ import { findTextNode } from '../helpers';
2
+ export class CopyJSONButton {
3
+ element;
4
+ hiddenTrigger;
5
+ successCSSClass;
6
+ textNode;
7
+ copyData;
8
+ successText = 'Copied!';
9
+ errorText = 'Something went wrong';
10
+ notificationDuration = 500;
11
+ notificationActive = false;
12
+ originalText;
13
+ constructor({ element, copyData, successText, errorText, notificationDuration, successCSSClass }) {
14
+ this.element = element;
15
+ this.copyData = copyData;
16
+ if (successText)
17
+ this.successText = successText;
18
+ if (errorText)
19
+ this.errorText = errorText;
20
+ if (notificationDuration)
21
+ this.notificationDuration = notificationDuration;
22
+ if (successCSSClass)
23
+ this.successCSSClass = successCSSClass;
24
+ this.textNode = findTextNode(element) || element;
25
+ this.originalText = this.textNode.textContent || '';
26
+ this.hiddenTrigger = this.createHiddenTrigger();
27
+ this.init();
28
+ }
29
+ /**
30
+ * Inits the component.
31
+ */
32
+ init() {
33
+ const { element, hiddenTrigger } = this;
34
+ element.addEventListener('click', (e) => this.handleClick(e));
35
+ hiddenTrigger.addEventListener('copy', (e) => this.handleCopy(e));
36
+ }
37
+ /**
38
+ * Creates a hidden button that will serve as the copy trigger.
39
+ * @returns The new button element.
40
+ */
41
+ createHiddenTrigger() {
42
+ const { element } = this;
43
+ const button = document.createElement('button');
44
+ button.contentEditable = 'true';
45
+ Object.assign(button.style, {
46
+ position: 'absolute',
47
+ clip: 'rect(1px, 1px, 1px, 1px)',
48
+ clipPath: 'inset(0px 0px 99.9% 99.9%)',
49
+ overflow: 'hidden',
50
+ height: '1px',
51
+ width: '1px',
52
+ padding: '0',
53
+ border: '0'
54
+ });
55
+ (element.parentElement || document.body).appendChild(button);
56
+ return button;
57
+ }
58
+ /**
59
+ * Handles click events: triggers a copy command on the element.
60
+ */
61
+ handleClick(e) {
62
+ e.preventDefault();
63
+ this.hiddenTrigger.focus();
64
+ document.execCommand('copy');
65
+ }
66
+ /**
67
+ * Handles the copy event, transfers the JSON data to the user's clipboard.
68
+ * @param e
69
+ */
70
+ handleCopy(e) {
71
+ try {
72
+ // Copy starter form JSON to clipboard
73
+ e.clipboardData?.setData('application/json', JSON.stringify(this.copyData).trim());
74
+ e.preventDefault();
75
+ // Trigger notification
76
+ this.triggerNotification('success');
77
+ }
78
+ catch {
79
+ this.triggerNotification('error');
80
+ }
81
+ }
82
+ /**
83
+ * Triggers a `success`/`error` notification on the button.
84
+ * If the `successCSSClass` is specific, it adds/removes on the button.
85
+ * @param state `success` or `error`
86
+ */
87
+ triggerNotification(state) {
88
+ const { notificationActive, notificationDuration, originalText, element, successCSSClass, successText, errorText } = this;
89
+ if (notificationActive)
90
+ return;
91
+ this.notificationActive = true;
92
+ this.textNode.textContent = state === 'success' ? successText : errorText;
93
+ if (successCSSClass)
94
+ element.classList.add(successCSSClass);
95
+ window.setTimeout(() => {
96
+ this.textNode.textContent = originalText;
97
+ if (successCSSClass)
98
+ element.classList.remove(successCSSClass);
99
+ this.notificationActive = false;
100
+ }, notificationDuration);
101
+ }
102
+ /**
103
+ * Updates the JSON data to be copied.
104
+ * @param newCopyData
105
+ */
106
+ updateCopyData(newCopyData) {
107
+ this.copyData = newCopyData;
108
+ }
109
+ /**
110
+ * Updates the button's text content.
111
+ * @param newText The new text to be displayed.
112
+ */
113
+ updateTextContent(newText) {
114
+ this.textNode.textContent = newText;
115
+ this.originalText = newText;
116
+ }
117
+ }
@@ -0,0 +1,55 @@
1
+ import { animations, type Easings } from '../animations';
2
+ import { type InteractionParams } from './Interaction';
3
+ export interface DisplayControllerParams {
4
+ /**
5
+ * The main element. Accepts both an HTMLElement or a string selector.
6
+ */
7
+ element: HTMLElement;
8
+ /**
9
+ * If the display must be controlled through a Webflow interaction.
10
+ */
11
+ interaction?: InteractionParams;
12
+ /**
13
+ * Defines a custom animation to be used when showing/hiding the element.
14
+ */
15
+ animation?: keyof typeof animations;
16
+ /**
17
+ * If set to true, the element will be set to `display: none`.
18
+ */
19
+ startsHidden?: boolean;
20
+ /**
21
+ * The duration of the animation in milliseconds.
22
+ */
23
+ animationDuration?: number;
24
+ /**
25
+ * The easing of the animation.
26
+ */
27
+ animationEasing: Easings[number];
28
+ }
29
+ /**
30
+ * Controls showing/hiding an element.
31
+ * Works with Webflow interactions, built-in fade animations or no animations at all.
32
+ */
33
+ export declare class DisplayController {
34
+ private readonly interaction;
35
+ private readonly animation;
36
+ private readonly animationEasing;
37
+ private readonly animationDuration;
38
+ private visible;
39
+ readonly element: HTMLElement;
40
+ constructor({ element, interaction, animation, startsHidden, animationEasing, animationDuration }: DisplayControllerParams);
41
+ /**
42
+ * @returns If the element is visible
43
+ */
44
+ isVisible: () => boolean;
45
+ /**
46
+ * Displays the element
47
+ * @returns An awaitable promise
48
+ */
49
+ show(): Promise<void>;
50
+ /**
51
+ * Hides the element
52
+ * @returns An awaitable promise
53
+ */
54
+ hide(): Promise<void>;
55
+ }
@@ -0,0 +1,91 @@
1
+ import { animations } from '../animations';
2
+ import { isVisible } from '../helpers';
3
+ import { Interaction } from './Interaction';
4
+ /**
5
+ * Controls showing/hiding an element.
6
+ * Works with Webflow interactions, built-in fade animations or no animations at all.
7
+ */
8
+ export class DisplayController {
9
+ interaction;
10
+ animation;
11
+ animationEasing;
12
+ animationDuration;
13
+ visible;
14
+ element;
15
+ constructor({ element, interaction, animation, startsHidden, animationEasing, animationDuration }) {
16
+ // Store properties
17
+ this.element = element;
18
+ this.animation = animation;
19
+ this.animationEasing = animationEasing;
20
+ this.animationDuration = animationDuration;
21
+ // Visibility check
22
+ if (startsHidden) {
23
+ this.element.style.display = 'none';
24
+ this.visible = false;
25
+ }
26
+ else
27
+ this.visible = isVisible(this.element);
28
+ if (interaction) {
29
+ const { element, duration } = interaction;
30
+ this.interaction = new Interaction({ element, duration });
31
+ }
32
+ }
33
+ /**
34
+ * @returns If the element is visible
35
+ */
36
+ isVisible = () => this.visible;
37
+ /**
38
+ * Displays the element
39
+ * @returns An awaitable promise
40
+ */
41
+ async show() {
42
+ if (this.visible)
43
+ return;
44
+ const { interaction, animation, element, animationDuration, animationEasing } = this;
45
+ const display = 'block';
46
+ // Interaction
47
+ if (interaction) {
48
+ await interaction.trigger('first');
49
+ }
50
+ // Animation
51
+ else if (animation) {
52
+ animations[animation].prepareIn(element, { display });
53
+ await animations[animation].animateIn(element, {
54
+ display,
55
+ duration: animationDuration,
56
+ easing: animationEasing
57
+ });
58
+ }
59
+ // No interaction or animation
60
+ else {
61
+ element.style.display = display;
62
+ }
63
+ this.visible = true;
64
+ }
65
+ /**
66
+ * Hides the element
67
+ * @returns An awaitable promise
68
+ */
69
+ async hide() {
70
+ if (!this.visible)
71
+ return;
72
+ const { interaction, animation, element, animationDuration, animationEasing } = this;
73
+ // Interaction
74
+ if (interaction) {
75
+ await interaction.trigger('second');
76
+ }
77
+ // Animation
78
+ else if (animation) {
79
+ await animations[animation].animateOut(element, {
80
+ display: 'none',
81
+ duration: animationDuration,
82
+ easing: animationEasing
83
+ });
84
+ }
85
+ // No interaction or animation
86
+ else {
87
+ element.style.display = 'none';
88
+ }
89
+ this.visible = false;
90
+ }
91
+ }
@@ -0,0 +1,47 @@
1
+ export interface InteractionParams {
2
+ /**
3
+ * The element that has a Webflow Ix2 Click interaction binded to it.
4
+ */
5
+ element: HTMLElement | string;
6
+ /**
7
+ * The duration of the interaction.
8
+ * If a single number is passed, it will be used for both first and second interactions.
9
+ * If an object is passed, you can specify the duration for each interaction.
10
+ */
11
+ duration?: number | Partial<Interaction['duration']>;
12
+ }
13
+ export declare class Interaction {
14
+ private readonly element;
15
+ private active;
16
+ private running;
17
+ private runningPromise?;
18
+ readonly duration: {
19
+ first: number;
20
+ second: number;
21
+ };
22
+ /**
23
+ * Acts as the controller for a Webflow Interaction.
24
+ * It accepts an element that will be clicked when required (firing a Mouse Click interaction).
25
+ * @param element Element that has the Mouse Click interaction.
26
+ * @param duration Optionally, the duration can be explicitly set so the trigger methods will return an awaitable Promise.
27
+ */
28
+ constructor({ element, duration }: InteractionParams);
29
+ /**
30
+ * Trigger the interaction
31
+ * @param click Perform first or second click
32
+ * @returns True if the interaction was fired
33
+ */
34
+ trigger(click?: 'first' | 'second'): Promise<boolean>;
35
+ /**
36
+ * @returns If the interaction is active
37
+ */
38
+ isActive: () => boolean;
39
+ /**
40
+ * @returns If the interaction is running
41
+ */
42
+ isRunning: () => boolean;
43
+ /**
44
+ * @returns A promise that fulfills when the current running interaction has finished
45
+ */
46
+ untilFinished: () => Promise<unknown> | undefined;
47
+ }