@finsweet/webflow-apps-utils 1.0.6 → 1.0.8

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 (151) hide show
  1. package/dist/index.d.ts +0 -3
  2. package/dist/index.js +0 -3
  3. package/dist/types/dom.d.ts +1 -0
  4. package/dist/types/dom.js +1 -0
  5. package/dist/types/index.d.ts +1 -0
  6. package/dist/types/index.js +1 -0
  7. package/dist/types/webflow.d.ts +1 -1
  8. package/dist/ui/components/layout/Layout.svelte +4 -3
  9. package/dist/ui/components/layout/Layout.svelte.d.ts +2 -0
  10. package/dist/ui/components/layout/common/EditModeMessage.svelte +1 -1
  11. package/dist/ui/components/layout/examples/ExampleLayout.svelte +1 -1
  12. package/dist/ui/components/layout/examples/Wrapper.svelte +1 -1
  13. package/dist/ui/components/text/Text.svelte +4 -2
  14. package/dist/ui/components/text/types.d.ts +22 -0
  15. package/dist/ui/icons/ChevronIcon.svelte +1 -1
  16. package/dist/ui/index.d.ts +4 -0
  17. package/dist/ui/index.js +4 -0
  18. package/dist/{providers → ui/providers}/GlobalProvider.stories.js +7 -7
  19. package/dist/{providers → ui/providers}/GlobalProvider.svelte +1 -1
  20. package/dist/{router → ui/router}/providers/RouterProvider.svelte +1 -1
  21. package/dist/{router → ui/router}/router.svelte.d.ts +0 -1
  22. package/dist/{router → ui/router}/router.svelte.js +3 -2
  23. package/dist/{stores → ui/stores}/forms/Form.stories.js +5 -5
  24. package/dist/{stores → ui/stores}/forms/FormDemo.svelte +1 -1
  25. package/dist/{stores → ui/stores}/index.d.ts +1 -2
  26. package/dist/{stores → ui/stores}/index.js +1 -2
  27. package/dist/ui/utils/api/checkIfAppModeIsDesign.d.ts +4 -0
  28. package/dist/ui/utils/api/checkIfAppModeIsDesign.js +19 -0
  29. package/dist/ui/utils/api/clipboard/handlePaste.d.ts +15 -0
  30. package/dist/ui/utils/api/clipboard/handlePaste.js +49 -0
  31. package/dist/ui/utils/api/clipboard/index.d.ts +1 -0
  32. package/dist/ui/utils/api/clipboard/index.js +1 -0
  33. package/dist/ui/utils/api/getAllAssets.d.ts +11 -0
  34. package/dist/ui/utils/api/getAllAssets.js +20 -0
  35. package/dist/ui/utils/api/getFinsweetComponentsEnvironment.d.ts +8 -0
  36. package/dist/ui/utils/api/getFinsweetComponentsEnvironment.js +66 -0
  37. package/dist/ui/utils/api/index.d.ts +5 -0
  38. package/dist/ui/utils/api/index.js +5 -0
  39. package/dist/ui/utils/api/insertWithXSCP.d.ts +4 -0
  40. package/dist/ui/utils/api/insertWithXSCP.js +12 -0
  41. package/dist/{utils → ui/utils}/auth/crossWindowLogin.d.ts +1 -1
  42. package/dist/{utils → ui/utils}/auth/crossWindowLogin.js +1 -1
  43. package/dist/{utils → ui/utils}/auth/index.d.ts +1 -1
  44. package/dist/{utils → ui/utils}/auth/index.js +4 -6
  45. package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.js +2 -2
  46. package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte +1 -1
  47. package/dist/{utils → ui/utils}/helpers/goto.js +2 -4
  48. package/dist/ui/utils/helpers/index.d.ts +1 -0
  49. package/dist/ui/utils/helpers/index.js +1 -0
  50. package/dist/ui/utils/index.d.ts +3 -0
  51. package/dist/ui/utils/index.js +3 -0
  52. package/dist/utils/constants.d.ts +5 -0
  53. package/dist/utils/constants.js +11 -0
  54. package/dist/utils/custom-code/api.d.ts +1 -1
  55. package/dist/utils/custom-code/api.js +4 -6
  56. package/dist/utils/custom-code/configs.d.ts +3 -2
  57. package/dist/utils/custom-code/configs.js +5 -8
  58. package/dist/utils/custom-code/index.d.ts +1 -1
  59. package/dist/utils/custom-code/index.js +1 -1
  60. package/dist/utils/helpers/dom.d.ts +37 -0
  61. package/dist/utils/helpers/dom.js +104 -0
  62. package/dist/utils/helpers/encodeDecodeConfigs.d.ts +13 -0
  63. package/dist/utils/helpers/encodeDecodeConfigs.js +20 -0
  64. package/dist/utils/helpers/events.d.ts +19 -0
  65. package/dist/utils/helpers/events.js +28 -0
  66. package/dist/utils/helpers/forms.d.ts +22 -0
  67. package/dist/utils/helpers/forms.js +82 -0
  68. package/dist/utils/helpers/guards.d.ts +124 -0
  69. package/dist/utils/helpers/guards.js +107 -0
  70. package/dist/utils/helpers/index.d.ts +8 -1
  71. package/dist/utils/helpers/index.js +8 -1
  72. package/dist/utils/helpers/parseCSV.d.ts +6 -0
  73. package/dist/utils/helpers/parseCSV.js +29 -0
  74. package/dist/utils/helpers/string.d.ts +23 -0
  75. package/dist/utils/helpers/string.js +33 -0
  76. package/dist/utils/helpers/wait.d.ts +13 -0
  77. package/dist/utils/helpers/wait.js +27 -0
  78. package/dist/utils/index.d.ts +3 -3
  79. package/dist/utils/index.js +2 -3
  80. package/dist/utils/logger/index.d.ts +1 -2
  81. package/dist/utils/stores/index.d.ts +2 -0
  82. package/dist/utils/stores/index.js +2 -0
  83. package/dist/utils/stores/isPreviewMode.d.ts +1 -0
  84. package/dist/utils/stores/isPreviewMode.js +2 -0
  85. package/dist/utils/webflow/CopyJSONButton.d.ts +54 -0
  86. package/dist/utils/webflow/CopyJSONButton.js +117 -0
  87. package/dist/utils/webflow/DisplayController.d.ts +55 -0
  88. package/dist/utils/webflow/DisplayController.js +91 -0
  89. package/dist/utils/webflow/Interaction.d.ts +47 -0
  90. package/dist/utils/webflow/Interaction.js +52 -0
  91. package/dist/utils/webflow/index.d.ts +4 -0
  92. package/dist/utils/webflow/index.js +4 -0
  93. package/dist/utils/webflow/webflow.d.ts +32 -0
  94. package/dist/utils/webflow/webflow.js +90 -0
  95. package/package.json +15 -7
  96. /package/dist/{providers → ui/providers}/GlobalProvider.stories.d.ts +0 -0
  97. /package/dist/{providers → ui/providers}/GlobalProvider.svelte.d.ts +0 -0
  98. /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte +0 -0
  99. /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte.d.ts +0 -0
  100. /package/dist/{providers → ui/providers}/configuratorUtils.d.ts +0 -0
  101. /package/dist/{providers → ui/providers}/configuratorUtils.js +0 -0
  102. /package/dist/{providers → ui/providers}/globalContext.svelte.d.ts +0 -0
  103. /package/dist/{providers → ui/providers}/globalContext.svelte.js +0 -0
  104. /package/dist/{providers → ui/providers}/index.d.ts +0 -0
  105. /package/dist/{providers → ui/providers}/index.js +0 -0
  106. /package/dist/{providers → ui/providers}/types.d.ts +0 -0
  107. /package/dist/{providers → ui/providers}/types.js +0 -0
  108. /package/dist/{router → ui/router}/Router.stories.d.ts +0 -0
  109. /package/dist/{router → ui/router}/Router.stories.js +0 -0
  110. /package/dist/{router → ui/router}/examples/RouterExample.svelte +0 -0
  111. /package/dist/{router → ui/router}/examples/RouterExample.svelte.d.ts +0 -0
  112. /package/dist/{router → ui/router}/examples/index.d.ts +0 -0
  113. /package/dist/{router → ui/router}/examples/index.js +0 -0
  114. /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte +0 -0
  115. /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte.d.ts +0 -0
  116. /package/dist/{router → ui/router}/examples/pages/HomePage.svelte +0 -0
  117. /package/dist/{router → ui/router}/examples/pages/HomePage.svelte.d.ts +0 -0
  118. /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte +0 -0
  119. /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte.d.ts +0 -0
  120. /package/dist/{router → ui/router}/hooks.svelte.d.ts +0 -0
  121. /package/dist/{router → ui/router}/hooks.svelte.js +0 -0
  122. /package/dist/{router → ui/router}/index.d.ts +0 -0
  123. /package/dist/{router → ui/router}/index.js +0 -0
  124. /package/dist/{router → ui/router}/providers/Link.svelte +0 -0
  125. /package/dist/{router → ui/router}/providers/Link.svelte.d.ts +0 -0
  126. /package/dist/{router → ui/router}/providers/Route.svelte +0 -0
  127. /package/dist/{router → ui/router}/providers/Route.svelte.d.ts +0 -0
  128. /package/dist/{router → ui/router}/providers/RouterProvider.svelte.d.ts +0 -0
  129. /package/dist/{router → ui/router}/providers/index.d.ts +0 -0
  130. /package/dist/{router → ui/router}/providers/index.js +0 -0
  131. /package/dist/{stores → ui/stores}/breakpoints.d.ts +0 -0
  132. /package/dist/{stores → ui/stores}/breakpoints.js +0 -0
  133. /package/dist/{stores → ui/stores}/componentInjectErrors.d.ts +0 -0
  134. /package/dist/{stores → ui/stores}/componentInjectErrors.js +0 -0
  135. /package/dist/{stores/forms.d.ts → ui/stores/form.d.ts} +0 -0
  136. /package/dist/{stores/forms.js → ui/stores/form.js} +0 -0
  137. /package/dist/{stores → ui/stores}/forms/Form.stories.d.ts +0 -0
  138. /package/dist/{stores → ui/stores}/forms/FormDemo.svelte.d.ts +0 -0
  139. /package/dist/{stores → ui/stores}/showConfirmActionModal.d.ts +0 -0
  140. /package/dist/{stores → ui/stores}/showConfirmActionModal.js +0 -0
  141. /package/dist/{stores → ui/stores}/siteInfo.d.ts +0 -0
  142. /package/dist/{stores → ui/stores}/siteInfo.js +0 -0
  143. /package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.d.ts +0 -0
  144. /package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte.d.ts +0 -0
  145. /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.d.ts +0 -0
  146. /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.js +0 -0
  147. /package/dist/{utils → ui/utils}/diff-mapper/index.d.ts +0 -0
  148. /package/dist/{utils → ui/utils}/diff-mapper/index.js +0 -0
  149. /package/dist/{utils → ui/utils}/helpers/goto.d.ts +0 -0
  150. /package/dist/{stores → utils/stores}/router.d.ts +0 -0
  151. /package/dist/{stores → utils/stores}/router.js +0 -0
