@finsweet/webflow-apps-utils 1.0.32 → 1.0.36

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.
@@ -59,6 +59,8 @@
59
59
  main?: Snippet;
60
60
  /** Preview bar content snippet */
61
61
  previewBar?: Snippet;
62
+ /** Custom tabs snippet to override default tab rendering */
63
+ customTabs?: Snippet;
62
64
  /** Footer content snippet */
63
65
  footer?: Snippet;
64
66
  }
@@ -73,6 +75,7 @@
73
75
  showFooter = true,
74
76
  showSidebar = true,
75
77
  showTabs = true,
78
+ customTabs,
76
79
  showPreviewBar = true,
77
80
  sidebarWidth = '274px',
78
81
  containerMode = false,
@@ -164,60 +167,64 @@
164
167
  >
165
168
  {#if showTabs}
166
169
  <div class="navbar" data-area="navbar">
167
- {#each tabs as tab (tab.path)}
168
- {@const Icon = tab.icon}
169
- {@const notification = getNotification(tab.path)}
170
- <button
171
- class="tab"
172
- class:isActive={activeTab === tab.path}
173
- class:warning={notification && !notification?.success}
174
- class:success={notification && notification?.success}
175
- onclick={() => switchTab(tab.path)}
176
- >
177
- <Icon />
178
- <span
179
- class="tab-text"
180
- style="color: {activeTab !== tab.path ? 'var(--text2)' : 'var(--actionPrimaryText)'}"
170
+ {#if customTabs}
171
+ {@render customTabs()}
172
+ {:else}
173
+ {#each tabs as tab (tab.path)}
174
+ {@const Icon = tab.icon}
175
+ {@const notification = getNotification(tab.path)}
176
+ <button
177
+ class="tab"
178
+ class:isActive={activeTab === tab.path}
179
+ class:warning={notification && !notification?.success}
180
+ class:success={notification && notification?.success}
181
+ onclick={() => switchTab(tab.path)}
181
182
  >
182
- {tab.name}
183
- </span>
184
-
185
- {#if notification?.showNotification}
186
- {#if notification?.success}
187
- <span class="notification-pill success">
188
- <CheckCircleOutlinedIcon />
189
- </span>
190
- {:else}
191
- <Tooltip
192
- message={notification?.message}
193
- placement="right"
194
- offsetVal={8}
195
- position="fixed"
196
- width="max-content"
197
- >
198
- {#snippet target()}
199
- <div class="notification-pill warning-tooltip">
200
- <WarningCircleOutlineIcon />
201
- </div>
202
- {/snippet}
203
- </Tooltip>
183
+ <Icon />
184
+ <span
185
+ class="tab-text"
186
+ style="color: {activeTab !== tab.path ? 'var(--text2)' : 'var(--actionPrimaryText)'}"
187
+ >
188
+ {tab.name}
189
+ </span>
190
+
191
+ {#if notification?.showNotification}
192
+ {#if notification?.success}
193
+ <span class="notification-pill success">
194
+ <CheckCircleOutlinedIcon />
195
+ </span>
196
+ {:else}
197
+ <Tooltip
198
+ message={notification?.message}
199
+ placement="right"
200
+ offsetVal={8}
201
+ position="fixed"
202
+ width="max-content"
203
+ >
204
+ {#snippet target()}
205
+ <div class="notification-pill warning-tooltip">
206
+ <WarningCircleOutlineIcon />
207
+ </div>
208
+ {/snippet}
209
+ </Tooltip>
210
+ {/if}
204
211
  {/if}
205
- {/if}
206
- </button>
207
- {/each}
208
- </div>
209
- {/if}
210
-
211
- {#if showPreviewBar && showSidebar}
212
- <div class="preview-bar" data-area="preview-bar">
213
- {#if previewBar}
214
- {@render previewBar()}
215
- {:else}
216
- <div class="preview-bar-content">
217
- <span>Preview: {activeTab} tab content</span>
218
- </div>
212
+ </button>
213
+ {/each}
219
214
  {/if}
220
215
  </div>
216
+
217
+ {#if showPreviewBar && showSidebar}
218
+ <div class="preview-bar" data-area="preview-bar">
219
+ {#if previewBar}
220
+ {@render previewBar()}
221
+ {:else}
222
+ <div class="preview-bar-content">
223
+ <span>Preview: {activeTab} tab content</span>
224
+ </div>
225
+ {/if}
226
+ </div>
227
+ {/if}
221
228
  {/if}
222
229
 
223
230
  {#if showSidebar}
@@ -47,6 +47,8 @@ interface LayoutProps extends HTMLAttributes<HTMLDivElement> {
47
47
  main?: Snippet;
48
48
  /** Preview bar content snippet */
49
49
  previewBar?: Snippet;
50
+ /** Custom tabs snippet to override default tab rendering */
51
+ customTabs?: Snippet;
50
52
  /** Footer content snippet */
51
53
  footer?: Snippet;
52
54
  }
@@ -15,8 +15,8 @@ export declare const getPathname: (page: Page | Folder) => Promise<string>;
15
15
  /**
16
16
  * Returns a single page with all its properties.
17
17
  */
18
- export declare const getPageMetadata: (page: Page) => Promise<PageWithProps>;
18
+ export declare const getPageMetadata: (page: Page, targetUrl?: URL) => Promise<PageWithProps>;
19
19
  /**
20
20
  * Returns all pages and folders from the Webflow project.
21
21
  */
22
- export declare const getAllPages: (pagesAndFolders?: boolean, kind?: PageWithProps["kind"]) => Promise<PageWithProps[]>;
22
+ export declare const getAllPages: (pagesAndFolders?: boolean, kind?: PageWithProps["kind"], targetUrl?: URL) => Promise<PageWithProps[]>;
@@ -18,10 +18,11 @@ export const getPathname = async (page) => {
18
18
  /**
19
19
  * Returns a single page with all its properties.
20
20
  */
21
- export const getPageMetadata = async (page) => {
21
+ export const getPageMetadata = async (page, targetUrl) => {
22
22
  if (!pageStagingUrl) {
23
- const { shortName } = await webflow.getSiteInfo();
24
- pageStagingUrl = `https://${shortName}.webflow.io`;
23
+ const { domains } = await webflow.getSiteInfo();
24
+ const stagingUrl = domains.find((domain) => domain.stage === 'staging')?.url;
25
+ pageStagingUrl = targetUrl?.toString() || `https://${stagingUrl}`;
25
26
  }
26
27
  const [fullPath, parent, name, kind, isDraft, isPasswordProtected, generatedPathname] = await Promise.all([
27
28
  page?.getPublishPath(),
@@ -50,7 +51,7 @@ export const getPageMetadata = async (page) => {
50
51
  /**
51
52
  * Returns all pages and folders from the Webflow project.
52
53
  */
53
- export const getAllPages = async (pagesAndFolders, kind) => {
54
+ export const getAllPages = async (pagesAndFolders, kind, targetUrl) => {
54
55
  try {
55
56
  const allPages = await webflow?.getAllPagesAndFolders();
56
57
  const pagesWithPropsPromises = [];
@@ -58,7 +59,7 @@ export const getAllPages = async (pagesAndFolders, kind) => {
58
59
  for (const page of allPages) {
59
60
  if (page.type === 'PageFolder')
60
61
  continue;
61
- pagesWithPropsPromises.push(getPageMetadata(page));
62
+ pagesWithPropsPromises.push(getPageMetadata(page, targetUrl));
62
63
  }
63
64
  }
64
65
  const list = await Promise.all(pagesWithPropsPromises);
@@ -2,10 +2,13 @@
2
2
  * Returns a valid Webflow project staging URL.
3
3
  */
4
4
  export const getSiteStagingUrl = async (origin, stagingName) => {
5
- const { shortName } = await webflow.getSiteInfo();
5
+ const { shortName, domains } = await webflow.getSiteInfo();
6
6
  if (stagingName)
7
7
  return shortName;
8
+ const stagingUrl = domains.find((domain) => domain.stage === 'staging')?.url;
8
9
  if (origin)
9
- return `${shortName}.webflow.io`;
10
+ return stagingUrl || `${shortName}.webflow.io`;
11
+ if (stagingUrl)
12
+ return `https://${stagingUrl}`;
10
13
  return `https://${shortName}.webflow.io`;
11
14
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finsweet/webflow-apps-utils",
3
- "version": "1.0.32",
3
+ "version": "1.0.36",
4
4
  "description": "Shared utilities for Webflow apps",
5
5
  "homepage": "https://github.com/finsweet/webflow-apps-utils",
6
6
  "repository": {
@@ -37,69 +37,70 @@
37
37
  "svelte": "^5.0.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@changesets/changelog-git": "^0.1.14",
41
- "@changesets/cli": "^2.27.1",
42
- "@chromatic-com/storybook": "^4",
43
- "@eslint/compat": "^1.2.5",
44
- "@eslint/js": "^9.18.0",
45
- "@playwright/test": "^1.49.1",
46
- "@storybook/addon-a11y": "^9.0.10",
47
- "@storybook/addon-docs": "^9.0.10",
48
- "@storybook/addon-svelte-csf": "^5.0.3",
49
- "@storybook/addon-vitest": "^9.0.10",
50
- "@storybook/sveltekit": "^9.0.10",
51
- "@sveltejs/adapter-auto": "^6.0.0",
52
- "@sveltejs/kit": "^2.16.0",
53
- "@sveltejs/package": "^2.0.0",
54
- "@sveltejs/vite-plugin-svelte": "^5.0.0",
55
- "@testing-library/jest-dom": "^6.6.3",
56
- "@testing-library/svelte": "^5.2.4",
57
- "@testing-library/user-event": "^14.6.1",
58
- "@types/js-cookie": "^3.0.6",
59
- "@types/lodash": "^4.17.18",
60
- "@types/lodash-es": "^4.17.12",
61
- "@types/luxon": "^3.6.2",
62
- "@types/node": "^22",
40
+ "@changesets/changelog-git": "0.2.1",
41
+ "@changesets/cli": "2.29.7",
42
+ "@chromatic-com/storybook": "4.1.1",
43
+ "@eslint/compat": "1.4.0",
44
+ "@eslint/js": "9.36.0",
45
+ "@playwright/test": "1.55.1",
46
+ "@storybook/addon-a11y": "9.1.8",
47
+ "@storybook/addon-docs": "9.1.8",
48
+ "@storybook/addon-svelte-csf": "5.0.8",
49
+ "@storybook/addon-vitest": "9.1.8",
50
+ "@storybook/sveltekit": "9.1.8",
51
+ "@sveltejs/adapter-auto": "6.1.0",
52
+ "@sveltejs/kit": "2.43.2",
53
+ "@sveltejs/package": "2.5.4",
54
+ "@sveltejs/vite-plugin-svelte": "5.1.1",
55
+ "@testing-library/jest-dom": "6.8.0",
56
+ "@testing-library/svelte": "5.2.8",
57
+ "@testing-library/user-event": "14.6.1",
58
+ "@types/js-cookie": "3.0.6",
59
+ "@types/lodash": "4.17.20",
60
+ "@types/lodash-es": "4.17.12",
61
+ "@types/luxon": "3.7.1",
62
+ "@types/node": "22.18.6",
63
63
  "@vitest/browser": "3.2.3",
64
64
  "@vitest/coverage-v8": "3.2.3",
65
- "@webflow/designer-extension-typings": "latest",
66
- "eslint": "^9.18.0",
67
- "eslint-config-prettier": "^10.0.1",
68
- "eslint-plugin-simple-import-sort": "^12.1.1",
69
- "eslint-plugin-storybook": "^9.0.10",
70
- "eslint-plugin-svelte": "^3.0.0",
71
- "globals": "^16.0.0",
72
- "jsdom": "^26.0.0",
73
- "prettier": "^3.4.2",
74
- "prettier-plugin-svelte": "^3.3.3",
75
- "publint": "^0.3.2",
76
- "storybook": "^9.0.10",
77
- "svelte": "^5.0.0",
78
- "svelte-check": "^4.0.0",
79
- "typescript": "^5.0.0",
80
- "typescript-eslint": "^8.20.0",
81
- "vite": "^6.2.6",
82
- "vitest": "^3.2.3"
65
+ "@webflow/designer-extension-typings": "2.0.23",
66
+ "eslint": "9.36.0",
67
+ "eslint-config-prettier": "10.1.8",
68
+ "eslint-plugin-simple-import-sort": "12.1.1",
69
+ "eslint-plugin-storybook": "9.1.8",
70
+ "eslint-plugin-svelte": "3.12.4",
71
+ "globals": "16.4.0",
72
+ "js-yaml": "4.1.1",
73
+ "jsdom": "26.1.0",
74
+ "prettier": "3.6.2",
75
+ "prettier-plugin-svelte": "3.4.0",
76
+ "publint": "0.3.13",
77
+ "storybook": "9.1.8",
78
+ "svelte": "5.39.5",
79
+ "svelte-check": "4.3.2",
80
+ "typescript": "5.9.2",
81
+ "typescript-eslint": "8.44.1",
82
+ "vite": "7.1.7",
83
+ "vitest": "3.2.4"
83
84
  },
84
85
  "keywords": [
85
86
  "svelte"
86
87
  ],
87
88
  "dependencies": {
88
- "@floating-ui/dom": "^1.7.1",
89
- "cheerio": "^1.1.0",
90
- "copy-text-to-clipboard": "^3.2.2",
91
- "csv-parse": "^5.6.0",
92
- "js-cookie": "^3.0.5",
93
- "just-debounce": "^1.1.0",
94
- "lodash": "^4.17.21",
95
- "lodash-es": "^4.17.21",
96
- "luxon": "^3.6.1",
97
- "motion": "^10.18.0",
98
- "svelte-routing": "^2.13.0",
99
- "swiper": "^11.2.8",
100
- "terser": "^5.43.1",
101
- "uuid": "^11.1.0",
102
- "zod": "^3.25.64"
89
+ "@floating-ui/dom": "1.7.4",
90
+ "cheerio": "1.1.2",
91
+ "copy-text-to-clipboard": "3.2.2",
92
+ "csv-parse": "5.6.0",
93
+ "js-cookie": "3.0.5",
94
+ "just-debounce": "1.1.0",
95
+ "lodash": "4.17.21",
96
+ "lodash-es": "4.17.21",
97
+ "luxon": "3.7.2",
98
+ "motion": "10.18.0",
99
+ "svelte-routing": "2.13.0",
100
+ "swiper": "11.2.10",
101
+ "terser": "5.44.0",
102
+ "uuid": "11.1.0",
103
+ "zod": "3.25.76"
103
104
  },
104
105
  "scripts": {
105
106
  "dev": "vite dev",