blocks-dusted 0.1.8 → 0.1.10
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/package.json +1 -1
- package/src/commands/header.js +13 -52
- package/templates/components/HeaderDD02/Component.client.tsx +9 -0
- package/templates/components/HeaderDD02/Component.tsx +10 -0
- package/templates/components/HeaderDD02/Header.config.ts +33 -0
- package/templates/components/HeaderDD02/MobileBottomNav/index.tsx +352 -257
- package/templates/components/HeaderDD02/Nav/index.tsx +9 -0
- package/templates/components/HeaderDD02/README.md +23 -16
- package/templates/components/HeaderDD02/hooks/revalidateHeader.ts +11 -0
- package/templates/components/HeaderDD02/index.tsx +313 -229
- package/templates/components/HeaderDD02/manifest.json +32 -16
package/package.json
CHANGED
package/src/commands/header.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { writeFile } from 'node:fs/promises'
|
|
2
1
|
import { copySharedFiles, copyTemplateFiles, backupExistingDestination, plannedBackupPath } from '../installers/copyTemplateFiles.js'
|
|
3
2
|
import { checkDependencies } from '../installers/installDependencies.js'
|
|
4
3
|
import { checkRequirements } from '../installers/checkRequirements.js'
|
|
@@ -9,11 +8,7 @@ import { packageRoot } from '../utils/paths.js'
|
|
|
9
8
|
import { fileExists, validateTargetProject } from '../utils/project.js'
|
|
10
9
|
|
|
11
10
|
const SUPPORTED_HEADERS = new Set(['HeaderDD02'])
|
|
12
|
-
const
|
|
13
|
-
'src/Header/config.ts',
|
|
14
|
-
'src/Header/Nav/index.tsx',
|
|
15
|
-
'src/Header/RowLabel.tsx',
|
|
16
|
-
]
|
|
11
|
+
const ACTIVE_HEADER_DIRECTORY = 'src/Header'
|
|
17
12
|
|
|
18
13
|
export async function addHeader({ headerName, targetDirectory = process.cwd(), dryRun = false }) {
|
|
19
14
|
if (!headerName) throw new Error('A header name is required. Example: blocks-dusted header add HeaderDD02 --dry-run')
|
|
@@ -31,30 +26,17 @@ export async function addHeader({ headerName, targetDirectory = process.cwd(), d
|
|
|
31
26
|
throw new Error(`Required project files are missing:\n${missingRequired.map(formatMissingRequirement).join('\n')}`)
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const missingActive = activeFileChecks.filter((check) => !check.exists)
|
|
38
|
-
if (missingActive.length > 0) {
|
|
39
|
-
throw new Error(`Active Header files are missing:\n${missingActive.map((check) => `- ${check.path}`).join('\n')}`)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const destinationBackupPath = checks.collisions.destinationExists
|
|
43
|
-
? await plannedBackupPath({ destinationPath: checks.collisions.destinationPath, targetDirectory })
|
|
29
|
+
const activeHeaderExists = await fileExists(`${targetDirectory}/${ACTIVE_HEADER_DIRECTORY}`)
|
|
30
|
+
const activeHeaderBackupPath = activeHeaderExists
|
|
31
|
+
? await plannedBackupPath({ destinationPath: ACTIVE_HEADER_DIRECTORY, targetDirectory })
|
|
44
32
|
: null
|
|
45
|
-
const activeBackups = await Promise.all(
|
|
46
|
-
ACTIVE_HEADER_FILES.map(async (path) => ({
|
|
47
|
-
path,
|
|
48
|
-
backupPath: await plannedBackupPath({ destinationPath: path, targetDirectory }),
|
|
49
|
-
})),
|
|
50
|
-
)
|
|
51
33
|
|
|
52
34
|
heading('Header workflow')
|
|
53
35
|
info(`Name: ${manifest.name}`)
|
|
54
36
|
info(`Target directory: ${targetDirectory}`)
|
|
55
37
|
info(`Payload config: ${project.payloadConfigPath}`)
|
|
56
38
|
info(`Source template path: ${templateDirectory}`)
|
|
57
|
-
info(`
|
|
39
|
+
info(`Active Header path: ${ACTIVE_HEADER_DIRECTORY}`)
|
|
58
40
|
|
|
59
41
|
heading(dryRun ? 'Files that would be installed' : 'Files to install')
|
|
60
42
|
for (const file of manifest.files) item(`${file.from} -> ${file.to}`)
|
|
@@ -73,17 +55,13 @@ export async function addHeader({ headerName, targetDirectory = process.cwd(), d
|
|
|
73
55
|
}
|
|
74
56
|
if (dependencyChecks.missing.length > 0) item(`Install command: ${installCommandText(dependencyChecks.packageManager, dependencyChecks.missing)}`)
|
|
75
57
|
|
|
76
|
-
heading('Active Header
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
if (destinationBackupPath) {
|
|
81
|
-
item(dryRun ? `Would back up ${checks.collisions.destinationPath} to ${destinationBackupPath}` : `Will back up ${checks.collisions.destinationPath} to ${destinationBackupPath}`)
|
|
82
|
-
}
|
|
58
|
+
heading('Active Header backup')
|
|
59
|
+
if (activeHeaderBackupPath) item(dryRun ? `Would back up ${ACTIVE_HEADER_DIRECTORY} to ${activeHeaderBackupPath}` : `Will back up ${ACTIVE_HEADER_DIRECTORY} to ${activeHeaderBackupPath}`)
|
|
60
|
+
else item('No existing src/Header directory found; a new active Header will be installed.')
|
|
83
61
|
|
|
84
|
-
heading('Activation
|
|
85
|
-
item('
|
|
86
|
-
item('
|
|
62
|
+
heading('Activation')
|
|
63
|
+
item('Install a complete active src/Header replacement wired to HeaderDD02.')
|
|
64
|
+
item('The previous Header folder is preserved as src/Header.bak, src/Header.bak.1, or the next available backup path.')
|
|
87
65
|
|
|
88
66
|
if (dryRun) {
|
|
89
67
|
const sharedResults = await copySharedFiles({ manifest, packageRoot, targetDirectory, dryRun: true })
|
|
@@ -95,17 +73,8 @@ export async function addHeader({ headerName, targetDirectory = process.cwd(), d
|
|
|
95
73
|
}
|
|
96
74
|
|
|
97
75
|
const sharedResults = await copySharedFiles({ manifest, packageRoot, targetDirectory })
|
|
98
|
-
|
|
99
|
-
if (checks.collisions.destinationExists) {
|
|
100
|
-
await backupExistingDestination({ destinationPath: checks.collisions.destinationPath, targetDirectory })
|
|
101
|
-
}
|
|
102
|
-
for (const file of ACTIVE_HEADER_FILES) {
|
|
103
|
-
await backupExistingDestination({ destinationPath: file, targetDirectory })
|
|
104
|
-
}
|
|
105
|
-
|
|
76
|
+
if (activeHeaderExists) await backupExistingDestination({ destinationPath: ACTIVE_HEADER_DIRECTORY, targetDirectory })
|
|
106
77
|
const copiedFiles = await copyTemplateFiles({ manifest, templateDirectory, targetDirectory })
|
|
107
|
-
await writeFile(`${targetDirectory}/src/Header/Nav/index.tsx`, renderHeaderNav())
|
|
108
|
-
await writeFile(`${targetDirectory}/src/Header/config.ts`, renderHeaderConfig())
|
|
109
78
|
|
|
110
79
|
heading('Copied files')
|
|
111
80
|
copiedFiles.forEach((file) => item(file))
|
|
@@ -122,14 +91,6 @@ export async function addHeader({ headerName, targetDirectory = process.cwd(), d
|
|
|
122
91
|
info('Header workflow complete.')
|
|
123
92
|
}
|
|
124
93
|
|
|
125
|
-
function renderHeaderNav() {
|
|
126
|
-
return `import React from 'react'\n\nimport type { Header as HeaderType } from '@/payload-types'\n\nimport HeaderDD02 from '@/Header/variants/HeaderDD02'\n\nexport const HeaderNav: React.FC<{ data: HeaderType }> = ({ data }) => {\n return <HeaderDD02 data={data} />\n}\n`
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function renderHeaderConfig() {
|
|
130
|
-
return `import type { GlobalConfig } from 'payload'\n\nimport { iconPicker } from '@/fields/lucide-icon-picker/field'\nimport { link } from '@/fields/link'\nimport { HeaderDD02 } from '@/Header/variants/HeaderDD02/config'\nimport { revalidateHeader } from './hooks/revalidateHeader'\n\nexport const Header: GlobalConfig = {\n slug: 'header',\n access: {\n read: () => true,\n update: () => true,\n },\n fields: [\n {\n name: 'variant',\n label: 'Variant',\n type: 'select',\n defaultValue: 'header02',\n options: [{ label: 'Header DD 02', value: 'header02' }],\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'header02',\n type: 'group',\n fields: HeaderDD02,\n },\n {\n name: 'navItems',\n type: 'array',\n admin: {\n hidden: true,\n description: 'Legacy starter Header navItems retained so existing stored header data is not discarded.',\n },\n fields: [\n link({ appearances: false }),\n iconPicker({\n name: 'icon',\n required: false,\n description: 'Legacy optional icon to display with the navigation item',\n }),\n ],\n },\n ],\n hooks: {\n afterChange: [revalidateHeader],\n },\n}\n`
|
|
131
|
-
}
|
|
132
|
-
|
|
133
94
|
function formatMissingRequirement(check) {
|
|
134
95
|
const resolution = check.resolution ? `\n Resolve: ${check.resolution}` : ''
|
|
135
96
|
return `- ${check.path}: ${check.reason}${resolution}`
|
|
@@ -142,4 +103,4 @@ function formatDependency(dependency) {
|
|
|
142
103
|
function installCommandText(packageManager, dependencies) {
|
|
143
104
|
const command = packageManager === 'yarn' ? ['yarn', 'add'] : packageManager === 'bun' ? ['bun', 'add'] : packageManager === 'npm' ? ['npm', 'install'] : ['pnpm', 'add']
|
|
144
105
|
return [...command, ...dependencies.map(formatDependency)].join(' ')
|
|
145
|
-
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Header as HeaderType } from '@/payload-types'
|
|
2
|
+
import { getCachedGlobal } from '@/utilities/getGlobals'
|
|
3
|
+
|
|
4
|
+
import { HeaderClient } from './Component.client'
|
|
5
|
+
|
|
6
|
+
export async function Header() {
|
|
7
|
+
const headerData = (await getCachedGlobal('header', 1)()) as HeaderType | null
|
|
8
|
+
|
|
9
|
+
return <HeaderClient data={headerData ?? ({} as HeaderType)} />
|
|
10
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GlobalConfig } from 'payload'
|
|
2
|
+
|
|
3
|
+
import { HeaderDD02 } from '@/Header/variants/HeaderDD02/config'
|
|
4
|
+
|
|
5
|
+
import { revalidateHeader } from './hooks/revalidateHeader'
|
|
6
|
+
|
|
7
|
+
export const Header: GlobalConfig = {
|
|
8
|
+
slug: 'header',
|
|
9
|
+
access: {
|
|
10
|
+
read: () => true,
|
|
11
|
+
update: () => true,
|
|
12
|
+
},
|
|
13
|
+
fields: [
|
|
14
|
+
{
|
|
15
|
+
name: 'variant',
|
|
16
|
+
label: 'Variant',
|
|
17
|
+
type: 'select',
|
|
18
|
+
defaultValue: 'header02',
|
|
19
|
+
options: [{ label: 'Header DD 02', value: 'header02' }],
|
|
20
|
+
admin: {
|
|
21
|
+
position: 'sidebar',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'header02',
|
|
26
|
+
type: 'group',
|
|
27
|
+
fields: HeaderDD02,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
hooks: {
|
|
31
|
+
afterChange: [revalidateHeader],
|
|
32
|
+
},
|
|
33
|
+
}
|