@kilivi/payloadcms-theme-management 0.2.10 → 0.2.12

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.
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Next.js Font Loader Utilities
3
+ *
4
+ * This file provides utilities for loading Google Fonts in Next.js applications
5
+ * based on theme configuration from the CMS.
6
+ *
7
+ * ## Usage Guide
8
+ *
9
+ * ### 1. Static Font Loading (Recommended)
10
+ *
11
+ * In your Next.js app's root layout:
12
+ *
13
+ * ```tsx
14
+ * // app/layout.tsx
15
+ * import { Inter, Playfair_Display } from 'next/font/google'
16
+ *
17
+ * const inter = Inter({
18
+ * subsets: ['latin'],
19
+ * variable: '--font-body',
20
+ * display: 'swap',
21
+ * })
22
+ *
23
+ * const playfair = Playfair_Display({
24
+ * subsets: ['latin'],
25
+ * variable: '--font-heading',
26
+ * display: 'swap',
27
+ * })
28
+ *
29
+ * export default function RootLayout({ children }: { children: React.ReactNode }) {
30
+ * return (
31
+ * <html lang="en" className={`${inter.variable} ${playfair.variable}`}>
32
+ * <body>{children}</body>
33
+ * </html>
34
+ * )
35
+ * }
36
+ * ```
37
+ *
38
+ * ### 2. CSS Variables Usage
39
+ *
40
+ * In your global CSS:
41
+ *
42
+ * ```css
43
+ * :root {
44
+ * --font-body: var(--font-inter), system-ui, sans-serif;
45
+ * --font-heading: var(--font-playfair), Georgia, serif;
46
+ * }
47
+ *
48
+ * body {
49
+ * font-family: var(--font-body);
50
+ * }
51
+ *
52
+ * h1, h2, h3, h4, h5, h6 {
53
+ * font-family: var(--font-heading);
54
+ * }
55
+ * ```
56
+ *
57
+ * ### 3. Dynamic Font Loading
58
+ *
59
+ * Use the helper functions below to generate font loader code:
60
+ *
61
+ * ```tsx
62
+ * import { getFontLoaderCode } from '@kilivi/payloadcms-theme-management/providers/font-loader'
63
+ *
64
+ * const themeConfig = await getThemeConfig()
65
+ * const fontCode = getFontLoaderCode(themeConfig)
66
+ * console.log(fontCode) // Copy this to your layout.tsx
67
+ * ```
68
+ */ import { jsx as _jsx } from "react/jsx-runtime";
69
+ /**
70
+ * Font mapping for next/font/google imports
71
+ * Maps theme font values to Next.js font imports
72
+ */ export const FONT_IMPORT_MAP = {
73
+ Inter: {
74
+ import: `import { Inter } from 'next/font/google'\nconst inter = Inter({ subsets: ['latin'], variable: '--font-body' })`,
75
+ variable: 'inter.variable'
76
+ },
77
+ Roboto: {
78
+ import: `import { Roboto } from 'next/font/google'\nconst roboto = Roboto({ weight: ['400', '500', '700'], subsets: ['latin'], variable: '--font-body' })`,
79
+ variable: 'roboto.variable'
80
+ },
81
+ 'Open Sans': {
82
+ import: `import { Open_Sans } from 'next/font/google'\nconst openSans = Open_Sans({ subsets: ['latin'], variable: '--font-body' })`,
83
+ variable: 'openSans.variable'
84
+ },
85
+ Lato: {
86
+ import: `import { Lato } from 'next/font/google'\nconst lato = Lato({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-body' })`,
87
+ variable: 'lato.variable'
88
+ },
89
+ Montserrat: {
90
+ import: `import { Montserrat } from 'next/font/google'\nconst montserrat = Montserrat({ subsets: ['latin'], variable: '--font-body' })`,
91
+ variable: 'montserrat.variable'
92
+ },
93
+ Poppins: {
94
+ import: `import { Poppins } from 'next/font/google'\nconst poppins = Poppins({ weight: ['400', '500', '600', '700'], subsets: ['latin'], variable: '--font-body' })`,
95
+ variable: 'poppins.variable'
96
+ },
97
+ 'Playfair Display': {
98
+ import: `import { Playfair_Display } from 'next/font/google'\nconst playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-heading' })`,
99
+ variable: 'playfair.variable'
100
+ },
101
+ Merriweather: {
102
+ import: `import { Merriweather } from 'next/font/google'\nconst merriweather = Merriweather({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-heading' })`,
103
+ variable: 'merriweather.variable'
104
+ },
105
+ Lora: {
106
+ import: `import { Lora } from 'next/font/google'\nconst lora = Lora({ subsets: ['latin'], variable: '--font-heading' })`,
107
+ variable: 'lora.variable'
108
+ },
109
+ 'Crimson Text': {
110
+ import: `import { Crimson_Text } from 'next/font/google'\nconst crimsonText = Crimson_Text({ weight: ['400', '600', '700'], subsets: ['latin'], variable: '--font-heading' })`,
111
+ variable: 'crimsonText.variable'
112
+ }
113
+ };
114
+ /**
115
+ * Generate Next.js font loader code for your layout
116
+ *
117
+ * @param config - Theme configuration from CMS
118
+ * @returns String with complete Next.js font loading code
119
+ *
120
+ * @example
121
+ * ```tsx
122
+ * const code = getFontLoaderCode({ bodyFont: 'Inter', headingFont: 'Playfair Display' })
123
+ * console.log(code)
124
+ * // Copy the output to your app/layout.tsx file
125
+ * ```
126
+ */ export function getFontLoaderCode(config) {
127
+ const imports = [];
128
+ const variables = [];
129
+ if (config.bodyFont && config.bodyFont !== 'preset' && config.bodyFont !== 'custom') {
130
+ const fontConfig = FONT_IMPORT_MAP[config.bodyFont];
131
+ if (fontConfig) {
132
+ imports.push(fontConfig.import);
133
+ variables.push(fontConfig.variable);
134
+ }
135
+ }
136
+ if (config.headingFont && config.headingFont !== 'preset' && config.headingFont !== 'custom') {
137
+ const fontConfig = FONT_IMPORT_MAP[config.headingFont];
138
+ if (fontConfig) {
139
+ imports.push(fontConfig.import);
140
+ variables.push(fontConfig.variable);
141
+ }
142
+ }
143
+ return `// app/layout.tsx
144
+ ${imports.join('\n\n')}
145
+
146
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
147
+ return (
148
+ <html lang="en" className={\`${variables.join(' ')}\`}>
149
+ <body>{children}</body>
150
+ </html>
151
+ )
152
+ }
153
+ `;
154
+ }
155
+ /**
156
+ * Get font family CSS strings for inline styles
157
+ *
158
+ * @param config - Theme configuration
159
+ * @returns Object with bodyFont and headingFont CSS font-family strings
160
+ */ export function getThemeFontFamilies(config) {
161
+ const result = {};
162
+ // Body font
163
+ if (config.bodyFont === 'custom' && config.bodyFontCustom) {
164
+ result.bodyFont = config.bodyFontCustom;
165
+ } else if (config.bodyFont && config.bodyFont !== 'preset') {
166
+ result.bodyFont = `var(--font-body), ${config.bodyFont}, sans-serif`;
167
+ }
168
+ // Heading font
169
+ if (config.headingFont === 'custom' && config.headingFontCustom) {
170
+ result.headingFont = config.headingFontCustom;
171
+ } else if (config.headingFont && config.headingFont !== 'preset') {
172
+ result.headingFont = `var(--font-heading), ${config.headingFont}, serif`;
173
+ }
174
+ return result;
175
+ }
176
+ /**
177
+ * React component wrapper for font variables
178
+ * Use this to inject font CSS variables into your app
179
+ */ export function ThemeFontProvider({ children, bodyFont, headingFont, bodyFontCustom, headingFontCustom }) {
180
+ const fonts = getThemeFontFamilies({
181
+ bodyFont,
182
+ headingFont,
183
+ bodyFontCustom,
184
+ headingFontCustom
185
+ });
186
+ return /*#__PURE__*/ _jsx("div", {
187
+ style: {
188
+ '--font-body': fonts.bodyFont,
189
+ '--font-heading': fonts.headingFont
190
+ },
191
+ children: children
192
+ });
193
+ }
194
+ /**
195
+ * Client-side hook for accessing theme fonts
196
+ * Use this in client components to read font CSS variables
197
+ */ export function useThemeFonts() {
198
+ if (typeof window === 'undefined') {
199
+ return {
200
+ bodyFont: undefined,
201
+ headingFont: undefined
202
+ };
203
+ }
204
+ const bodyFont = getComputedStyle(document.documentElement).getPropertyValue('--font-body');
205
+ const headingFont = getComputedStyle(document.documentElement).getPropertyValue('--font-heading');
206
+ return {
207
+ bodyFont: bodyFont || undefined,
208
+ headingFont: headingFont || undefined
209
+ };
210
+ }
211
+
212
+ //# sourceMappingURL=font-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/providers/font-loader.tsx"],"sourcesContent":["/**\n * Next.js Font Loader Utilities\n *\n * This file provides utilities for loading Google Fonts in Next.js applications\n * based on theme configuration from the CMS.\n *\n * ## Usage Guide\n *\n * ### 1. Static Font Loading (Recommended)\n *\n * In your Next.js app's root layout:\n *\n * ```tsx\n * // app/layout.tsx\n * import { Inter, Playfair_Display } from 'next/font/google'\n *\n * const inter = Inter({\n * subsets: ['latin'],\n * variable: '--font-body',\n * display: 'swap',\n * })\n *\n * const playfair = Playfair_Display({\n * subsets: ['latin'],\n * variable: '--font-heading',\n * display: 'swap',\n * })\n *\n * export default function RootLayout({ children }: { children: React.ReactNode }) {\n * return (\n * <html lang=\"en\" className={`${inter.variable} ${playfair.variable}`}>\n * <body>{children}</body>\n * </html>\n * )\n * }\n * ```\n *\n * ### 2. CSS Variables Usage\n *\n * In your global CSS:\n *\n * ```css\n * :root {\n * --font-body: var(--font-inter), system-ui, sans-serif;\n * --font-heading: var(--font-playfair), Georgia, serif;\n * }\n *\n * body {\n * font-family: var(--font-body);\n * }\n *\n * h1, h2, h3, h4, h5, h6 {\n * font-family: var(--font-heading);\n * }\n * ```\n *\n * ### 3. Dynamic Font Loading\n *\n * Use the helper functions below to generate font loader code:\n *\n * ```tsx\n * import { getFontLoaderCode } from '@kilivi/payloadcms-theme-management/providers/font-loader'\n *\n * const themeConfig = await getThemeConfig()\n * const fontCode = getFontLoaderCode(themeConfig)\n * console.log(fontCode) // Copy this to your layout.tsx\n * ```\n */\n\ninterface ThemeConfig {\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}\n\n/**\n * Font mapping for next/font/google imports\n * Maps theme font values to Next.js font imports\n */\nexport const FONT_IMPORT_MAP: Record<string, { import: string; variable: string }> = {\n Inter: {\n import: `import { Inter } from 'next/font/google'\\nconst inter = Inter({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'inter.variable',\n },\n Roboto: {\n import: `import { Roboto } from 'next/font/google'\\nconst roboto = Roboto({ weight: ['400', '500', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'roboto.variable',\n },\n 'Open Sans': {\n import: `import { Open_Sans } from 'next/font/google'\\nconst openSans = Open_Sans({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'openSans.variable',\n },\n Lato: {\n import: `import { Lato } from 'next/font/google'\\nconst lato = Lato({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'lato.variable',\n },\n Montserrat: {\n import: `import { Montserrat } from 'next/font/google'\\nconst montserrat = Montserrat({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'montserrat.variable',\n },\n Poppins: {\n import: `import { Poppins } from 'next/font/google'\\nconst poppins = Poppins({ weight: ['400', '500', '600', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'poppins.variable',\n },\n 'Playfair Display': {\n import: `import { Playfair_Display } from 'next/font/google'\\nconst playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'playfair.variable',\n },\n Merriweather: {\n import: `import { Merriweather } from 'next/font/google'\\nconst merriweather = Merriweather({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'merriweather.variable',\n },\n Lora: {\n import: `import { Lora } from 'next/font/google'\\nconst lora = Lora({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'lora.variable',\n },\n 'Crimson Text': {\n import: `import { Crimson_Text } from 'next/font/google'\\nconst crimsonText = Crimson_Text({ weight: ['400', '600', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'crimsonText.variable',\n },\n}\n\n/**\n * Generate Next.js font loader code for your layout\n *\n * @param config - Theme configuration from CMS\n * @returns String with complete Next.js font loading code\n *\n * @example\n * ```tsx\n * const code = getFontLoaderCode({ bodyFont: 'Inter', headingFont: 'Playfair Display' })\n * console.log(code)\n * // Copy the output to your app/layout.tsx file\n * ```\n */\nexport function getFontLoaderCode(config: ThemeConfig): string {\n const imports: string[] = []\n const variables: string[] = []\n\n if (config.bodyFont && config.bodyFont !== 'preset' && config.bodyFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.bodyFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n if (config.headingFont && config.headingFont !== 'preset' && config.headingFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.headingFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n return `// app/layout.tsx\n${imports.join('\\n\\n')}\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n return (\n <html lang=\"en\" className={\\`${variables.join(' ')}\\`}>\n <body>{children}</body>\n </html>\n )\n}\n`\n}\n\n/**\n * Get font family CSS strings for inline styles\n *\n * @param config - Theme configuration\n * @returns Object with bodyFont and headingFont CSS font-family strings\n */\nexport function getThemeFontFamilies(config: ThemeConfig): {\n bodyFont?: string\n headingFont?: string\n} {\n const result: { bodyFont?: string; headingFont?: string } = {}\n\n // Body font\n if (config.bodyFont === 'custom' && config.bodyFontCustom) {\n result.bodyFont = config.bodyFontCustom\n } else if (config.bodyFont && config.bodyFont !== 'preset') {\n result.bodyFont = `var(--font-body), ${config.bodyFont}, sans-serif`\n }\n\n // Heading font\n if (config.headingFont === 'custom' && config.headingFontCustom) {\n result.headingFont = config.headingFontCustom\n } else if (config.headingFont && config.headingFont !== 'preset') {\n result.headingFont = `var(--font-heading), ${config.headingFont}, serif`\n }\n\n return result\n}\n\n/**\n * React component wrapper for font variables\n * Use this to inject font CSS variables into your app\n */\nexport function ThemeFontProvider({\n children,\n bodyFont,\n headingFont,\n bodyFontCustom,\n headingFontCustom,\n}: {\n children: React.ReactNode\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}) {\n const fonts = getThemeFontFamilies({ bodyFont, headingFont, bodyFontCustom, headingFontCustom })\n\n return (\n <div\n style={\n {\n '--font-body': fonts.bodyFont,\n '--font-heading': fonts.headingFont,\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n )\n}\n\n/**\n * Client-side hook for accessing theme fonts\n * Use this in client components to read font CSS variables\n */\nexport function useThemeFonts() {\n if (typeof window === 'undefined') {\n return { bodyFont: undefined, headingFont: undefined }\n }\n\n const bodyFont = getComputedStyle(document.documentElement).getPropertyValue('--font-body')\n const headingFont = getComputedStyle(document.documentElement).getPropertyValue('--font-heading')\n\n return {\n bodyFont: bodyFont || undefined,\n headingFont: headingFont || undefined,\n }\n}\n"],"names":["FONT_IMPORT_MAP","Inter","import","variable","Roboto","Lato","Montserrat","Poppins","Merriweather","Lora","getFontLoaderCode","config","imports","variables","bodyFont","fontConfig","push","headingFont","join","getThemeFontFamilies","result","bodyFontCustom","headingFontCustom","ThemeFontProvider","children","fonts","div","style","useThemeFonts","window","undefined","getComputedStyle","document","documentElement","getPropertyValue"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kilivi/payloadcms-theme-management",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Theme configuration plugin for Payload CMS v3",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",