@kilivi/payloadcms-theme-management 0.5.9 β 1.0.0
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/README.md +531 -40
- package/dist/app/api/google-fonts/route.d.ts +31 -0
- package/dist/app/api/google-fonts/route.d.ts.map +1 -0
- package/dist/app/api/google-fonts/route.js +925 -0
- package/dist/app/api/google-fonts/route.js.map +1 -0
- package/dist/fields/themeConfigurationField.d.ts.map +1 -1
- package/dist/fields/themeConfigurationField.js +16 -8
- package/dist/fields/themeConfigurationField.js.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.d.ts +17 -0
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.js +229 -0
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.js.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/PreviewContent.d.ts +20 -0
- package/dist/globals/ThemeSettings/FontPicker/PreviewContent.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/PreviewContent.js +400 -0
- package/dist/globals/ThemeSettings/FontPicker/PreviewContent.js.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/index.d.ts +25 -0
- package/dist/globals/ThemeSettings/FontPicker/index.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/index.js +483 -0
- package/dist/globals/ThemeSettings/FontPicker/index.js.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/styles.css +337 -0
- package/dist/globals/ThemeSettings/FontPicker/translations.d.ts +76 -0
- package/dist/globals/ThemeSettings/FontPicker/translations.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/FontPicker/translations.js +147 -0
- package/dist/globals/ThemeSettings/FontPicker/translations.js.map +1 -0
- package/dist/globals/ThemeSettings/config.d.ts +10 -0
- package/dist/globals/ThemeSettings/config.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/config.js +171 -0
- package/dist/globals/ThemeSettings/config.js.map +1 -0
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.d.ts +5 -0
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js +177 -0
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js.map +1 -0
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.d.ts +5 -0
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.js +89 -0
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.js.map +1 -0
- package/dist/globals/ThemeSettings/index.d.ts +4 -0
- package/dist/globals/ThemeSettings/index.d.ts.map +1 -0
- package/dist/globals/ThemeSettings/index.js +4 -0
- package/dist/globals/ThemeSettings/index.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +119 -20
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/getThemeSettings.d.ts +34 -0
- package/dist/utilities/getThemeSettings.d.ts.map +1 -0
- package/dist/utilities/getThemeSettings.js +67 -0
- package/dist/utilities/getThemeSettings.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,23 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
A comprehensive theme management plugin for Payload CMS v3 that provides powerful theming capabilities with SSR support, preventing FOUC (Flash of Unstyled Content).
|
|
4
4
|
|
|
5
|
-
## π Version 0.
|
|
5
|
+
## π Version 0.6.0 - New Features!
|
|
6
6
|
|
|
7
|
+
- **β
Standalone Global Support** - Create separate appearance settings as a global
|
|
8
|
+
- **β
Auto-Populate Light/Dark Colors** - Theme selection hook automatically fills color fields
|
|
9
|
+
- **β
Multi-Tenant Ready** - Full support for multi-tenant applications
|
|
10
|
+
- **β
Cleaner Data Structure** - Fixed nesting issues for better API integration
|
|
7
11
|
- **β
Live Theme Preview** - Real-time theme preview in admin panel at `/admin/theme-preview`
|
|
8
12
|
- **β
Professional Color Picker** - Enhanced color picker with react-colorful library
|
|
9
|
-
- **β
Streamlined Tokens** - Optimized to 24 essential color tokens
|
|
10
|
-
- **β
Tabs Structure** - Plugin creates a "NastavenΓ vzhledu" (Appearance Settings) tab
|
|
11
|
-
- **β
Extended Theme Support** - OKLCH color format with semantic tokens
|
|
12
13
|
- **β
shadcn/ui Compatible** - Works with https://ui.shadcn.com/themes
|
|
13
14
|
- **β
TweakCN Compatible** - Works with https://tweakcn.com/editor/theme
|
|
14
|
-
- **β
Chart Colors** - 5 customizable colors for data visualization
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
18
|
- π¨ **Multiple Theme Presets** - Cool, Brutal, Neon, Solar, and more
|
|
19
|
+
- π― **Auto-Populate Colors** - Theme selection automatically sets Light/Dark mode colors
|
|
20
|
+
- π **Standalone Global** - Create separate appearance settings global (v0.6.0+)
|
|
19
21
|
- πΌοΈ **Live Theme Preview** - Real-time preview in admin panel (no configuration needed!)
|
|
20
22
|
- π¨ **Extended Themes** - OKLCH-based themes with full shadcn/ui token support
|
|
21
|
-
- π¨ **Custom Color Palette** - Full HSL color customization (
|
|
23
|
+
- π¨ **Custom Color Palette** - Full HSL color customization (19 semantic tokens)
|
|
22
24
|
- π€ **Typography Control** - Google Fonts integration for headings, body, and code
|
|
23
25
|
- π **Border Radius Presets** - Sharp, Rounded, or Pill styles
|
|
24
26
|
- π **Dark Mode Support** - Built-in light/dark/system mode toggle
|
|
@@ -27,6 +29,7 @@ A comprehensive theme management plugin for Payload CMS v3 that provides powerfu
|
|
|
27
29
|
- β‘ **Performance Optimized** - Critical CSS inlining, preload links
|
|
28
30
|
- π― **Type Safe** - Full TypeScript support
|
|
29
31
|
- π§ **Highly Configurable** - Flexible plugin options
|
|
32
|
+
- π₯ **Multi-Tenant Support** - Built-in multi-tenant capabilities
|
|
30
33
|
|
|
31
34
|
## Installation
|
|
32
35
|
|
|
@@ -42,6 +45,8 @@ yarn add @kilivi/payloadcms-theme-management
|
|
|
42
45
|
|
|
43
46
|
### 1. Add Plugin to Payload Config
|
|
44
47
|
|
|
48
|
+
#### Option A: Add as Tab to Existing Collection (Default)
|
|
49
|
+
|
|
45
50
|
```typescript
|
|
46
51
|
import { themeManagementPlugin } from '@kilivi/payloadcms-theme-management'
|
|
47
52
|
import { buildConfig } from 'payload'
|
|
@@ -49,7 +54,7 @@ import { buildConfig } from 'payload'
|
|
|
49
54
|
export default buildConfig({
|
|
50
55
|
// ... other config
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
collections: [
|
|
53
58
|
{
|
|
54
59
|
slug: 'site-settings',
|
|
55
60
|
fields: [
|
|
@@ -57,7 +62,7 @@ export default buildConfig({
|
|
|
57
62
|
name: 'siteName',
|
|
58
63
|
type: 'text',
|
|
59
64
|
},
|
|
60
|
-
// Theme configuration will be injected here
|
|
65
|
+
// Theme configuration will be injected here as a tab inside this collection
|
|
61
66
|
],
|
|
62
67
|
},
|
|
63
68
|
],
|
|
@@ -74,10 +79,37 @@ export default buildConfig({
|
|
|
74
79
|
})
|
|
75
80
|
```
|
|
76
81
|
|
|
82
|
+
> **Note:** Option A injects an **Appearance Settings** tab into the specified collection (`targetCollection`). If you prefer a separate global (standalone settings), use **Option B** below and set `useStandaloneCollection: true` in the plugin options.
|
|
83
|
+
|
|
84
|
+
#### Option B: Create Standalone Global (Separate Settings)
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { themeManagementPlugin } from '@kilivi/payloadcms-theme-management'
|
|
88
|
+
import { buildConfig } from 'payload'
|
|
89
|
+
|
|
90
|
+
export default buildConfig({
|
|
91
|
+
// ... other config
|
|
92
|
+
|
|
93
|
+
plugins: [
|
|
94
|
+
themeManagementPlugin({
|
|
95
|
+
enabled: true,
|
|
96
|
+
useStandaloneCollection: true, // Creates a separate global
|
|
97
|
+
standaloneCollectionSlug: 'appearance-settings', // Optional: custom slug
|
|
98
|
+
standaloneCollectionLabel: 'Appearance Settings', // Optional: custom label
|
|
99
|
+
defaultTheme: 'cool',
|
|
100
|
+
includeColorModeToggle: true,
|
|
101
|
+
enableLogging: true,
|
|
102
|
+
}),
|
|
103
|
+
],
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
77
107
|
### 2. Add Server Theme Injection (Next.js)
|
|
78
108
|
|
|
79
109
|
**β οΈ IMPORTANT:** Import from `/server` entry point!
|
|
80
110
|
|
|
111
|
+
#### If Using Default (Tab in existing collection):
|
|
112
|
+
|
|
81
113
|
```tsx
|
|
82
114
|
// app/layout.tsx
|
|
83
115
|
import { ServerThemeInjector } from '@kilivi/payloadcms-theme-management/server'
|
|
@@ -88,7 +120,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|
|
88
120
|
const payload = await getPayload({ config: configPromise })
|
|
89
121
|
|
|
90
122
|
const { docs } = await payload.find({
|
|
91
|
-
collection: 'site-settings',
|
|
123
|
+
collection: 'site-settings', // Your target collection
|
|
92
124
|
limit: 1,
|
|
93
125
|
})
|
|
94
126
|
|
|
@@ -103,6 +135,33 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|
|
103
135
|
}
|
|
104
136
|
```
|
|
105
137
|
|
|
138
|
+
#### If Using Standalone Global:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
// app/layout.tsx
|
|
142
|
+
import { ServerThemeInjector } from '@kilivi/payloadcms-theme-management/server'
|
|
143
|
+
import configPromise from '@payload-config'
|
|
144
|
+
import { getPayload } from 'payload'
|
|
145
|
+
|
|
146
|
+
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
|
147
|
+
const payload = await getPayload({ config: configPromise })
|
|
148
|
+
|
|
149
|
+
// Fetch from standalone global
|
|
150
|
+
const appearanceSettings = await payload.globals.findBySlug({
|
|
151
|
+
slug: 'appearance-settings', // Your standalone global slug
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<html lang="en">
|
|
156
|
+
<head>
|
|
157
|
+
<ServerThemeInjector themeConfiguration={appearanceSettings?.themeConfiguration} />
|
|
158
|
+
</head>
|
|
159
|
+
<body>{children}</body>
|
|
160
|
+
</html>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
106
165
|
### 3. Use Theme Variables in Your CSS
|
|
107
166
|
|
|
108
167
|
The plugin injects CSS custom properties you can use:
|
|
@@ -124,17 +183,20 @@ Or with Tailwind CSS:
|
|
|
124
183
|
|
|
125
184
|
## Plugin Configuration Options
|
|
126
185
|
|
|
127
|
-
| Option
|
|
128
|
-
|
|
|
129
|
-
| `enabled`
|
|
130
|
-
| `targetCollection`
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
186
|
+
| Option | Type | Default | Description |
|
|
187
|
+
| --------------------------- | ---------------------------------- | ----------------------- | ----------------------------------------------------------------- |
|
|
188
|
+
| `enabled` | `boolean` | `true` | Enable/disable the plugin |
|
|
189
|
+
| `targetCollection` | `string` | `'site-settings'` | Collection slug to add theme field to (when not using standalone) |
|
|
190
|
+
| `useStandaloneCollection` | `boolean` | `false` | Create a separate global instead of adding as a tab |
|
|
191
|
+
| `standaloneCollectionSlug` | `string` | `'appearance-settings'` | Slug for the standalone global |
|
|
192
|
+
| `standaloneCollectionLabel` | `string \| Record<string, string>` | `'Appearance Settings'` | Label for the standalone global (supports i18n) |
|
|
193
|
+
| `themePresets` | `ThemePreset[]` | Built-in presets | Custom theme presets |
|
|
194
|
+
| `defaultTheme` | `string` | `'cool'` | Default theme preset name |
|
|
195
|
+
| `includeColorModeToggle` | `boolean` | `true` | Show light/dark mode toggle |
|
|
196
|
+
| `includeCustomCSS` | `boolean` | `true` | Allow custom CSS injection |
|
|
197
|
+
| `includeBrandIdentity` | `boolean` | `false` | Show brand identity fields |
|
|
198
|
+
| `enableAdvancedFeatures` | `boolean` | `true` | Enable advanced customization |
|
|
199
|
+
| `enableLogging` | `boolean` | `false` | Log plugin actions to console |
|
|
138
200
|
|
|
139
201
|
## Available Theme Presets
|
|
140
202
|
|
|
@@ -222,33 +284,433 @@ import { ThemeTokenSelectField } from '@kilivi/payloadcms-theme-management/field
|
|
|
222
284
|
|
|
223
285
|
### With Tailwind CSS
|
|
224
286
|
|
|
225
|
-
|
|
226
|
-
// tailwind.config.ts
|
|
227
|
-
import type { Config } from 'tailwindcss'
|
|
287
|
+
#### tailwind.config.mjs
|
|
228
288
|
|
|
229
|
-
|
|
289
|
+
```typescript
|
|
290
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
291
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
292
|
+
/* eslint-disable import/no-anonymous-default-export */
|
|
293
|
+
import defaultTheme from 'tailwindcss/defaultTheme'
|
|
294
|
+
|
|
295
|
+
/** @type {import('tailwindcss').Config} */
|
|
296
|
+
export default {
|
|
297
|
+
darkMode: ['class'],
|
|
298
|
+
content: [
|
|
299
|
+
'./src/app/**/*.{ts,tsx}',
|
|
300
|
+
'./src/components/**/*.{ts,tsx}',
|
|
301
|
+
'./src/collections/**/*.{ts,tsx}',
|
|
302
|
+
'./src/providers/**/*.{ts,tsx}',
|
|
303
|
+
'./src/heros/**/*.{ts,tsx}',
|
|
304
|
+
],
|
|
305
|
+
safelist: [
|
|
306
|
+
// Grid columns
|
|
307
|
+
'col-span-4',
|
|
308
|
+
'md:col-span-2',
|
|
309
|
+
'lg:col-span-4',
|
|
310
|
+
'lg:col-span-6',
|
|
311
|
+
'lg:col-span-8',
|
|
312
|
+
'lg:col-span-12',
|
|
313
|
+
// Border colors
|
|
314
|
+
'border-border',
|
|
315
|
+
'border-error',
|
|
316
|
+
'border-success',
|
|
317
|
+
'border-warning',
|
|
318
|
+
// Background colors
|
|
319
|
+
'bg-card',
|
|
320
|
+
'bg-error/30',
|
|
321
|
+
'bg-success/30',
|
|
322
|
+
'bg-warning/30',
|
|
323
|
+
],
|
|
230
324
|
theme: {
|
|
325
|
+
container: {
|
|
326
|
+
center: true,
|
|
327
|
+
padding: {
|
|
328
|
+
DEFAULT: 'var(--layout-containerPadding)',
|
|
329
|
+
md: 'var(--layout-containerPaddingTablet)',
|
|
330
|
+
lg: 'var(--layout-containerPaddingDesktop)',
|
|
331
|
+
},
|
|
332
|
+
screens: {
|
|
333
|
+
sm: '640px',
|
|
334
|
+
md: '768px',
|
|
335
|
+
lg: '1024px',
|
|
336
|
+
xl: '1280px',
|
|
337
|
+
},
|
|
338
|
+
},
|
|
231
339
|
extend: {
|
|
232
340
|
colors: {
|
|
233
|
-
background: '
|
|
234
|
-
foreground: '
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
341
|
+
background: 'var(--background)',
|
|
342
|
+
foreground: 'var(--foreground)',
|
|
343
|
+
card: 'var(--card)',
|
|
344
|
+
'card-foreground': 'var(--card-foreground)',
|
|
345
|
+
popover: 'var(--popover)',
|
|
346
|
+
'popover-foreground': 'var(--popover-foreground)',
|
|
347
|
+
primary: 'var(--primary)',
|
|
348
|
+
'primary-foreground': 'var(--primary-foreground)',
|
|
349
|
+
secondary: 'var(--secondary)',
|
|
350
|
+
'secondary-foreground': 'var(--secondary-foreground)',
|
|
351
|
+
muted: 'var(--muted)',
|
|
352
|
+
'muted-foreground': 'var(--muted-foreground)',
|
|
353
|
+
accent: 'var(--accent)',
|
|
354
|
+
'accent-foreground': 'var(--accent-foreground)',
|
|
355
|
+
destructive: 'var(--destructive)',
|
|
356
|
+
'destructive-foreground': 'var(--destructive-foreground)',
|
|
357
|
+
border: 'var(--border)',
|
|
358
|
+
input: 'var(--input)',
|
|
359
|
+
ring: 'var(--ring)',
|
|
360
|
+
success: 'var(--success)',
|
|
361
|
+
'success-foreground': 'var(--success-foreground)',
|
|
362
|
+
warning: 'var(--warning)',
|
|
363
|
+
'warning-foreground': 'var(--warning-foreground)',
|
|
364
|
+
error: 'var(--error)',
|
|
365
|
+
'error-foreground': 'var(--error-foreground)',
|
|
366
|
+
info: 'var(--info)',
|
|
367
|
+
'info-foreground': 'var(--info-foreground)',
|
|
240
368
|
},
|
|
241
369
|
borderRadius: {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
370
|
+
sm: 'var(--radius-small)',
|
|
371
|
+
DEFAULT: 'var(--radius-default)',
|
|
372
|
+
md: 'var(--radius-medium)',
|
|
373
|
+
lg: 'var(--radius-large)',
|
|
245
374
|
},
|
|
246
375
|
fontFamily: {
|
|
247
|
-
|
|
248
|
-
|
|
376
|
+
sans: ['var(--typography-fontFamily)', ...defaultTheme.fontFamily.sans],
|
|
377
|
+
heading: ['var(--typography-headingFamily)', ...defaultTheme.fontFamily.sans],
|
|
378
|
+
mono: ['var(--font-geist-mono)', ...defaultTheme.fontFamily.mono],
|
|
379
|
+
},
|
|
380
|
+
fontSize: {
|
|
381
|
+
base: ['var(--typography-baseFontSize)', { lineHeight: 'var(--typography-lineHeight)' }],
|
|
382
|
+
},
|
|
383
|
+
letterSpacing: {
|
|
384
|
+
tight: 'var(--typography-letterSpacing-tight)',
|
|
385
|
+
normal: 'var(--typography-letterSpacing-normal)',
|
|
386
|
+
wide: 'var(--typography-letterSpacing-wide)',
|
|
387
|
+
},
|
|
388
|
+
fontWeight: {
|
|
389
|
+
normal: 'var(--typography-fontWeights-normal)',
|
|
390
|
+
medium: 'var(--typography-fontWeights-medium)',
|
|
391
|
+
semibold: 'var(--typography-fontWeights-semibold)',
|
|
392
|
+
bold: 'var(--typography-fontWeights-bold)',
|
|
393
|
+
},
|
|
394
|
+
spacing: {
|
|
395
|
+
section: {
|
|
396
|
+
DEFAULT: 'var(--layout-sectionSpacing)',
|
|
397
|
+
md: 'var(--layout-sectionSpacingTablet)',
|
|
398
|
+
lg: 'var(--layout-sectionSpacingDesktop)',
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
transitionProperty: {
|
|
402
|
+
button: 'var(--components-button-transition)',
|
|
403
|
+
},
|
|
404
|
+
scale: {
|
|
405
|
+
'button-hover': 'var(--components-button-hover-scale)',
|
|
406
|
+
},
|
|
407
|
+
opacity: {
|
|
408
|
+
'button-hover': 'var(--components-button-hover-opacity)',
|
|
409
|
+
},
|
|
410
|
+
boxShadow: {
|
|
411
|
+
card: 'var(--components-card-shadow)',
|
|
412
|
+
},
|
|
413
|
+
padding: {
|
|
414
|
+
card: 'var(--components-card-padding)',
|
|
415
|
+
button: 'var(--components-button-padding)',
|
|
416
|
+
input: 'var(--components-input-padding)',
|
|
417
|
+
},
|
|
418
|
+
height: {
|
|
419
|
+
input: 'var(--components-input-height)',
|
|
420
|
+
},
|
|
421
|
+
typography: ({ theme }) => ({
|
|
422
|
+
DEFAULT: {
|
|
423
|
+
css: {
|
|
424
|
+
'--tw-prose-body': theme('colors.foreground'),
|
|
425
|
+
'--tw-prose-headings': theme('colors.foreground'),
|
|
426
|
+
'--tw-prose-lead': theme('colors.muted.foreground'),
|
|
427
|
+
'--tw-prose-links': theme('colors.primary'),
|
|
428
|
+
'--tw-prose-bold': theme('colors.foreground'),
|
|
429
|
+
'--tw-prose-counters': theme('colors.foreground'),
|
|
430
|
+
'--tw-prose-bullets': theme('colors.foreground'),
|
|
431
|
+
'--tw-prose-hr': theme('colors.border'),
|
|
432
|
+
'--tw-prose-quotes': theme('colors.foreground'),
|
|
433
|
+
'--tw-prose-quote-borders': theme('colors.border'),
|
|
434
|
+
'--tw-prose-captions': theme('colors.muted.foreground'),
|
|
435
|
+
'--tw-prose-code': theme('colors.foreground'),
|
|
436
|
+
'--tw-prose-pre-code': theme('colors.foreground'),
|
|
437
|
+
'--tw-prose-pre-bg': theme('colors.muted'),
|
|
438
|
+
'--tw-prose-th-borders': theme('colors.border'),
|
|
439
|
+
'--tw-prose-td-borders': theme('colors.border'),
|
|
440
|
+
h1: {
|
|
441
|
+
fontWeight: 'var(--typography-fontWeights-bold)',
|
|
442
|
+
marginBottom: '0.25em',
|
|
443
|
+
fontFamily: theme('fontFamily.heading'),
|
|
444
|
+
letterSpacing: 'var(--typography-letterSpacing-tight)',
|
|
445
|
+
},
|
|
446
|
+
h2: {
|
|
447
|
+
fontFamily: theme('fontFamily.heading'),
|
|
448
|
+
fontWeight: 'var(--typography-fontWeights-semibold)',
|
|
449
|
+
letterSpacing: 'var(--typography-letterSpacing-tight)',
|
|
450
|
+
},
|
|
451
|
+
h3: {
|
|
452
|
+
fontFamily: theme('fontFamily.heading'),
|
|
453
|
+
fontWeight: 'var(--typography-fontWeights-semibold)',
|
|
454
|
+
letterSpacing: 'var(--typography-letterSpacing-tight)',
|
|
455
|
+
},
|
|
456
|
+
h4: {
|
|
457
|
+
fontFamily: theme('fontFamily.heading'),
|
|
458
|
+
fontWeight: 'var(--typography-fontWeights-medium)',
|
|
459
|
+
letterSpacing: 'var(--typography-letterSpacing-normal)',
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
base: {
|
|
464
|
+
css: [
|
|
465
|
+
{
|
|
466
|
+
h1: { fontSize: '2.5rem' },
|
|
467
|
+
h2: { fontSize: '1.25rem' },
|
|
468
|
+
},
|
|
469
|
+
],
|
|
470
|
+
},
|
|
471
|
+
md: {
|
|
472
|
+
css: [
|
|
473
|
+
{
|
|
474
|
+
h1: { fontSize: '3.5rem' },
|
|
475
|
+
h2: { fontSize: '1.5rem' },
|
|
476
|
+
},
|
|
477
|
+
],
|
|
478
|
+
},
|
|
479
|
+
invert: {
|
|
480
|
+
css: {
|
|
481
|
+
'--tw-prose-body': 'var(--foreground)',
|
|
482
|
+
'--tw-prose-headings': 'var(--foreground)',
|
|
483
|
+
'--tw-prose-lead': 'var(--muted-foreground)',
|
|
484
|
+
'--tw-prose-links': 'var(--primary)',
|
|
485
|
+
'--tw-prose-bold': 'var(--foreground)',
|
|
486
|
+
'--tw-prose-counters': 'var(--foreground)',
|
|
487
|
+
'--tw-prose-bullets': 'var(--foreground)',
|
|
488
|
+
'--tw-prose-hr': 'var(--border)',
|
|
489
|
+
'--tw-prose-quotes': 'var(--foreground)',
|
|
490
|
+
'--tw-prose-quote-borders': 'var(--border)',
|
|
491
|
+
'--tw-prose-captions': 'var(--muted-foreground)',
|
|
492
|
+
'--tw-prose-code': 'var(--foreground)',
|
|
493
|
+
'--tw-prose-pre-code': 'var(--foreground)',
|
|
494
|
+
'--tw-prose-pre-bg': 'var(--muted)',
|
|
495
|
+
'--tw-prose-th-borders': 'var(--border)',
|
|
496
|
+
'--tw-prose-td-borders': 'var(--border)',
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
}),
|
|
500
|
+
animation: {
|
|
501
|
+
'accordion-down': 'accordion-down 0.2s ease-out',
|
|
502
|
+
'accordion-up': 'accordion-up 0.2s ease-out',
|
|
503
|
+
},
|
|
504
|
+
keyframes: {
|
|
505
|
+
'accordion-down': {
|
|
506
|
+
from: { height: 0 },
|
|
507
|
+
to: { height: 'var(--radix-accordion-content-height)' },
|
|
508
|
+
},
|
|
509
|
+
'accordion-up': {
|
|
510
|
+
from: { height: 'var(--radix-accordion-content-height)' },
|
|
511
|
+
to: { height: 0 },
|
|
512
|
+
},
|
|
249
513
|
},
|
|
250
514
|
},
|
|
251
515
|
},
|
|
516
|
+
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### globals.css
|
|
521
|
+
|
|
522
|
+
```css
|
|
523
|
+
@import 'tailwindcss';
|
|
524
|
+
|
|
525
|
+
@config '../../../../../tailwind.config.mjs';
|
|
526
|
+
|
|
527
|
+
@layer base {
|
|
528
|
+
/* Theme Configuration CSS Variables */
|
|
529
|
+
:root {
|
|
530
|
+
/* Font Scale Presets */
|
|
531
|
+
--font-scale-small: 0.875;
|
|
532
|
+
--font-scale-medium: 1;
|
|
533
|
+
--font-scale-large: 1.125;
|
|
534
|
+
--font-scale-xl: 1.25;
|
|
535
|
+
|
|
536
|
+
/* Spacing Presets */
|
|
537
|
+
--spacing-compact: 0.75;
|
|
538
|
+
--spacing-comfortable: 1;
|
|
539
|
+
--spacing-spacious: 1.25;
|
|
540
|
+
--spacing-xl: 1.5;
|
|
541
|
+
|
|
542
|
+
/* Animation Levels */
|
|
543
|
+
--animation-none-duration: 0ms;
|
|
544
|
+
--animation-reduced-duration: 100ms;
|
|
545
|
+
--animation-normal-duration: 200ms;
|
|
546
|
+
--animation-enhanced-duration: 300ms;
|
|
547
|
+
|
|
548
|
+
/* Dynamic theme configuration (set by JS) */
|
|
549
|
+
--theme-font-scale: var(--font-scale-medium);
|
|
550
|
+
--theme-spacing: var(--spacing-comfortable);
|
|
551
|
+
--theme-animation-level: normal;
|
|
552
|
+
|
|
553
|
+
/* Apply spacing multiplier to layout */
|
|
554
|
+
--layout-containerPadding-scaled: calc(
|
|
555
|
+
var(--layout-containerPadding) * var(--theme-spacing, 1)
|
|
556
|
+
);
|
|
557
|
+
--layout-containerPaddingTablet-scaled: calc(
|
|
558
|
+
var(--layout-containerPaddingTablet) * var(--theme-spacing, 1)
|
|
559
|
+
);
|
|
560
|
+
--layout-containerPaddingDesktop-scaled: calc(
|
|
561
|
+
var(--layout-containerPaddingDesktop) * var(--theme-spacing, 1)
|
|
562
|
+
);
|
|
563
|
+
--layout-sectionSpacing-scaled: calc(var(--layout-sectionSpacing) * var(--theme-spacing, 1));
|
|
564
|
+
--layout-sectionSpacingTablet-scaled: calc(
|
|
565
|
+
var(--layout-sectionSpacingTablet) * var(--theme-spacing, 1)
|
|
566
|
+
);
|
|
567
|
+
--layout-sectionSpacingDesktop-scaled: calc(
|
|
568
|
+
var(--layout-sectionSpacingDesktop) * var(--theme-spacing, 1)
|
|
569
|
+
);
|
|
570
|
+
--components-card-padding-scaled: calc(
|
|
571
|
+
var(--components-card-padding) * var(--theme-spacing, 1)
|
|
572
|
+
);
|
|
573
|
+
--components-button-padding-scaled: var(--components-button-padding);
|
|
574
|
+
--components-input-padding-scaled: var(--components-input-padding);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
*,
|
|
578
|
+
*::before,
|
|
579
|
+
*::after {
|
|
580
|
+
box-sizing: border-box;
|
|
581
|
+
margin: 0;
|
|
582
|
+
padding: 0;
|
|
583
|
+
@apply border-border;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
html {
|
|
587
|
+
-webkit-text-size-adjust: 100%;
|
|
588
|
+
font-size: calc(var(--typography-baseFontSize, 16px) * var(--theme-font-scale, 1));
|
|
589
|
+
line-height: var(--typography-lineHeight, 1.5);
|
|
590
|
+
font-family: var(--typography-fontFamily, system-ui, sans-serif);
|
|
591
|
+
visibility: hidden;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/* Animation level controls */
|
|
595
|
+
[data-animation-level='none'] * {
|
|
596
|
+
animation-duration: var(--animation-none-duration) !important;
|
|
597
|
+
transition-duration: var(--animation-none-duration) !important;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
[data-animation-level='reduced'] * {
|
|
601
|
+
animation-duration: var(--animation-reduced-duration) !important;
|
|
602
|
+
transition-duration: var(--animation-reduced-duration) !important;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
[data-animation-level='normal'] * {
|
|
606
|
+
animation-duration: var(--animation-normal-duration);
|
|
607
|
+
transition-duration: var(--animation-normal-duration);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
[data-animation-level='enhanced'] * {
|
|
611
|
+
animation-duration: var(--animation-enhanced-duration);
|
|
612
|
+
transition-duration: var(--animation-enhanced-duration);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
h1,
|
|
616
|
+
h2,
|
|
617
|
+
h3,
|
|
618
|
+
h4,
|
|
619
|
+
h5,
|
|
620
|
+
h6 {
|
|
621
|
+
font-family: var(
|
|
622
|
+
--typography-headingFamily,
|
|
623
|
+
var(--typography-fontFamily, system-ui, sans-serif)
|
|
624
|
+
);
|
|
625
|
+
font-weight: var(--typography-fontWeights-bold, 700);
|
|
626
|
+
line-height: 1.2;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/* Prevent flash of unstyled content except for Storybook */
|
|
630
|
+
:root:not([data-theme]):not([data-theme-mode]):not(.sb-show-main) {
|
|
631
|
+
visibility: hidden;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
:root[data-theme][data-theme-mode],
|
|
635
|
+
.sb-show-main {
|
|
636
|
+
visibility: visible;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
html:not(.sb-show-main) {
|
|
640
|
+
opacity: 0;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
html[data-theme-mode='dark'],
|
|
644
|
+
html[data-theme-mode='light'],
|
|
645
|
+
html.sb-show-main {
|
|
646
|
+
opacity: 1;
|
|
647
|
+
transition: opacity 0ms;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/* Force immediate opacity when JS is disabled */
|
|
651
|
+
html:not([data-theme-mode]) {
|
|
652
|
+
opacity: 1;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/* Media queries for responsive layout */
|
|
656
|
+
@media (min-width: 640px) {
|
|
657
|
+
:root {
|
|
658
|
+
--layout-containerPadding: var(--layout-containerPaddingTablet, 2rem);
|
|
659
|
+
--layout-sectionSpacing: var(--layout-sectionSpacingTablet, 3rem);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
@media (min-width: 1024px) {
|
|
664
|
+
:root {
|
|
665
|
+
--layout-containerPadding: var(--layout-containerPaddingDesktop, 2rem);
|
|
666
|
+
--layout-sectionSpacing: var(--layout-sectionSpacingDesktop, 4rem);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/* Ensure dark mode styles take precedence */
|
|
671
|
+
html[data-theme-mode='dark'] {
|
|
672
|
+
color-scheme: dark;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/* Native View Transitions API - React 19 */
|
|
676
|
+
@view-transition {
|
|
677
|
+
navigation: auto;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/* Smooth fade transition for page navigation */
|
|
681
|
+
::view-transition-old(root),
|
|
682
|
+
::view-transition-new(root) {
|
|
683
|
+
animation-duration: 0.3s;
|
|
684
|
+
animation-timing-function: ease-in-out;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
::view-transition-old(root) {
|
|
688
|
+
animation-name: fade-out;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
::view-transition-new(root) {
|
|
692
|
+
animation-name: fade-in;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
@keyframes fade-out {
|
|
696
|
+
to {
|
|
697
|
+
opacity: 0;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
@keyframes fade-in {
|
|
702
|
+
from {
|
|
703
|
+
opacity: 0;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/* Respect user's reduced motion preference */
|
|
708
|
+
@media (prefers-reduced-motion: reduce) {
|
|
709
|
+
::view-transition-old(root),
|
|
710
|
+
::view-transition-new(root) {
|
|
711
|
+
animation-duration: 0.01ms !important;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
252
714
|
}
|
|
253
715
|
```
|
|
254
716
|
|
|
@@ -257,12 +719,29 @@ const config: Config = {
|
|
|
257
719
|
```typescript
|
|
258
720
|
import { fetchThemeConfiguration } from '@kilivi/payloadcms-theme-management'
|
|
259
721
|
|
|
260
|
-
//
|
|
722
|
+
// Default: fetch from 'site-settings' collection
|
|
261
723
|
const theme = await fetchThemeConfiguration()
|
|
262
724
|
|
|
263
|
-
//
|
|
725
|
+
// Fetch from standalone global
|
|
264
726
|
const theme = await fetchThemeConfiguration({
|
|
265
|
-
collectionSlug: '
|
|
727
|
+
collectionSlug: 'appearance-settings', // Your standalone global slug
|
|
728
|
+
useGlobal: true, // Set to true when using standalone global
|
|
729
|
+
depth: 2,
|
|
730
|
+
locale: 'en',
|
|
731
|
+
})
|
|
732
|
+
|
|
733
|
+
// With multi-tenant support
|
|
734
|
+
const theme = await fetchThemeConfiguration({
|
|
735
|
+
tenantSlug: 'tenant-123', // Optional: tenant identifier
|
|
736
|
+
collectionSlug: 'appearance-settings',
|
|
737
|
+
useGlobal: true,
|
|
738
|
+
depth: 2,
|
|
739
|
+
})
|
|
740
|
+
|
|
741
|
+
// From collection (default behavior)
|
|
742
|
+
const theme = await fetchThemeConfiguration({
|
|
743
|
+
collectionSlug: 'site-settings', // Collection slug
|
|
744
|
+
useGlobal: false, // Use collection endpoint
|
|
266
745
|
depth: 2,
|
|
267
746
|
locale: 'en',
|
|
268
747
|
})
|
|
@@ -423,7 +902,19 @@ Created for Payload CMS v3 applications.
|
|
|
423
902
|
|
|
424
903
|
## Changelog
|
|
425
904
|
|
|
426
|
-
### v0.
|
|
905
|
+
### v0.6.0 (Latest)
|
|
906
|
+
|
|
907
|
+
- β
**Added:** Standalone Global Support β create separate appearance settings as a global
|
|
908
|
+
- β
**Added:** Auto-populate Light/Dark colors when selecting a theme
|
|
909
|
+
- β
**Added:** Multi-tenant support and tenant-aware theme fetching
|
|
910
|
+
- β
**Fixed:** Cleaner data structure for improved API integration
|
|
911
|
+
- β
**Added:** Live Theme Preview at `/admin/theme-preview` (real-time updates)
|
|
912
|
+
- β
**Added:** Professional color picker (react-colorful)
|
|
913
|
+
- β
**Improved:** shadcn/ui and TweakCN compatibility
|
|
914
|
+
- β
**Improved:** SSR theme injection, zero FOUC, and performance optimizations
|
|
915
|
+
- β
**Updated:** Documentation and examples
|
|
916
|
+
|
|
917
|
+
### v0.1.9
|
|
427
918
|
|
|
428
919
|
- β
**Fixed:** Server/client component separation
|
|
429
920
|
- β
**Added:** `server-only` package to prevent bundling errors
|