@linktr.ee/linkapp 0.0.9 → 0.0.11
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.
- package/dev-server/classic/main.tsx +46 -8
- package/dev-server/classic.html +58 -0
- package/dev-server/components/ui/dialog.tsx +19 -42
- package/dev-server/components/ui/tabs.tsx +6 -6
- package/dev-server/featured/main.tsx +46 -8
- package/dev-server/featured.html +58 -0
- package/dev-server/lib/utils.ts +2 -2
- package/dev-server/preview/Preview.tsx +428 -15
- package/dev-server/vite.config.ts +11 -11
- package/dist/cli.js +5 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +3 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +10 -4
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +15 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/components/ThemeStyle.d.ts +30 -0
- package/dist/components/ThemeStyle.d.ts.map +1 -0
- package/dist/components/ThemeStyle.js +33 -0
- package/dist/components/ThemeStyle.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -0
- package/dist/lib/build/detect-layouts.d.ts +2 -2
- package/dist/lib/build/detect-layouts.d.ts.map +1 -1
- package/dist/lib/build/detect-layouts.js +14 -25
- package/dist/lib/build/detect-layouts.js.map +1 -1
- package/dist/lib/config/load-config.d.ts +9 -0
- package/dist/lib/config/load-config.d.ts.map +1 -0
- package/dist/lib/config/load-config.js +31 -0
- package/dist/lib/config/load-config.js.map +1 -0
- package/dist/lib/deploy/generate-manifest-files.d.ts.map +1 -1
- package/dist/lib/deploy/generate-manifest-files.js +20 -35
- package/dist/lib/deploy/generate-manifest-files.js.map +1 -1
- package/dist/lib/deploy/pack-project.d.ts.map +1 -1
- package/dist/lib/deploy/pack-project.js +32 -5
- package/dist/lib/deploy/pack-project.js.map +1 -1
- package/dist/lib/deploy/upload.d.ts +1 -0
- package/dist/lib/deploy/upload.d.ts.map +1 -1
- package/dist/lib/deploy/upload.js +17 -7
- package/dist/lib/deploy/upload.js.map +1 -1
- package/dist/lib/deploy/validation.d.ts.map +1 -1
- package/dist/lib/deploy/validation.js +4 -61
- package/dist/lib/deploy/validation.js.map +1 -1
- package/dist/lib/utils/setup-runtime.d.ts.map +1 -1
- package/dist/lib/utils/setup-runtime.js +46 -19
- package/dist/lib/utils/setup-runtime.js.map +1 -1
- package/dist/lib/vite/config-factory.d.ts.map +1 -1
- package/dist/lib/vite/config-factory.js +2 -2
- package/dist/lib/vite/config-factory.js.map +1 -1
- package/dist/lib/vite/plugins/asset-versioning.d.ts.map +1 -1
- package/dist/lib/vite/plugins/asset-versioning.js +4 -2
- package/dist/lib/vite/plugins/asset-versioning.js.map +1 -1
- package/dist/schema/config.schema.d.ts +126 -99
- package/dist/schema/config.schema.d.ts.map +1 -1
- package/dist/schema/config.schema.js +140 -20
- package/dist/schema/config.schema.js.map +1 -1
- package/dist/sdk/index.d.ts +21 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +21 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/send-message.d.ts +16 -0
- package/dist/sdk/send-message.d.ts.map +1 -0
- package/dist/sdk/send-message.js +34 -0
- package/dist/sdk/send-message.js.map +1 -0
- package/dist/sdk/use-open-popup.d.ts +23 -0
- package/dist/sdk/use-open-popup.d.ts.map +1 -0
- package/dist/sdk/use-open-popup.js +29 -0
- package/dist/sdk/use-open-popup.js.map +1 -0
- package/dist/types.d.ts +162 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +41 -1
- package/dist/types.js.map +1 -1
- package/package.json +11 -3
- package/runtime/index.html +58 -0
|
@@ -1,13 +1,47 @@
|
|
|
1
|
+
import Classic from "@/app/classic";
|
|
1
2
|
import { StrictMode } from "react";
|
|
2
3
|
import { createRoot } from "react-dom/client";
|
|
3
|
-
import Layout from "@/app/layout";
|
|
4
|
-
import Classic from "@/app/classic";
|
|
5
4
|
import "@/app/globals.css";
|
|
6
5
|
|
|
7
|
-
//
|
|
8
|
-
const
|
|
6
|
+
// Conditionally import Layout if it exists
|
|
7
|
+
const layoutModules = import.meta.glob("@/app/layout.{ts,tsx}", {
|
|
8
|
+
eager: true,
|
|
9
|
+
});
|
|
10
|
+
const Layout = Object.values(layoutModules)[0]?.default as
|
|
11
|
+
| React.ComponentType<{ children: React.ReactNode; theme?: any }>
|
|
12
|
+
| undefined;
|
|
13
|
+
|
|
14
|
+
// Preview props injected by dev server via Vite define
|
|
15
|
+
declare const __PREVIEW_PROPS__: Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
const previewProps = __PREVIEW_PROPS__ || {
|
|
9
18
|
linkUrl: "https://example.com/demo",
|
|
10
|
-
|
|
19
|
+
theme: {
|
|
20
|
+
cssVariables: {
|
|
21
|
+
"--button-style-text": "#000000",
|
|
22
|
+
"--button-style-background": "#ffffff",
|
|
23
|
+
"--button-style-inner-radius": "12px",
|
|
24
|
+
"--button-style-border-color": "#e5e7eb",
|
|
25
|
+
"--button-style-background-hover": "#f3f4f6",
|
|
26
|
+
"--button-style-contrast-color": "#ffffff",
|
|
27
|
+
"--profileBackground": "#ffffff",
|
|
28
|
+
},
|
|
29
|
+
// Legacy properties (deprecated)
|
|
30
|
+
textColor: "#000000",
|
|
31
|
+
backgroundColor: "#ffffff",
|
|
32
|
+
borderRadius: "12px",
|
|
33
|
+
borderColor: "#e5e7eb",
|
|
34
|
+
backgroundHover: "#f3f4f6",
|
|
35
|
+
contrastColor: "#ffffff",
|
|
36
|
+
textHoverColor: "#111827",
|
|
37
|
+
},
|
|
38
|
+
locale: "en-US",
|
|
39
|
+
currency: "USD",
|
|
40
|
+
username: "demo-user",
|
|
41
|
+
viewport: {
|
|
42
|
+
width: 680,
|
|
43
|
+
height: 800,
|
|
44
|
+
},
|
|
11
45
|
};
|
|
12
46
|
|
|
13
47
|
const rootElement = document.getElementById("root");
|
|
@@ -17,8 +51,12 @@ if (!rootElement) {
|
|
|
17
51
|
|
|
18
52
|
createRoot(rootElement).render(
|
|
19
53
|
<StrictMode>
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
54
|
+
{Layout ? (
|
|
55
|
+
<Layout theme={previewProps.theme}>
|
|
56
|
+
<Classic {...previewProps} />
|
|
57
|
+
</Layout>
|
|
58
|
+
) : (
|
|
59
|
+
<Classic {...previewProps} />
|
|
60
|
+
)}
|
|
23
61
|
</StrictMode>,
|
|
24
62
|
);
|
package/dev-server/classic.html
CHANGED
|
@@ -4,6 +4,64 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Classic - LinkApp</title>
|
|
7
|
+
|
|
8
|
+
<!-- Linktree theme variables will be injected here -->
|
|
9
|
+
<style id="linktree-theme"></style>
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
/**
|
|
13
|
+
* Helper function to convert CSS variables object to CSS string
|
|
14
|
+
* @param {Record<string, string>} vars - Object with CSS variable names as keys
|
|
15
|
+
* @returns {string} CSS string like "--var1: value1; --var2: value2;"
|
|
16
|
+
*/
|
|
17
|
+
function renderCssVariables(vars) {
|
|
18
|
+
return Object.entries(vars)
|
|
19
|
+
.map((entry) => entry.join(': '))
|
|
20
|
+
.join('; ') + ';'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Listen for theme updates from parent window
|
|
25
|
+
* Applies CSS variables to the document root
|
|
26
|
+
*/
|
|
27
|
+
window.addEventListener('message', function(event) {
|
|
28
|
+
// Only process messages with the correct structure
|
|
29
|
+
if (
|
|
30
|
+
event.data &&
|
|
31
|
+
typeof event.data === 'object' &&
|
|
32
|
+
event.data.type === 'THEME_UPDATE'
|
|
33
|
+
) {
|
|
34
|
+
const themeUpdate = event.data
|
|
35
|
+
|
|
36
|
+
// Get the style element where theme variables are injected
|
|
37
|
+
const themeStyle = document.getElementById('linktree-theme')
|
|
38
|
+
|
|
39
|
+
if (!themeStyle) {
|
|
40
|
+
console.warn('linktree-theme style element not found')
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Inject CSS variables into :root
|
|
45
|
+
themeStyle.textContent = ':root { ' + renderCssVariables(themeUpdate.payload.variables) + ' }'
|
|
46
|
+
|
|
47
|
+
// Remove any existing theme classes
|
|
48
|
+
const classesToRemove = []
|
|
49
|
+
document.documentElement.classList.forEach((className) => {
|
|
50
|
+
if (className.startsWith('linktree-theme-')) {
|
|
51
|
+
classesToRemove.push(className)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
classesToRemove.forEach((className) => {
|
|
55
|
+
document.documentElement.classList.remove(className)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// Add theme class for additional styling hooks
|
|
59
|
+
if (themeUpdate.payload.name && themeUpdate.payload.name !== 'legacy') {
|
|
60
|
+
document.documentElement.classList.add('linktree-theme-' + themeUpdate.payload.name)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, false)
|
|
64
|
+
</script>
|
|
7
65
|
</head>
|
|
8
66
|
<body>
|
|
9
67
|
<div id="root"></div>
|
|
@@ -1,45 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import * as DialogPrimitive from
|
|
4
|
-
import { XIcon } from
|
|
3
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog'
|
|
4
|
+
import { XIcon } from 'lucide-react'
|
|
5
5
|
|
|
6
|
-
import { cn } from
|
|
6
|
+
import { cn } from '../../lib/utils'
|
|
7
7
|
|
|
8
|
-
function Dialog({
|
|
9
|
-
...props
|
|
10
|
-
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
8
|
+
function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
11
9
|
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
function DialogTrigger({
|
|
15
|
-
...props
|
|
16
|
-
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
12
|
+
function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
17
13
|
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
function DialogPortal({
|
|
21
|
-
...props
|
|
22
|
-
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
16
|
+
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
23
17
|
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
function DialogClose({
|
|
27
|
-
...props
|
|
28
|
-
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
20
|
+
function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
29
21
|
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
|
30
22
|
}
|
|
31
23
|
|
|
32
|
-
function DialogOverlay({
|
|
33
|
-
className,
|
|
34
|
-
...props
|
|
35
|
-
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
24
|
+
function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
36
25
|
return (
|
|
37
26
|
<DialogPrimitive.Overlay
|
|
38
27
|
data-slot="dialog-overlay"
|
|
39
|
-
className={cn(
|
|
40
|
-
"fixed inset-0 z-50 bg-black/50",
|
|
41
|
-
className
|
|
42
|
-
)}
|
|
28
|
+
className={cn('fixed inset-0 z-50 bg-black/50', className)}
|
|
43
29
|
{...props}
|
|
44
30
|
/>
|
|
45
31
|
)
|
|
@@ -59,7 +45,7 @@ function DialogContent({
|
|
|
59
45
|
<DialogPrimitive.Content
|
|
60
46
|
data-slot="dialog-content"
|
|
61
47
|
className={cn(
|
|
62
|
-
|
|
48
|
+
'bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
|
63
49
|
className
|
|
64
50
|
)}
|
|
65
51
|
{...props}
|
|
@@ -79,50 +65,41 @@ function DialogContent({
|
|
|
79
65
|
)
|
|
80
66
|
}
|
|
81
67
|
|
|
82
|
-
function DialogHeader({ className, ...props }: React.ComponentProps<
|
|
68
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
83
69
|
return (
|
|
84
70
|
<div
|
|
85
71
|
data-slot="dialog-header"
|
|
86
|
-
className={cn(
|
|
72
|
+
className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
|
|
87
73
|
{...props}
|
|
88
74
|
/>
|
|
89
75
|
)
|
|
90
76
|
}
|
|
91
77
|
|
|
92
|
-
function DialogFooter({ className, ...props }: React.ComponentProps<
|
|
78
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
93
79
|
return (
|
|
94
80
|
<div
|
|
95
81
|
data-slot="dialog-footer"
|
|
96
|
-
className={cn(
|
|
97
|
-
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
98
|
-
className
|
|
99
|
-
)}
|
|
82
|
+
className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
|
|
100
83
|
{...props}
|
|
101
84
|
/>
|
|
102
85
|
)
|
|
103
86
|
}
|
|
104
87
|
|
|
105
|
-
function DialogTitle({
|
|
106
|
-
className,
|
|
107
|
-
...props
|
|
108
|
-
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
88
|
+
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
109
89
|
return (
|
|
110
90
|
<DialogPrimitive.Title
|
|
111
91
|
data-slot="dialog-title"
|
|
112
|
-
className={cn(
|
|
92
|
+
className={cn('text-lg leading-none font-semibold', className)}
|
|
113
93
|
{...props}
|
|
114
94
|
/>
|
|
115
95
|
)
|
|
116
96
|
}
|
|
117
97
|
|
|
118
|
-
function DialogDescription({
|
|
119
|
-
className,
|
|
120
|
-
...props
|
|
121
|
-
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
98
|
+
function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
122
99
|
return (
|
|
123
100
|
<DialogPrimitive.Description
|
|
124
101
|
data-slot="dialog-description"
|
|
125
|
-
className={cn(
|
|
102
|
+
className={cn('text-muted-foreground text-sm', className)}
|
|
126
103
|
{...props}
|
|
127
104
|
/>
|
|
128
105
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as TabsPrimitive from
|
|
3
|
-
import { cn } from
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs'
|
|
3
|
+
import { cn } from '../../lib/utils'
|
|
4
4
|
|
|
5
5
|
const Tabs = TabsPrimitive.Root
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ const TabsList = React.forwardRef<
|
|
|
11
11
|
<TabsPrimitive.List
|
|
12
12
|
ref={ref}
|
|
13
13
|
className={cn(
|
|
14
|
-
|
|
14
|
+
'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
|
|
15
15
|
className
|
|
16
16
|
)}
|
|
17
17
|
{...props}
|
|
@@ -26,7 +26,7 @@ const TabsTrigger = React.forwardRef<
|
|
|
26
26
|
<TabsPrimitive.Trigger
|
|
27
27
|
ref={ref}
|
|
28
28
|
className={cn(
|
|
29
|
-
|
|
29
|
+
'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
|
|
30
30
|
className
|
|
31
31
|
)}
|
|
32
32
|
{...props}
|
|
@@ -41,7 +41,7 @@ const TabsContent = React.forwardRef<
|
|
|
41
41
|
<TabsPrimitive.Content
|
|
42
42
|
ref={ref}
|
|
43
43
|
className={cn(
|
|
44
|
-
|
|
44
|
+
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
45
45
|
className
|
|
46
46
|
)}
|
|
47
47
|
{...props}
|
|
@@ -1,13 +1,47 @@
|
|
|
1
|
+
import Featured from "@/app/featured";
|
|
1
2
|
import { StrictMode } from "react";
|
|
2
3
|
import { createRoot } from "react-dom/client";
|
|
3
|
-
import Layout from "@/app/layout";
|
|
4
|
-
import Featured from "@/app/featured";
|
|
5
4
|
import "@/app/globals.css";
|
|
6
5
|
|
|
7
|
-
//
|
|
8
|
-
const
|
|
6
|
+
// Conditionally import Layout if it exists
|
|
7
|
+
const layoutModules = import.meta.glob("@/app/layout.{ts,tsx}", {
|
|
8
|
+
eager: true,
|
|
9
|
+
});
|
|
10
|
+
const Layout = Object.values(layoutModules)[0]?.default as
|
|
11
|
+
| React.ComponentType<{ children: React.ReactNode; theme?: any }>
|
|
12
|
+
| undefined;
|
|
13
|
+
|
|
14
|
+
// Preview props injected by dev server via Vite define
|
|
15
|
+
declare const __PREVIEW_PROPS__: Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
const previewProps = __PREVIEW_PROPS__ || {
|
|
9
18
|
linkUrl: "https://example.com/demo",
|
|
10
|
-
|
|
19
|
+
theme: {
|
|
20
|
+
cssVariables: {
|
|
21
|
+
"--button-style-text": "#000000",
|
|
22
|
+
"--button-style-background": "#ffffff",
|
|
23
|
+
"--button-style-inner-radius": "12px",
|
|
24
|
+
"--button-style-border-color": "#e5e7eb",
|
|
25
|
+
"--button-style-background-hover": "#f3f4f6",
|
|
26
|
+
"--button-style-contrast-color": "#ffffff",
|
|
27
|
+
"--profileBackground": "#ffffff",
|
|
28
|
+
},
|
|
29
|
+
// Legacy properties (deprecated)
|
|
30
|
+
textColor: "#000000",
|
|
31
|
+
backgroundColor: "#ffffff",
|
|
32
|
+
borderRadius: "12px",
|
|
33
|
+
borderColor: "#e5e7eb",
|
|
34
|
+
backgroundHover: "#f3f4f6",
|
|
35
|
+
contrastColor: "#ffffff",
|
|
36
|
+
textHoverColor: "#111827",
|
|
37
|
+
},
|
|
38
|
+
locale: "en-US",
|
|
39
|
+
currency: "USD",
|
|
40
|
+
username: "demo-user",
|
|
41
|
+
viewport: {
|
|
42
|
+
width: 680,
|
|
43
|
+
height: 800,
|
|
44
|
+
},
|
|
11
45
|
};
|
|
12
46
|
|
|
13
47
|
const rootElement = document.getElementById("root");
|
|
@@ -17,8 +51,12 @@ if (!rootElement) {
|
|
|
17
51
|
|
|
18
52
|
createRoot(rootElement).render(
|
|
19
53
|
<StrictMode>
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
54
|
+
{Layout ? (
|
|
55
|
+
<Layout theme={previewProps.theme}>
|
|
56
|
+
<Featured {...previewProps} />
|
|
57
|
+
</Layout>
|
|
58
|
+
) : (
|
|
59
|
+
<Featured {...previewProps} />
|
|
60
|
+
)}
|
|
23
61
|
</StrictMode>,
|
|
24
62
|
);
|
package/dev-server/featured.html
CHANGED
|
@@ -4,6 +4,64 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Featured - LinkApp</title>
|
|
7
|
+
|
|
8
|
+
<!-- Linktree theme variables will be injected here -->
|
|
9
|
+
<style id="linktree-theme"></style>
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
/**
|
|
13
|
+
* Helper function to convert CSS variables object to CSS string
|
|
14
|
+
* @param {Record<string, string>} vars - Object with CSS variable names as keys
|
|
15
|
+
* @returns {string} CSS string like "--var1: value1; --var2: value2;"
|
|
16
|
+
*/
|
|
17
|
+
function renderCssVariables(vars) {
|
|
18
|
+
return Object.entries(vars)
|
|
19
|
+
.map((entry) => entry.join(': '))
|
|
20
|
+
.join('; ') + ';'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Listen for theme updates from parent window
|
|
25
|
+
* Applies CSS variables to the document root
|
|
26
|
+
*/
|
|
27
|
+
window.addEventListener('message', function(event) {
|
|
28
|
+
// Only process messages with the correct structure
|
|
29
|
+
if (
|
|
30
|
+
event.data &&
|
|
31
|
+
typeof event.data === 'object' &&
|
|
32
|
+
event.data.type === 'THEME_UPDATE'
|
|
33
|
+
) {
|
|
34
|
+
const themeUpdate = event.data
|
|
35
|
+
|
|
36
|
+
// Get the style element where theme variables are injected
|
|
37
|
+
const themeStyle = document.getElementById('linktree-theme')
|
|
38
|
+
|
|
39
|
+
if (!themeStyle) {
|
|
40
|
+
console.warn('linktree-theme style element not found')
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Inject CSS variables into :root
|
|
45
|
+
themeStyle.textContent = ':root { ' + renderCssVariables(themeUpdate.payload.variables) + ' }'
|
|
46
|
+
|
|
47
|
+
// Remove any existing theme classes
|
|
48
|
+
const classesToRemove = []
|
|
49
|
+
document.documentElement.classList.forEach((className) => {
|
|
50
|
+
if (className.startsWith('linktree-theme-')) {
|
|
51
|
+
classesToRemove.push(className)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
classesToRemove.forEach((className) => {
|
|
55
|
+
document.documentElement.classList.remove(className)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// Add theme class for additional styling hooks
|
|
59
|
+
if (themeUpdate.payload.name && themeUpdate.payload.name !== 'legacy') {
|
|
60
|
+
document.documentElement.classList.add('linktree-theme-' + themeUpdate.payload.name)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, false)
|
|
64
|
+
</script>
|
|
7
65
|
</head>
|
|
8
66
|
<body>
|
|
9
67
|
<div id="root"></div>
|
package/dev-server/lib/utils.ts
CHANGED