@@ -1,4 +1,4 @@
1
- import { AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_LOGIN_URL, AUTH0_REDIRECT_URL, AUTH0_SCOPE, PROD_FINSWEEET_ACCOUNTS_ORIGIN } from '../constants';
1
+ import { AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_LOGIN_URL, AUTH0_REDIRECT_URL, AUTH0_SCOPE, PROD_FINSWEEET_ACCOUNTS_ORIGIN } from '../../../utils/constants';
2
2
  /**
3
3
  * Opens a popup window for cross-window authentication with Auth0.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { FinsweetAuth } from '../../types';
1
+ import type { FinsweetAuth } from '../../../types';
2
2
  /**
3
3
  * Store for the Finsweet user data.
4
4
  */
@@ -1,12 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  import Cookies from 'js-cookie';
3
3
  import { get, writable } from 'svelte/store';
4
+ import { getLocalStorage, removeLocalStorage, setLocalStorage } from '../../../utils';
5
+ import { FINSWEET_SUBSCRIPTIONS_ENDPOINT, FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING } from '../../../utils/constants';
4
6
  import { getFinsweetComponentsEnvironment } from '../api';
5
- import { getLocalStorage, removeLocalStorage, setLocalStorage } from '../browser-storage';
6
- import { FINSWEET_SUBSCRIPTIONS_ENDPOINT, FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING } from '../constants';
7
- import { getLogger } from '../logger';
8
7
  import { crossWindowLogin } from './crossWindowLogin';
