diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0697e30c..7667b7e8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -181,8 +181,8 @@ importers:
specifier: ^7.2.1
version: 7.2.1(marked@15.0.3)
nanospinner:
- specifier: ^1.2.0
- version: 1.2.0
+ specifier: ^1.2.2
+ version: 1.2.2
picocolors:
specifier: ^1.0.1
version: 1.0.1
@@ -4188,8 +4188,8 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
- nanospinner@1.2.0:
- resolution: {integrity: sha512-dGxYcEj8YhuxjVO3PYmnj1nBhtwUkvuwYbLl/MduBPmQUPy3xBtG/ScJgqZgntQkX44UQaCSlFeW4rS5fUR/Sw==}
+ nanospinner@1.2.2:
+ resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==}
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@@ -10384,7 +10384,7 @@ snapshots:
nanoid@3.3.8: {}
- nanospinner@1.2.0:
+ nanospinner@1.2.2:
dependencies:
picocolors: 1.1.1
diff --git a/remix-app/framer-intl/chunk-72DMJFRS.js b/remix-app/framer-intl/chunk-72DMJFRS.js
index 8185f6e0..26eb9a69 100644
--- a/remix-app/framer-intl/chunk-72DMJFRS.js
+++ b/remix-app/framer-intl/chunk-72DMJFRS.js
@@ -62,7 +62,7 @@ function withSingleToggle(Component,) {
}
}
} catch (e) {
- console.warn('Cannot access stylesheet:', sheet.href,);
+ console.warn('Cannot access stylesheet:',e, sheet.href,);
}
}
let styleElement = document.createElement('style',);
diff --git a/remix-app/framer-intl/chunk-DAGDNIBA.js b/remix-app/framer-intl/chunk-DAGDNIBA.js
index ddcaa6ac..85d575d5 100644
--- a/remix-app/framer-intl/chunk-DAGDNIBA.js
+++ b/remix-app/framer-intl/chunk-DAGDNIBA.js
@@ -124,7 +124,7 @@ function withSingleToggle(Component3,) {
}
}
} catch (e) {
- console.warn('Cannot access stylesheet:', sheet.href,);
+ console.warn('Cannot access stylesheet:',e, sheet.href,);
}
}
let styleElement = document.createElement('style',);
@@ -215,7 +215,7 @@ function withSingleToggle2(Component3,) {
}
}
} catch (e) {
- console.warn('Cannot access stylesheet:', sheet.href,);
+ console.warn('Cannot access stylesheet:', e,sheet.href,);
}
}
let styleElement = document.createElement('style',);
diff --git a/remix-app/framer-intl/hero-section.js b/remix-app/framer-intl/hero-section.js
index d6d6af45..17fb8c27 100644
--- a/remix-app/framer-intl/hero-section.js
+++ b/remix-app/framer-intl/hero-section.js
@@ -568,6 +568,7 @@ function ComponentWithRoot({ locale, ...rest },) {
},
'cvVskSlKE': {
'path': '/sign-up',
+ 'page': null,
},
'dqRVpj9Kn': {
'path': '/docs/:slug',
diff --git a/unframer/package.json b/unframer/package.json
index f8e82893..52fdd944 100644
--- a/unframer/package.json
+++ b/unframer/package.json
@@ -59,7 +59,7 @@
"just-kebab-case": "^4.2.0",
"marked": "^15.0.3",
"marked-terminal": "^7.2.1",
- "nanospinner": "^1.2.0",
+ "nanospinner": "^1.2.2",
"picocolors": "^1.0.1",
"real-framer-motion": "npm:framer-motion@11.2.10",
"spiceflow": "^1.4.1",
diff --git a/unframer/scripts/download.ts b/unframer/scripts/download.ts
index 878c580d..6ecaa610 100644
--- a/unframer/scripts/download.ts
+++ b/unframer/scripts/download.ts
@@ -199,7 +199,8 @@ export async function fixFramerCode({ resultFile }) {
}
codeAfter += '\n\n'
codeAfter += dedent`
- export { Router, FetchClientProvider, FormContext }
+ export { Link as FramerLink }
+ export { Router, FetchClientProvider, FormContext, LocaleInfoContext }
`
codeAfter = codeAfter.replace(toRemove, '')
diff --git a/unframer/src/exporter.ts b/unframer/src/exporter.ts
index 1e325214..0b337d8c 100644
--- a/unframer/src/exporter.ts
+++ b/unframer/src/exporter.ts
@@ -68,6 +68,12 @@ export async function bundle({
spinner.start()
+ const otherRoutes = Object.fromEntries(
+ (config.framerWebPages || []).map((page) => [
+ page.webPageId,
+ { path: page.path, page: null },
+ ]),
+ )
const buildContext = await context({
absWorkingDir: out,
entryPoints: Object.keys(components).map((name) => {
@@ -121,20 +127,17 @@ export async function bundle({
JSON.stringify(config.locales) || '[]'
}
- Component.Responsive = ({ locale, ...props }) => {
+ Component.Responsive = ({ locale, ...rest }) => {
return (
,
- path: '/',
- },
- }}
+ {...rest}
+ />}
framerSiteId={${JSON.stringify(
config.fullFramerProjectId,
)}}
@@ -148,13 +151,12 @@ export async function bundle({
return (
,
- path: '/',
- },
- }}
+ routes={${JSON.stringify(
+ otherRoutes,
+ null,
+ 2,
+ )}}
+ children={}
framerSiteId={${JSON.stringify(
config.fullFramerProjectId,
)}}
@@ -227,21 +229,21 @@ export async function bundle({
`/* eslint-disable */\n` +
doNotEditComment +
formatted
- if (framerWebPages?.length) {
- codeNew = replaceWebPageIds({
- code: codeNew,
- elements: framerWebPages,
- })
- }
- const lines = findRelativeLinks(codeNew)
- if (lines.length) {
- spinner.error(
- `found broken links for ${path.relative(out, file.path)}`,
- )
- lines.forEach((line) => {
- logger.log(`${path.resolve(out, file.path)}:${line + 1}`)
- })
- }
+ // if (framerWebPages?.length) {
+ // codeNew = replaceWebPageIds({
+ // code: codeNew,
+ // elements: framerWebPages,
+ // })
+ // }
+ // const lines = findRelativeLinks(codeNew)
+ // if (lines.length) {
+ // spinner.error(
+ // `found broken links for ${path.relative(out, file.path)}`,
+ // )
+ // lines.forEach((line) => {
+ // logger.log(`${path.resolve(out, file.path)}:${line + 1}`)
+ // })
+ // }
if (existing === codeNew) {
continue
@@ -402,11 +404,15 @@ export async function bundle({
// when user press ctrl+c dispose
process.on('SIGINT', async () => {
+ spinner.stop()
+ console.log()
await buildContext.cancel()
buildContext.dispose()
process.exit(0) // Ensure process exits
})
process.on('SIGABRT', async () => {
+ spinner.stop()
+ console.log()
await buildContext.cancel()
buildContext.dispose()
process.exit(0) // Ensure process exits
diff --git a/unframer/src/framer.js b/unframer/src/framer.js
index ee1e3865..329d975e 100644
--- a/unframer/src/framer.js
+++ b/unframer/src/framer.js
@@ -52196,4 +52196,5 @@ if (typeof document !== 'undefined') {
document.head.appendChild(fragment);
}
-export { Router, FetchClientProvider, FormContext }
\ No newline at end of file
+export { Link as FramerLink }
+export { Router, FetchClientProvider, FormContext, LocaleInfoContext }
\ No newline at end of file
diff --git a/unframer/src/index.ts b/unframer/src/index.ts
index c28ae279..f3ce2900 100644
--- a/unframer/src/index.ts
+++ b/unframer/src/index.ts
@@ -1,8 +1,14 @@
export * from './framer.js'
-
+import {
+ AdaptedLink as Link,
+ ResolveLinksAdapted as ResolveLinks,
+} from './react.js'
export {
FramerStyles,
UnframerBreakpoint,
WithFramerBreakpoints,
ContextProviders,
+ AdaptedLink,
} from './react.js'
+
+export { Link, ResolveLinks }
diff --git a/unframer/src/react.tsx b/unframer/src/react.tsx
index 8b9f5186..a0bff2ed 100644
--- a/unframer/src/react.tsx
+++ b/unframer/src/react.tsx
@@ -229,36 +229,117 @@ import {
FormContext,
// @ts-ignore
Router,
+ // @ts-ignore
+ LocaleInfoContext,
+ // @ts-ignore
+ FramerLink as Link,
} from './framer.js'
+import React from 'react'
+
+type Routes = Record
+
+const routesContext = React.createContext({})
+
+function replacePathParams(path: string, params: Record) {
+ const paramRegex = /:[a-zA-Z]+/g
+ const matches = path.match(paramRegex)
+
+ // If there is only one match
+ if (matches?.length === 1) {
+ const paramValue = Object.values(params)[0]
+
+ let res = path.replace(paramRegex, paramValue)
+ // console.log({ matches, params, paramValue, res })
+
+ return res
+ }
+
+ return path.replace(paramRegex, (match) => {
+ const param = match.slice(1) // Remove the : prefix
+ return params[param] || match // Replace with param value or keep original if not found
+ })
+}
+
+export function ResolveLinksAdapted({ links, children }) {
+ // TODO add ref
+ return children(links.map((x) => x.href))
+}
+
+export function AdaptedLink({
+ href,
+ nodeId,
+ openInNewTab,
+ smoothScroll,
+ ...rest
+}) {
+ const onlyForFramer = { nodeId, openInNewTab, smoothScroll }
+ const routes = React.useContext(routesContext)
+ const webPageId = href?.webPageId as string
+ const pathVariables = href?.pathVariables as Record
+ const route = routes?.[webPageId]
+ // console.log({ href, pathVariables, path: route?.path, ...rest })
+ if (href?.startsWith && href.startsWith('/')) {
+ return
+ }
+ if (!webPageId) {
+ return
+ }
+
+ if (!route || !route.path) {
+ return
+ }
+ let path = route.path
+ if (pathVariables) {
+ path = replacePathParams(path, pathVariables)
+ }
+ if (path?.startsWith?.('/')) {
+ return
+ }
+
+ return
+}
export function ContextProviders({
locale,
children,
framerSiteId,
routes,
- routeId,
- pathVariables,
- collectionUtils,
+ // collectionUtils,
locales,
}) {
- const localeId = locales?.find(
+ const activeLocale = locales?.find(
(l) => l.slug === locale || l.code === locale || l.id === locale,
- )?.id
+ )
+
+ const localeInfo = useMemo(() => {
+ return {
+ activeLocale,
+ locales,
+ setLocale: async (localeOrLocaleId) => {
+ console.log('setLocale', localeOrLocaleId)
+ },
+ }
+ }, [activeLocale, locales])
return (
-
- {children}
-
+
+
+ {/*
+ {children}
+ */}
+ {children}
+
+
diff --git a/unframer/src/utils.ts b/unframer/src/utils.ts
index d9819dcf..f872989f 100644
--- a/unframer/src/utils.ts
+++ b/unframer/src/utils.ts
@@ -4,7 +4,7 @@ import { marked } from 'marked'
import { markedTerminal } from 'marked-terminal'
import { createSpinner } from 'nanospinner'
-export const spinner = createSpinner('Downloading Framer Components') as any
+export const spinner = createSpinner('Downloading Framer Components')
marked.use(markedTerminal())