9
- const logger = getLogger('webflow-apps-ui-utils');
10
8
  /**
11
9
  * Store for the Finsweet user data.
12
10
  */
@@ -51,7 +49,7 @@ export const getSubscriptions = async (token) => {
51
49
  return data;
52
50
  }
53
51
  catch (error) {
54
- logger.error({}, 'Failed to fetch subscriptions', error);
52
+ console.error('Failed to fetch subscriptions', error);
55
53
  return [];
56
54
  }
57
55
  };
@@ -95,7 +93,7 @@ export const handleLogin = async () => {
95
93
  }
96
94
  catch (error) {
97
95
  const err = error;
98
- logger.error({}, 'Login failed:', err.message);
96
+ console.error('Login failed:', err.message);
99
97
  finsweetUser.set(null);
100
98
  webflow.notify({
101
99
  type: 'Error',
@@ -131,7 +131,7 @@ Automatic cache cleanup when size exceeds 100 entries or TTL expires.
131
131
  The diff mapper is seamlessly integrated with the GlobalProvider system:
132
132
 
133
133
  \`\`\`typescript
134
- import { useConfiguratorContext } from '../../providers';
134
+ import { useConfiguratorContext } from '../../../providers';
135
135
 
136
136
  const configurator = useConfiguratorContext<MyConfigType>();
137
137
 
@@ -155,7 +155,7 @@ import {
155
155
  validateWatchOptions,
156
156
  extractKeys,
157
157
  createDebouncedUpdate
158
- } from '../../providers';
158
+ } from '../../../providers';
159
159
 
160
160
  // Create default configurator state
161
161
  const defaultState = createDefaultConfiguratorState<MyConfigType>();
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { getDetailedDiff, hasChangesViaDiff } from '../../providers/configuratorUtils';
2
+ import { getDetailedDiff, hasChangesViaDiff } from '../../providers';
3
3
 
4
4
  let output = '';
5
5
  let coercionExamples = '';
@@ -1,8 +1,6 @@
1
1
  import { get } from 'svelte/store';
2
2
  import { navigate } from 'svelte-routing';
3
- import { routerStore } from '../../stores';
4
- import { getLogger } from '../logger';
5
- const logger = getLogger('webflow-apps-ui-utils');
3
+ import { routerStore } from '../../../utils/stores';
6
4
  /**
7
5
  * Normalizes a URL path to ensure proper formatting.
8
6
  */
@@ -21,7 +19,7 @@ const normalizeUrlPath = (path, hash) => {
21
19
  export const goto = (path = '/', state = {}) => {
22
20
  const { hash = '' } = get(routerStore);
23
21
  if (!hash) {
24
- logger.error({}, 'goto method found no router hash in the router store. Contact Finsweet support.');
22
+ console.error('goto method found no router hash in the router store. Contact Finsweet support.');
25
23
  return;
26
24
  }
27
25
  const url = normalizeUrlPath(`/${hash}/${path}`, hash);
@@ -0,0 +1 @@
1
+ export * from './goto';
@@ -0,0 +1 @@
1
+ export * from './goto';
@@ -0,0 +1,3 @@
1
+ export * from './auth';
2
+ export * from './diff-mapper';
3
+ export * from './helpers';
@@ -0,0 +1,3 @@
1
+ export * from './auth';
2
+ export * from './diff-mapper';
3
+ export * from './helpers';
@@ -59,3 +59,8 @@ export declare const BRAND: {
59
59
  */
60
60
  export declare const FINSWEET_COMPONENTS_WEBFLOW_APP_ORIGINS: string[];
61
61
  export declare const ACCEPTED_WEBFLOW_ELEMENTS_FOR_INSERTION: string[];
62
+ /**
63
+ * List of domains that are considered staging.
64
+ */
65
+ export declare const STAGING_DOMAINS: string[];
66
+ export declare const FINSWEET_LOGO_URL = "https://cdn.prod.website-files.com/61819aaca0e7ac73f85a2d54/6865d68f194e84da9c6452e5_Components%20White%20Logo.svg";
@@ -71,3 +71,14 @@ export const ACCEPTED_WEBFLOW_ELEMENTS_FOR_INSERTION = [
71
71
  'Container',
72
72
  'BlockContainer'
73
73
  ];
74
+ /**
75
+ * List of domains that are considered staging.
76
+ */
77
+ export const STAGING_DOMAINS = [
78
+ 'webflow.io',
79
+ 'webflow-ext.com',
80
+ 'localhost',
81
+ 'canvas.webflow.com',
82
+ 'server.wized.com'
83
+ ];
84
+ export const FINSWEET_LOGO_URL = 'https://cdn.prod.website-files.com/61819aaca0e7ac73f85a2d54/6865d68f194e84da9c6452e5_Components%20White%20Logo.svg';
@@ -2,7 +2,7 @@ import type { CustomCodeBlock } from '../../types';
2
2
  /**
3
3
  * Gets stored Custom Code blocks by ID or returns all if no ID provided.
4
4
  */
5
- export declare const getCustomCode: (id?: string) => Promise<Array<CustomCodeBlock>>;
5
+ export declare const getCustomCode: (displayName?: string) => Promise<Array<CustomCodeBlock>>;
6
6
  /**
7
7
  * Sets custom code blocks in the site.
8
8
  */
@@ -1,17 +1,15 @@
1
- import { getLogger } from '../logger';
2
- const logger = getLogger('webflow-apps-ui-utils');
3
1
  /**
4
2
  * Gets stored Custom Code blocks by ID or returns all if no ID provided.
5
3
  */
6
- export const getCustomCode = async (id) => {
4
+ export const getCustomCode = async (displayName) => {
7
5
  //TODO: update this when typings are available plus any other place we have disabled this warning.
8
6
  //@ts-expect-error - not available in typings for now
9
7
  const customCodeBlock = (await webflow.getSiteCustomCode());
10
8
  if (!customCodeBlock || customCodeBlock.length === 0)
11
9
  return [];
12
- if (!id)
10
+ if (!displayName)
13
11
  return customCodeBlock;
14
- const storedConfigs = customCodeBlock.filter((block) => block.id === id);
12
+ const storedConfigs = customCodeBlock.filter((block) => block.id === displayName);
15
13
  if (storedConfigs)
16
14
  return storedConfigs;
17
15
  return [];
@@ -25,7 +23,7 @@ export const setCustomCode = async (customCodeBlock) => {
25
23
  await webflow.setSiteCustomCode(customCodeBlock);
26
24
  }
27
25
  catch (error) {
28
- logger.error({}, 'Failed to save custom code block', error, customCodeBlock);
26
+ console.error('Failed to save custom code block', error, customCodeBlock);
29
27
  }
30
28
  };
31
29
  /**
@@ -12,11 +12,12 @@ export type CustomCodeConfigsStore = {
12
12
  export declare const customCodeConfigsStore: import("svelte/store").Writable<CustomCodeConfigsStore>;
13
13
  /**
14
14
  * Get configs from custom code.
15
+ * @param displayName - The name of the custom code block to get configs from.
15
16
  */
16
- export declare const getProjectConfigs: () => Promise<any>;
17
+ export declare const getProjectConfigs: (displayName: string) => Promise<any>;
17
18
  /**
18
19
  * Fetches configs stored in custom code for a given component.
19
20
  * @param component
20
21
  * @returns
21
22
  */
22
- export declare const getComponentConfigs: (component: string) => Promise<any>;
23
+ export declare const getComponentConfigs: (component: string, displayName: string) => Promise<any>;
@@ -1,8 +1,5 @@
1
1
  import { writable } from 'svelte/store';
2
- import { getLogger } from '../logger';
3
2
  import { getCustomCode } from './api';
4
- const logger = getLogger('utils');
5
- const DISPLAY_NAME = 'finsweetcomponentsconfig';
6
3
  /**
7
4
  * Store for Custom Code stored Component configs
8
5
  */
@@ -13,9 +10,10 @@ export const componentConfigsStore = writable(null);
13
10
  export const customCodeConfigsStore = writable([]);
14
11
  /**
15
12
  * Get configs from custom code.
13
+ * @param displayName - The name of the custom code block to get configs from.
16
14
  */
17
- export const getProjectConfigs = async () => {
18
- const [customCodeBlock] = await getCustomCode(DISPLAY_NAME);
15
+ export const getProjectConfigs = async (displayName) => {
16
+ const [customCodeBlock] = await getCustomCode(displayName);
19
17
  if (!customCodeBlock || !customCodeBlock.hostedLocation) {
20
18
  return null;
21
19
  }
@@ -24,7 +22,6 @@ export const getProjectConfigs = async () => {
24
22
  const configs = await import(/* @vite-ignore */ customCodeBlock.hostedLocation);
25
23
  window.isLoadingCustomCodeConfigs = false;
26
24
  customCodeConfigsStore.set(configs);
27
- logger.log({}, 'Project custom code configs', configs);
28
25
  return configs;
29
26
  };
30
27
  /**
@@ -32,8 +29,8 @@ export const getProjectConfigs = async () => {
32
29
  * @param component
33
30
  * @returns
34
31
  */
35
- export const getComponentConfigs = async (component) => {
36
- const customCodeBlock = await getProjectConfigs();
32
+ export const getComponentConfigs = async (component, displayName) => {
33
+ const customCodeBlock = await getProjectConfigs(displayName);
37
34
  if (!customCodeBlock || Object.keys(customCodeBlock[component]).length === 0)
38
35
  return null;
39
36
  return customCodeBlock[component];
@@ -1,2 +1,2 @@
1
- export * from './api';
2
1
  export * from './configs';
2
+ export * from './api';
@@ -1,2 +1,2 @@
1
- export * from './api';
2
1
  export * from './configs';
2
+ export * from './api';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Check if an element is scrollable
3
+ * @param element
4
+ * @returns True or false
5
+ */
6
+ export declare const isScrollable: (element: Element) => boolean;
7
+ /**
8
+ * Finds the first child text node of an element
9
+ * @param element The element to search into.
10
+ */
11
+ export declare const findTextNode: (element: HTMLElement) => ChildNode | undefined;
12
+ /**
13
+ * Function to fetch the Document of a specified URL.
14
+ *
15
+ * @param url - The URL of the page.
16
+ * @param slug - [optional] The slug of the page.
17
+ * @returns
18
+ */
19
+ export declare const fetchDocument: (url: string, slug?: string) => Promise<Document>;
20
+ /**
21
+ * Function to fetch the Elements of a specified URL.
22
+ *
23
+ * @param url - The URL of the page.
24
+ * @param tagName - The tag name of the elements to fetch. If not provided, returns the whole page as a string.
25
+ * @param asElement - [optional] If true, returns the element as an object.
26
+ * @returns
27
+ */
28
+ export declare const fetchElements: (url: URL, tagName?: string, asElement?: boolean) => Promise<string[] | HTMLElement[]>;
29
+ /**
30
+ * Fetch elements by attribute
31
+ */
32
+ export declare const fetchElementsByAttribute: (url: URL, attribute: string) => Promise<string[]>;
33
+ /**
34
+ * Checks if an element is visible
35
+ * @param element
36
+ */
37
+ export declare const isVisible: (element: HTMLElement) => boolean;
@@ -0,0 +1,104 @@
1
+ import { load } from 'cheerio';
2
+ import { FINSWEET_REVERSE_PROXY_URL } from '../constants';
3
+ import { isHTMLElement } from './guards';
4
+ /**
5
+ * Check if an element is scrollable
6
+ * @param element
7
+ * @returns True or false
8
+ */
9
+ export const isScrollable = (element) => {
10
+ const { overflow } = getComputedStyle(element);
11
+ return overflow === 'auto' || overflow === 'scroll';
12
+ };
13
+ /**
14
+ * Finds the first child text node of an element
15
+ * @param element The element to search into.
16
+ */
17
+ export const findTextNode = (element) => {
18
+ let textNode;
19
+ for (const node of Array.from(element.childNodes)) {
20
+ if (isHTMLElement(node) && node.childNodes.length)
21
+ textNode = findTextNode(node);
22
+ else if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim())
23
+ textNode = node;
24
+ if (textNode)
25
+ break;
26
+ }
27
+ return textNode;
28
+ };
29
+ /**
30
+ * Function to fetch the Document of a specified URL.
31
+ *
32
+ * @param url - The URL of the page.
33
+ * @param slug - [optional] The slug of the page.
34
+ * @returns
35
+ */
36
+ export const fetchDocument = async (url, slug) => {
37
+ const pageUrl = new URL(url);
38
+ if (slug)
39
+ pageUrl.pathname = slug;
40
+ const target = `${FINSWEET_REVERSE_PROXY_URL}${pageUrl}`;
41
+ const response = await fetch(target);
42
+ const pageContent = await response.text();
43
+ const parser = new DOMParser();
44
+ return parser.parseFromString(pageContent, 'text/html');
45
+ };
46
+ /**
47
+ * Function to fetch the Elements of a specified URL.
48
+ *
49
+ * @param url - The URL of the page.
50
+ * @param tagName - The tag name of the elements to fetch. If not provided, returns the whole page as a string.
51
+ * @param asElement - [optional] If true, returns the element as an object.
52
+ * @returns
53
+ */
54
+ export const fetchElements = async (url, tagName, asElement) => {
55
+ const target = `${FINSWEET_REVERSE_PROXY_URL}${url.href}`;
56
+ const response = await fetch(target);
57
+ const html = await response.text();
58
+ const $ = load(html);
59
+ // return the whole page if no tag name is provided
60
+ if (!tagName)
61
+ return [$.html()];
62
+ // crawl page and get elements
63
+ if (asElement && tagName) {
64
+ const elements = $(tagName)
65
+ .map((_, el) => {
66
+ const outerHTML = $.html(el); // Get the outer HTML of each element
67
+ const parser = new DOMParser();
68
+ const parsedDoc = parser.parseFromString(outerHTML, 'text/html');
69
+ const element = parsedDoc.querySelector(tagName);
70
+ return element;
71
+ })
72
+ .get();
73
+ return elements;
74
+ }
75
+ // crawl page and get elements as strings
76
+ const elements = $(tagName)
77
+ .map((_, el) => {
78
+ const outerHTML = $.html(el);
79
+ return outerHTML;
80
+ })
81
+ .get();
82
+ return elements;
83
+ };
84
+ /**
85
+ * Fetch elements by attribute
86
+ */
87
+ export const fetchElementsByAttribute = async (url, attribute) => {
88
+ const target = `${FINSWEET_REVERSE_PROXY_URL}${url.href}`;
89
+ const response = await fetch(target);
90
+ const html = await response.text();
91
+ const $ = load(html);
92
+ const elements = $(attribute)
93
+ .map((_, el) => {
94
+ const outerHTML = $.html(el);
95
+ return outerHTML;
96
+ })
97
+ .get();
98
+ return elements;
99
+ };
100
+ /**
101
+ * Checks if an element is visible
102
+ * @param element
103
+ */
104
+ export const isVisible = (element) => !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Converts a configuration object to a base64-encoded string.
3
+ * @param {object} configs
4
+ * @returns
5
+ */
6
+ export declare const encodeComponentConfigs: (configs: object) => string;
7
+ /**
8
+ * Decodes a base64-encoded configuration string to a configuration object.
9
+ * @param configsString
10
+ * @param component
11
+ * @returns
12
+ */
13
+ export declare const decodeComponentConfigs: <T>(configsString: string) => T;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Converts a configuration object to a base64-encoded string.
3
+ * @param {object} configs
4
+ * @returns
5
+ */
6
+ export const encodeComponentConfigs = (configs) => {
7
+ const previewModeConfigs = btoa(JSON.stringify(configs));
8
+ return previewModeConfigs;
9
+ };
10
+ /**
11
+ * Decodes a base64-encoded configuration string to a configuration object.
12
+ * @param configsString
13
+ * @param component
14
+ * @returns
15
+ */
16
+ export const decodeComponentConfigs = (configsString) => {
17
+ const jsonString = atob(configsString);
18
+ const configParsed = JSON.parse(jsonString);
19
+ return configParsed;
20
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Adds an event listener to an element.
3
+ * @returns A callback to remove the event listener from the element.
4
+ *
5
+ * @param target
6
+ * @param type
7
+ * @param listener
8
+ * @param options
9
+ */
10
+ export declare function addListener<TargetInterface extends EventTarget, Type extends TargetInterface extends Window ? keyof WindowEventMap | string : TargetInterface extends Document ? keyof DocumentEventMap | string : TargetInterface extends HTMLElement ? keyof HTMLElementEventMap | string : keyof ElementEventMap | string, Listener extends Type extends keyof WindowEventMap ? (this: Document, ev: WindowEventMap[Type]) => unknown : Type extends keyof DocumentEventMap ? (this: Document, ev: DocumentEventMap[Type]) => unknown : Type extends keyof HTMLElementEventMap ? (this: HTMLElement, ev: HTMLElementEventMap[Type]) => unknown : Type extends keyof ElementEventMap ? (this: Element, ev: ElementEventMap[Type]) => unknown : EventListenerOrEventListenerObject>(target: TargetInterface | null | undefined, type: Type, listener: Listener, options?: boolean | AddEventListenerOptions): () => void;
11
+ type AllowedEvent = keyof DocumentEventMap | 'w-close';
12
+ /**
13
+ * Dispatches a custom event that bubbles from the target.
14
+ * @param target The element where the event will originate.
15
+ * @param events The event name or an array of event names.
16
+ * @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
17
+ */
18
+ export declare const simulateEvent: (target: EventTarget, events: AllowedEvent | Array<AllowedEvent>) => boolean;
19
+ export {};
@@ -0,0 +1,28 @@
1
+ import { noop } from './noop';
2
+ /**
3
+ * Adds an event listener to an element.
4
+ * @returns A callback to remove the event listener from the element.
5
+ *
6
+ * @param target
7
+ * @param type
8
+ * @param listener
9
+ * @param options
10
+ */
11
+ export function addListener(target, type, listener, options) {
12
+ if (!target)
13
+ return noop;
14
+ target.addEventListener(type, listener, options);
15
+ return () => target.removeEventListener(type, listener, options);
16
+ }
17
+ /**
18
+ * Dispatches a custom event that bubbles from the target.
19
+ * @param target The element where the event will originate.
20
+ * @param events The event name or an array of event names.
21
+ * @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
22
+ */
23
+ export const simulateEvent = (target, events) => {
24
+ if (!Array.isArray(events))
25
+ events = [events];
26
+ const eventsSuccess = events.map((event) => target.dispatchEvent(new Event(event, { bubbles: true })));
27
+ return eventsSuccess.every((success) => success);
28
+ };
@@ -0,0 +1,22 @@
1
+ import type { FormField } from '../../types';
2
+ import { simulateEvent } from './events';
3
+ /**
4
+ * Clears the form field's value and emits an input and changed event.
5
+ * If the field is a checkbox or a radio, it will unselect it.
6
+ * @param field The `FormField` to clear.
7
+ * @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system.
8
+ * You can omit certain events from being dispatched by passing them in an array.
9
+ */
10
+ export declare const clearFormField: (field: FormField, omitEvents?: Parameters<typeof simulateEvent>["1"]) => void;
11
+ /**
12
+ * Gets the value of a given input element.
13
+ * @param {FormField} input
14
+ */
15
+ export declare const getFormFieldValue: (input: FormField) => string;
16
+ /**
17
+ * Sets a value to a FormField element and emits `click`, `input` and `change` Events.
18
+ *
19
+ * @param element The FormField to update.
20
+ * @param value `boolean` for Checkboxes and Radios, `string` for the rest.
21
+ */
22
+ export declare const setFormFieldValue: (element: FormField, value: string | boolean) => void;
@@ -0,0 +1,82 @@
1
+ import { FORM_CSS_CLASSES } from '../webflow';
2
+ import { simulateEvent } from './events';
3
+ import { isHTMLInputElement } from './guards';
4
+ /**
5
+ * Clears the form field's value and emits an input and changed event.
6
+ * If the field is a checkbox or a radio, it will unselect it.
7
+ * @param field The `FormField` to clear.
8
+ * @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system.
9
+ * You can omit certain events from being dispatched by passing them in an array.
10
+ */
11
+ export const clearFormField = (field, omitEvents = []) => {
12
+ const { type } = field;
13
+ if (isHTMLInputElement(field) && ['checkbox', 'radio'].includes(type)) {
14
+ if (!field.checked)
15
+ return;
16
+ // Reset the field's value
17
+ field.checked = false;
18
+ // Emit DOM events
19
+ simulateEvent(field, ['click', 'input', 'change'].filter((event) => !omitEvents.includes(event)));
20
+ if (type === 'checkbox')
21
+ return;
22
+ // Clear custom radio button classes
23
+ const { parentElement } = field;
24
+ if (!parentElement)
25
+ return;
26
+ const radioInput = parentElement.querySelector(`.${FORM_CSS_CLASSES.radioInput}`);
27
+ if (!radioInput)
28
+ return;
29
+ radioInput.classList.remove(FORM_CSS_CLASSES.checkboxOrRadioFocus, FORM_CSS_CLASSES.checkboxOrRadioChecked);
30
+ return;
31
+ }
32
+ // Reset the field's value
33
+ field.value = '';
34
+ // Emit DOM events
35
+ simulateEvent(field, ['input', 'change'].filter((eventKey) => !omitEvents.includes(eventKey)));
36
+ };
37
+ /**
38
+ * Gets the value of a given input element.
39
+ * @param {FormField} input
40
+ */
41
+ export const getFormFieldValue = (input) => {
42
+ let { value } = input;
43
+ // Perform actions depending on input type
44
+ if (input.type === 'checkbox')
45
+ value = input.checked.toString();
46
+ if (input.type === 'radio') {
47
+ // Get the checked radio
48
+ const checkedOption = input
49
+ .closest('form')
50
+ ?.querySelector(`input[name="${input.name}"]:checked`);
51
+ // If exists, set its value
52
+ value = isHTMLInputElement(checkedOption) ? checkedOption.value : '';
53
+ }
54
+ return value.toString();
55
+ };
56
+ /**
57
+ * Sets a value to a FormField element and emits `click`, `input` and `change` Events.
58
+ *
59
+ * @param element The FormField to update.
60
+ * @param value `boolean` for Checkboxes and Radios, `string` for the rest.
61
+ */
62
+ export const setFormFieldValue = (element, value) => {
63
+ const { type } = element;
64
+ const isRadio = type === 'radio';
65
+ const isCheckbox = type === 'checkbox';
66
+ if (isRadio || isCheckbox) {
67
+ if (!isHTMLInputElement(element) ||
68
+ typeof value !== 'boolean' ||
69
+ value === element.checked ||
70
+ (isRadio && value === false)) {
71
+ return;
72
+ }
73
+ element.checked = value;
74
+ }
75
+ else {
76
+ if (element.value === value)
77
+ return;
78
+ element.value = value.toString();
79
+ }
80
+ // Emit DOM events
81
+ simulateEvent(element, ['click', 'input', 'change']);
82
+ };