kmcom-nuxt-layers 2.2.6 → 2.2.8
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/docs/FEEDS.md +197 -0
- package/docs/LAYERS-FIXES.md +101 -0
- package/docs/MIGRATION.md +627 -0
- package/docs/feed-layer.md +374 -0
- package/docs/patch-picture-provider-type.md +52 -0
- package/docs/shaderGuide.md +2071 -0
- package/docs/types-architecture.md +234 -0
- package/layers/animations/app/components/Motion/CountUp.vue +1 -2
- package/layers/animations/app/components/Motion/Magnetic.vue +1 -2
- package/layers/animations/app/components/Motion/Marquee.vue +2 -5
- package/layers/animations/app/components/Motion/MarqueeText.vue +1 -2
- package/layers/animations/app/components/Motion/Tilt.vue +1 -2
- package/layers/animations/app/composables/useCountUp.ts +4 -1
- package/layers/animations/app/composables/useMagneticElement.ts +1 -3
- package/layers/animations/app/composables/useMarqueeCopies.ts +3 -3
- package/layers/animations/app/types/animations.ts +8 -0
- package/layers/animations/app/types/index.ts +1 -0
- package/layers/animations/package.json +4 -1
- package/layers/canvas/app/components/ShaderCanvas.vue +4 -4
- package/layers/canvas/app/composables/useRendererCapabilities.ts +19 -15
- package/layers/canvas/app/types/index.ts +1 -0
- package/layers/canvas/package.json +2 -1
- package/layers/canvas/tsconfig.json +2 -1
- package/layers/content/app/components/Blog/Card.vue +5 -5
- package/layers/content/app/components/Gallery/AmbientImage.vue +3 -3
- package/layers/content/app/components/Gallery/Card.vue +3 -3
- package/layers/content/app/components/NuxtContent/Detail.vue +5 -1
- package/layers/content/app/components/NuxtContent/Surround.vue +5 -3
- package/layers/content/app/components/NuxtContent/Toc.vue +1 -1
- package/layers/content/app/components/Portfolio/Card.vue +5 -5
- package/layers/content/app/components/content/Figure.vue +3 -3
- package/layers/content/app/types/index.ts +1 -0
- package/layers/content/package.json +2 -1
- package/layers/core/app/composables/useErrorLog.ts +9 -11
- package/layers/core/app/utils/helpers.ts +14 -12
- package/layers/core/nuxt.config.ts +1 -0
- package/layers/feeds/app/plugins/feed-head.ts +1 -2
- package/layers/feeds/package.json +2 -1
- package/layers/feeds/server/routes/feed/discovery.get.ts +1 -2
- package/layers/feeds/server/utils/content-adapter.ts +3 -2
- package/layers/forms/app/components/Form/Field.vue +4 -4
- package/layers/forms/app/types/index.ts +1 -0
- package/layers/forms/package.json +2 -1
- package/layers/layout/app/components/Layout/Grid/Item.vue +33 -19
- package/layers/layout/app/components/Layout/Page/Container.vue +11 -11
- package/layers/layout/app/components/Layout/Page/Header.vue +1 -1
- package/layers/layout/app/components/Layout/Page/index.vue +1 -1
- package/layers/layout/app/components/Layout/Section/Gallery.vue +6 -1
- package/layers/layout/app/components/Layout/Section/Title.vue +1 -1
- package/layers/layout/app/types/index.ts +1 -0
- package/layers/layout/package.json +2 -1
- package/layers/mailer/app/types/index.ts +1 -0
- package/layers/mailer/app/types/mailer.ts +25 -0
- package/layers/mailer/package.json +2 -1
- package/layers/motion/package.json +2 -1
- package/layers/navigation/app/components/Links/Group.vue +1 -0
- package/layers/navigation/app/components/Links/Named.vue +2 -0
- package/layers/navigation/app/types/index.ts +1 -0
- package/layers/navigation/package.json +4 -1
- package/layers/page-transitions/package.json +4 -1
- package/layers/routing/app/types/app-config.d.ts +3 -1
- package/layers/routing/app/types/index.ts +1 -0
- package/layers/routing/package.json +2 -1
- package/layers/scripts/app/composables/useGtm.ts +1 -1
- package/layers/scripts/app/types/index.ts +1 -0
- package/layers/scripts/app/types/scripts.ts +14 -0
- package/layers/scripts/package.json +2 -1
- package/layers/scroll/app/components/Motion/ScrollScene.vue +3 -1
- package/layers/scroll/app/composables/useScrollSteps.ts +2 -9
- package/layers/scroll/app/composables/useSectionProgress.ts +2 -1
- package/layers/scroll/app/plugins/locomotive-scroll.client.ts +1 -8
- package/layers/scroll/app/types/index.ts +1 -0
- package/layers/scroll/app/types/scroll.ts +32 -0
- package/layers/scroll/package.json +3 -0
- package/layers/seo/package.json +2 -1
- package/layers/shader/app/components/Material/Fresnel.client.vue +1 -1
- package/layers/shader/app/components/Material/Image.client.vue +1 -1
- package/layers/shader/app/components/Material/Node.client.vue +7 -7
- package/layers/shader/app/components/Material/Noise.client.vue +1 -1
- package/layers/shader/app/components/Node/Color.client.vue +17 -20
- package/layers/shader/app/components/Node/Noise.client.vue +31 -34
- package/layers/shader/app/components/Pipeline/Aurora.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/BilinearGradient.client.vue +8 -11
- package/layers/shader/app/components/Pipeline/BillowNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/BrightnessContrast.client.vue +6 -2
- package/layers/shader/app/components/Pipeline/CellularNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Checkerboard.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Circle.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/Clouds.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/ColorBurnBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/ColorDodgeBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/ColourRamp.client.vue +5 -9
- package/layers/shader/app/components/Pipeline/ConicGradient.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/Cross.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/CurlNoise.client.vue +3 -7
- package/layers/shader/app/components/Pipeline/DarkenBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/DayNightCycle.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/DiagonalGradient.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/DiamondGradient.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/DifferenceBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/DomainWarpedNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Dots.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/DuoTone.client.vue +5 -9
- package/layers/shader/app/components/Pipeline/ExclusionBlend.client.vue +3 -23
- package/layers/shader/app/components/Pipeline/ExponentialFog.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/FilmBurn.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/Flame.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/FocalGradient.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/GodRays.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/GradientNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Grid.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Halation.client.vue +3 -7
- package/layers/shader/app/components/Pipeline/HardLightBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/Haze.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/Hexagon.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/LensFlare.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/LightenBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/LinearGradient4.client.vue +2 -2
- package/layers/shader/app/components/Pipeline/Marble.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/MonochromeTint.client.vue +3 -7
- package/layers/shader/app/components/Pipeline/MultiplyBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/NoisyGradient.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/NoisyGradientBlend.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/OverlayBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/Polygon.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/RaymarchTunnel.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/Rectangle.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/RidgedNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Ring.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/ScreenBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/SkyAtmosphere.client.vue +6 -9
- package/layers/shader/app/components/Pipeline/SoftLightBlend.client.vue +2 -19
- package/layers/shader/app/components/Pipeline/SplitTone.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Star.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Stripes.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Tint.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/Triangle.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/ValueNoise.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/VoronoiEdges.client.vue +4 -8
- package/layers/shader/app/components/Pipeline/Water.client.vue +5 -8
- package/layers/shader/app/components/Pipeline/WaveBendLayer.client.vue +4 -7
- package/layers/shader/app/components/Pipeline/WaveColourLayer.client.vue +3 -7
- package/layers/shader/app/components/Pipeline/Wood.client.vue +4 -8
- package/layers/shader/app/components/Preset/Aurora.client.vue +15 -21
- package/layers/shader/app/components/Preset/Flow.client.vue +2 -1
- package/layers/shader/app/components/Preset/GradientMesh.client.vue +2 -1
- package/layers/shader/app/components/Preset/Nebula.client.vue +2 -1
- package/layers/shader/app/components/Preset/Ocean.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemeAurora.client.vue +30 -90
- package/layers/shader/app/components/Preset/ThemeBubble.client.vue +30 -91
- package/layers/shader/app/components/Preset/ThemeFlow.client.vue +30 -90
- package/layers/shader/app/components/Preset/ThemeGradient.client.vue +30 -91
- package/layers/shader/app/components/Preset/ThemeLavaLamp.client.vue +30 -90
- package/layers/shader/app/components/Preset/ThemePlasma.client.vue +30 -90
- package/layers/shader/app/components/Preset/ThemeWave.client.vue +30 -90
- package/layers/shader/app/components/Shader/Background.client.vue +4 -4
- package/layers/shader/app/components/Shader/Host.client.vue +31 -33
- package/layers/shader/app/components/Shader/Runtime.client.vue +15 -23
- package/layers/shader/app/composables/useAmbientMaterials.ts +53 -51
- package/layers/shader/app/composables/useShaderMixBlend.ts +26 -0
- package/layers/shader/app/composables/useThemePreset.ts +75 -0
- package/layers/shader/app/shaders/common/noise.ts +2 -7
- package/layers/shader/app/shaders/types.ts +6 -6
- package/layers/shader/app/types/tsl.ts +7 -25
- package/layers/shader/app/types/uniforms.ts +2 -1
- package/layers/shader/app/utils/tsl/color.ts +7 -1
- package/layers/shader/package.json +2 -1
- package/layers/theme/app/components/ThemePicker/Colors.vue +1 -3
- package/layers/theme/app/types/app-config.d.ts +4 -2
- package/layers/theme/app/types/index.ts +1 -0
- package/layers/theme/app/types/theme.ts +3 -18
- package/layers/theme/package.json +2 -1
- package/layers/theme/server/plugins/theme-fouc.ts +1 -1
- package/layers/transitions/package.json +4 -1
- package/layers/typography/app/components/Typography/CodeBlock.vue +2 -2
- package/layers/typography/app/components/Typography/Headline.vue +2 -2
- package/layers/typography/app/components/Typography/HeadlineScreen.vue +1 -1
- package/layers/typography/app/components/Typography/QuoteBlock.vue +4 -1
- package/layers/typography/app/components/Typography/TextStroke.vue +2 -0
- package/layers/typography/app/components/Typography/index.vue +36 -27
- package/layers/typography/app/composables/typography.ts +27 -21
- package/layers/typography/app/types/colors.ts +9 -29
- package/layers/typography/app/types/index.ts +2 -0
- package/layers/typography/package.json +4 -1
- package/layers/ui/package.json +2 -1
- package/layers/visual/app/app.config.ts +5 -2
- package/layers/visual/app/components/Accent/Blob.vue +20 -20
- package/layers/visual/app/components/Accent/Scene.vue +2 -2
- package/layers/visual/app/components/Base/Modal.vue +2 -2
- package/layers/visual/app/components/Gradient/Background.vue +2 -2
- package/layers/visual/app/components/Gradient/Text.vue +2 -2
- package/layers/visual/app/components/Media/Picture.vue +3 -1
- package/layers/visual/app/components/Progress/Bar.vue +6 -6
- package/layers/visual/app/components/Tint/Overlay.vue +14 -14
- package/layers/visual/app/composables/accent.ts +10 -8
- package/layers/visual/app/composables/tint.ts +7 -7
- package/layers/visual/app/types/index.ts +6 -0
- package/layers/visual/app/types/media.ts +4 -2
- package/layers/visual/app/types/tint.ts +2 -1
- package/layers/visual/package.json +4 -1
- package/package.json +5 -2
|
@@ -94,9 +94,9 @@ export function useErrorLog() {
|
|
|
94
94
|
const { externalUrl, externalToken } = config.value
|
|
95
95
|
|
|
96
96
|
if (!externalUrl) {
|
|
97
|
-
process.env.NODE_ENV === 'development'
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
if (process.env.NODE_ENV === 'development') {
|
|
98
|
+
console.warn('Error logging enabled but no externalUrl configured')
|
|
99
|
+
}
|
|
100
100
|
return
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -118,10 +118,8 @@ export function useErrorLog() {
|
|
|
118
118
|
})
|
|
119
119
|
} catch (loggingError) {
|
|
120
120
|
// Don't let logging errors crash the app
|
|
121
|
-
if (import.meta.dev) {
|
|
122
|
-
|
|
123
|
-
? console.error('Failed to send error to external service:', loggingError)
|
|
124
|
-
: ''
|
|
121
|
+
if (import.meta.dev && process.env.NODE_ENV === 'development') {
|
|
122
|
+
console.error('Failed to send error to external service:', loggingError)
|
|
125
123
|
}
|
|
126
124
|
}
|
|
127
125
|
}
|
|
@@ -130,8 +128,8 @@ export function useErrorLog() {
|
|
|
130
128
|
* Log a warning (non-critical error)
|
|
131
129
|
*/
|
|
132
130
|
const logWarning = (message: string, context?: ErrorContext) => {
|
|
133
|
-
if (config.value.logToConsole && import.meta.dev) {
|
|
134
|
-
|
|
131
|
+
if (config.value.logToConsole && import.meta.dev && process.env.NODE_ENV === 'development') {
|
|
132
|
+
console.warn('⚠️ Warning:', message, context)
|
|
135
133
|
}
|
|
136
134
|
}
|
|
137
135
|
|
|
@@ -139,8 +137,8 @@ export function useErrorLog() {
|
|
|
139
137
|
* Log info (for debugging)
|
|
140
138
|
*/
|
|
141
139
|
const logInfo = (message: string, data?: unknown) => {
|
|
142
|
-
if (config.value.logToConsole && import.meta.dev) {
|
|
143
|
-
|
|
140
|
+
if (config.value.logToConsole && import.meta.dev && process.env.NODE_ENV === 'development') {
|
|
141
|
+
console.log('ℹ️ Info:', message, data)
|
|
144
142
|
}
|
|
145
143
|
}
|
|
146
144
|
|
|
@@ -18,30 +18,32 @@ export function safeJsonParse<T>(json: string, fallback: T): T {
|
|
|
18
18
|
/**
|
|
19
19
|
* Debounce function execution
|
|
20
20
|
*/
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
22
|
export function debounce<T extends (...args: any[]) => any>(
|
|
22
23
|
fn: T,
|
|
23
24
|
delay: number
|
|
24
25
|
): (...args: Parameters<T>) => void {
|
|
25
26
|
let timeoutId: ReturnType<typeof setTimeout>
|
|
26
27
|
|
|
27
|
-
return function (
|
|
28
|
+
return function (...args: Parameters<T>) {
|
|
28
29
|
clearTimeout(timeoutId)
|
|
29
|
-
timeoutId = setTimeout(() => fn
|
|
30
|
+
timeoutId = setTimeout(() => fn(...args), delay)
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Throttle function execution
|
|
35
36
|
*/
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
38
|
export function throttle<T extends (...args: any[]) => any>(
|
|
37
39
|
fn: T,
|
|
38
40
|
limit: number
|
|
39
41
|
): (...args: Parameters<T>) => void {
|
|
40
42
|
let inThrottle: boolean
|
|
41
43
|
|
|
42
|
-
return function (
|
|
44
|
+
return function (...args: Parameters<T>) {
|
|
43
45
|
if (!inThrottle) {
|
|
44
|
-
fn
|
|
46
|
+
fn(...args)
|
|
45
47
|
inThrottle = true
|
|
46
48
|
setTimeout(() => (inThrottle = false), limit)
|
|
47
49
|
}
|
|
@@ -68,7 +70,7 @@ export async function retry<T>(
|
|
|
68
70
|
): Promise<T> {
|
|
69
71
|
const { maxAttempts = 3, delay = 1000, backoff = 2 } = options
|
|
70
72
|
|
|
71
|
-
let lastError: Error
|
|
73
|
+
let lastError: Error = new Error('All retry attempts failed')
|
|
72
74
|
|
|
73
75
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
74
76
|
try {
|
|
@@ -83,7 +85,7 @@ export async function retry<T>(
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
throw lastError
|
|
88
|
+
throw lastError
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
/**
|
|
@@ -123,8 +125,8 @@ export function formatBytes(bytes: number, decimals = 2): string {
|
|
|
123
125
|
export function deepClone<T>(obj: T): T {
|
|
124
126
|
if (obj === null || typeof obj !== 'object') return obj
|
|
125
127
|
|
|
126
|
-
if (obj instanceof Date) return new Date(obj.getTime()) as
|
|
127
|
-
if (obj instanceof Array) return obj.map((item) => deepClone(item)) as
|
|
128
|
+
if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T
|
|
129
|
+
if (obj instanceof Array) return obj.map((item) => deepClone(item)) as unknown as T
|
|
128
130
|
if (obj instanceof Object) {
|
|
129
131
|
const clonedObj = {} as T
|
|
130
132
|
for (const key in obj) {
|
|
@@ -182,8 +184,8 @@ export function truncate(str: string, length: number, suffix = '...'): string {
|
|
|
182
184
|
/**
|
|
183
185
|
* Remove undefined/null values from object
|
|
184
186
|
*/
|
|
185
|
-
export function removeEmpty<T extends Record<string,
|
|
186
|
-
const result:
|
|
187
|
+
export function removeEmpty<T extends Record<string, unknown>>(obj: T): Partial<T> {
|
|
188
|
+
const result: Partial<T> = {}
|
|
187
189
|
|
|
188
190
|
for (const key in obj) {
|
|
189
191
|
if (obj[key] !== undefined && obj[key] !== null) {
|
|
@@ -214,7 +216,7 @@ export function groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {
|
|
|
214
216
|
/**
|
|
215
217
|
* Pick specific keys from object
|
|
216
218
|
*/
|
|
217
|
-
export function pick<T extends Record<string,
|
|
219
|
+
export function pick<T extends Record<string, unknown>, K extends keyof T>(
|
|
218
220
|
obj: T,
|
|
219
221
|
keys: K[]
|
|
220
222
|
): Pick<T, K> {
|
|
@@ -232,7 +234,7 @@ export function pick<T extends Record<string, any>, K extends keyof T>(
|
|
|
232
234
|
/**
|
|
233
235
|
* Omit specific keys from object
|
|
234
236
|
*/
|
|
235
|
-
export function omit<T extends Record<string,
|
|
237
|
+
export function omit<T extends Record<string, unknown>, K extends keyof T>(
|
|
236
238
|
obj: T,
|
|
237
239
|
keys: K[]
|
|
238
240
|
): Omit<T, K> {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export default defineNuxtPlugin({
|
|
2
2
|
name: 'feeds:feed-head',
|
|
3
3
|
setup() {
|
|
4
|
-
|
|
5
|
-
const appConfig = useAppConfig() as any
|
|
4
|
+
const appConfig = useAppConfig()
|
|
6
5
|
const site = appConfig.site ?? {}
|
|
7
6
|
const feedConfig = appConfig.feedsLayer?.feed ?? {}
|
|
8
7
|
const collections: string[] = feedConfig.collections ?? ['blog']
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"dev:prepare": "nuxt prepare .playground",
|
|
11
11
|
"build": "FEEDS_STANDALONE=true nuxi build",
|
|
12
12
|
"generate": "FEEDS_STANDALONE=true nuxi generate",
|
|
13
|
-
"preview": "nuxt preview .playground"
|
|
13
|
+
"preview": "nuxt preview .playground",
|
|
14
|
+
"lint": "eslint ."
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"feed": "catalog:"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export default defineEventHandler((event) => {
|
|
2
|
-
|
|
3
|
-
const appConfig = useAppConfig() as any
|
|
2
|
+
const appConfig = useAppConfig()
|
|
4
3
|
const feedConfig = appConfig.feedsLayer?.feed ?? {}
|
|
5
4
|
const collections: string[] = feedConfig.collections ?? ['blog']
|
|
6
5
|
|
|
@@ -3,14 +3,15 @@ import type { H3Event } from 'h3'
|
|
|
3
3
|
|
|
4
4
|
import type { FeedItem } from './types'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
type AnyContent = Record<string, any>
|
|
6
|
+
type AnyContent = Record<string, unknown>
|
|
8
7
|
|
|
9
8
|
export async function getContentFeedItems(
|
|
10
9
|
event: H3Event,
|
|
11
10
|
collection: string = 'blog',
|
|
12
11
|
limit: number = 30
|
|
13
12
|
): Promise<FeedItem[]> {
|
|
13
|
+
// queryCollection's first argument is typed as a const collection name, but we pass
|
|
14
|
+
// a dynamic string at runtime — the cast is intentional and safe here.
|
|
14
15
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
16
|
const raw: AnyContent[] = await (queryCollection as any)(event, collection).all()
|
|
16
17
|
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
const {
|
|
6
6
|
type = 'text',
|
|
7
7
|
name,
|
|
8
|
-
label,
|
|
8
|
+
label = undefined,
|
|
9
9
|
required = false,
|
|
10
10
|
size = 'md',
|
|
11
|
-
placeholder,
|
|
12
|
-
icon,
|
|
13
|
-
class: className,
|
|
11
|
+
placeholder = undefined,
|
|
12
|
+
icon = undefined,
|
|
13
|
+
class: className = undefined,
|
|
14
14
|
} = defineProps<{
|
|
15
15
|
/** Field type determines validation, icon, and input behavior */
|
|
16
16
|
type?: FieldType
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './fields'
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nuxi dev",
|
|
8
8
|
"dev:playground": "PLAYGROUND_LAYERS=core,mailer,forms pnpm -F playground dev",
|
|
9
|
-
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json"
|
|
9
|
+
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json",
|
|
10
|
+
"lint": "eslint ."
|
|
10
11
|
},
|
|
11
12
|
"dependencies": {
|
|
12
13
|
"zod": "catalog:conflicts_conflicts_zod_h4_3_6_h4_4_3"
|
|
@@ -65,26 +65,40 @@
|
|
|
65
65
|
aspect?: AspectRatio
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const {
|
|
69
|
+
preset: presetProp = undefined,
|
|
70
|
+
as = 'div',
|
|
71
|
+
colStart: colStartProp = undefined,
|
|
72
|
+
colSpan: colSpanProp = undefined,
|
|
73
|
+
rowStart: rowStartProp = undefined,
|
|
74
|
+
rowSpan: rowSpanProp = undefined,
|
|
75
|
+
align: alignProp = undefined,
|
|
76
|
+
justify: justifyProp = undefined,
|
|
77
|
+
container: containerProp = undefined,
|
|
78
|
+
gap: gapProp = undefined,
|
|
79
|
+
density: densityProp = undefined,
|
|
80
|
+
z = undefined,
|
|
81
|
+
layer = undefined,
|
|
82
|
+
bleed = undefined,
|
|
83
|
+
aspect = undefined,
|
|
84
|
+
} = defineProps<Props>()
|
|
71
85
|
|
|
72
86
|
// Get preset configuration if preset prop is provided
|
|
73
87
|
const { getPreset } = useGridConfig()
|
|
74
|
-
const presetConfig = computed(() => (
|
|
88
|
+
const presetConfig = computed(() => (presetProp ? getPreset(presetProp) : undefined))
|
|
75
89
|
|
|
76
90
|
// Merge preset values with explicit props (explicit props take precedence)
|
|
77
|
-
const colStart = computed(() =>
|
|
78
|
-
const colSpan = computed(() =>
|
|
79
|
-
const rowStart = computed(() =>
|
|
80
|
-
const rowSpan = computed(() =>
|
|
91
|
+
const colStart = computed(() => colStartProp ?? presetConfig.value?.colStart)
|
|
92
|
+
const colSpan = computed(() => colSpanProp ?? presetConfig.value?.colSpan ?? 'full')
|
|
93
|
+
const rowStart = computed(() => rowStartProp ?? presetConfig.value?.rowStart)
|
|
94
|
+
const rowSpan = computed(() => rowSpanProp ?? presetConfig.value?.rowSpan ?? 1)
|
|
81
95
|
|
|
82
96
|
// Preset-aware alignment computed refs
|
|
83
|
-
const align = computed(() =>
|
|
84
|
-
const justify = computed(() =>
|
|
85
|
-
const container = computed(() =>
|
|
86
|
-
const gap = computed(() =>
|
|
87
|
-
const density = computed(() =>
|
|
97
|
+
const align = computed(() => alignProp ?? presetConfig.value?.align)
|
|
98
|
+
const justify = computed(() => justifyProp ?? presetConfig.value?.justify)
|
|
99
|
+
const container = computed(() => containerProp ?? presetConfig.value?.container)
|
|
100
|
+
const gap = computed(() => gapProp ?? presetConfig.value?.gap)
|
|
101
|
+
const density = computed(() => densityProp ?? presetConfig.value?.density)
|
|
88
102
|
|
|
89
103
|
const layerZIndex: Record<LayerName, number> = {
|
|
90
104
|
back: 0,
|
|
@@ -133,15 +147,15 @@
|
|
|
133
147
|
const rowStartVal = getDefaultValue(rowStart.value, undefined)
|
|
134
148
|
const rowSpanVal = getDefaultValue(rowSpan.value, 1)
|
|
135
149
|
|
|
136
|
-
if (
|
|
137
|
-
if (
|
|
150
|
+
if (bleed) {
|
|
151
|
+
if (bleed === 'both') {
|
|
138
152
|
styles.gridColumn = '1 / -1'
|
|
139
153
|
styles.marginInline = 'calc(-1 * var(--grid-padding))'
|
|
140
|
-
} else if (
|
|
154
|
+
} else if (bleed === 'left') {
|
|
141
155
|
const spanNum = typeof colSpanVal === 'number' ? colSpanVal : undefined
|
|
142
156
|
styles.gridColumn = spanNum ? `1 / span ${spanNum}` : '1 / -1'
|
|
143
157
|
styles.marginInlineStart = 'calc(-1 * var(--grid-padding))'
|
|
144
|
-
} else if (
|
|
158
|
+
} else if (bleed === 'right') {
|
|
145
159
|
styles.gridColumn = `${colStartVal ?? 'auto'} / -1`
|
|
146
160
|
styles.marginInlineEnd = 'calc(-1 * var(--grid-padding))'
|
|
147
161
|
}
|
|
@@ -218,7 +232,7 @@
|
|
|
218
232
|
}
|
|
219
233
|
|
|
220
234
|
// Z-index
|
|
221
|
-
const zIndex =
|
|
235
|
+
const zIndex = z ?? (layer ? layerZIndex[layer] : undefined)
|
|
222
236
|
if (zIndex !== undefined) styles.zIndex = String(zIndex)
|
|
223
237
|
|
|
224
238
|
return styles
|
|
@@ -227,7 +241,7 @@
|
|
|
227
241
|
const classes = computed(() => {
|
|
228
242
|
const classList: string[] = ['gi-placed', '@container', '@container/item']
|
|
229
243
|
|
|
230
|
-
if (
|
|
244
|
+
if (aspect) classList.push(aspectClasses[aspect])
|
|
231
245
|
if (container.value) classList.push(`layout-container-${container.value}`)
|
|
232
246
|
|
|
233
247
|
return classList.join(' ')
|
|
@@ -38,23 +38,23 @@
|
|
|
38
38
|
* </PageContainer>
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
title: string
|
|
43
|
-
description?: string
|
|
44
|
-
showHeader?: boolean
|
|
45
|
-
headerPreset?: string
|
|
46
|
-
layout?: 'grid' | 'upage'
|
|
47
|
-
back?: string
|
|
48
|
-
}
|
|
41
|
+
defineOptions({ inheritAttrs: false })
|
|
49
42
|
|
|
50
43
|
const {
|
|
51
44
|
title,
|
|
52
|
-
description,
|
|
45
|
+
description = undefined,
|
|
53
46
|
showHeader = true,
|
|
54
47
|
headerPreset = 'centered',
|
|
55
48
|
layout = 'grid',
|
|
56
|
-
back,
|
|
57
|
-
} = defineProps<
|
|
49
|
+
back = undefined,
|
|
50
|
+
} = defineProps<{
|
|
51
|
+
title: string
|
|
52
|
+
description?: string
|
|
53
|
+
showHeader?: boolean
|
|
54
|
+
headerPreset?: string
|
|
55
|
+
layout?: 'grid' | 'upage'
|
|
56
|
+
back?: string
|
|
57
|
+
}>()
|
|
58
58
|
|
|
59
59
|
// Set page metadata for SEO and browser tab
|
|
60
60
|
useHead({
|
|
@@ -29,7 +29,12 @@
|
|
|
29
29
|
fullHeight?: boolean
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const {
|
|
32
|
+
const {
|
|
33
|
+
items = undefined,
|
|
34
|
+
columns = 3,
|
|
35
|
+
itemRowSpan = 4,
|
|
36
|
+
fullHeight = false,
|
|
37
|
+
} = defineProps<Props<T>>()
|
|
33
38
|
|
|
34
39
|
// Responsive column spans that work across 6/12/18 column grids
|
|
35
40
|
const columnSpan = computed(() => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './layouts'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './mailer'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type ContactEmailData = {
|
|
2
|
+
name: string
|
|
3
|
+
email: string
|
|
4
|
+
message: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type ContactSubmittedPayload = {
|
|
8
|
+
name: string
|
|
9
|
+
email: string
|
|
10
|
+
message: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ContactSentPayload = {
|
|
14
|
+
messageId: string
|
|
15
|
+
} & ContactSubmittedPayload
|
|
16
|
+
|
|
17
|
+
export type ContactFailedPayload = {
|
|
18
|
+
error: unknown
|
|
19
|
+
} & ContactSubmittedPayload
|
|
20
|
+
|
|
21
|
+
export type MailerLayerHooks = {
|
|
22
|
+
'contact:submitted': (payload: ContactSubmittedPayload) => void
|
|
23
|
+
'contact:sent': (payload: ContactSentPayload) => void
|
|
24
|
+
'contact:failed': (payload: ContactFailedPayload) => void
|
|
25
|
+
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nuxi dev",
|
|
8
8
|
"dev:playground": "PLAYGROUND_LAYERS=core,mailer pnpm -F playground dev",
|
|
9
|
-
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json"
|
|
9
|
+
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json",
|
|
10
|
+
"lint": "eslint ."
|
|
10
11
|
},
|
|
11
12
|
"dependencies": {
|
|
12
13
|
"hookable": "catalog:",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './nav'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './routing'
|
|
@@ -4,7 +4,7 @@ export function useGtm() {
|
|
|
4
4
|
|
|
5
5
|
const gtmConfig = scriptsLayer?.gtm
|
|
6
6
|
if (!gtmConfig?.enabled || !gtmConfig?.id) {
|
|
7
|
-
return { push: (
|
|
7
|
+
return { push: () => {}, load: () => {} }
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
// Load on Nuxt ready unless consent is required and not yet granted
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './scripts'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type LoadStrategy = 'onNuxtReady' | 'idle' | 'manual'
|
|
2
|
+
|
|
3
|
+
export type ScriptLoaderOptions = {
|
|
4
|
+
src: string
|
|
5
|
+
key?: string
|
|
6
|
+
strategy?: LoadStrategy
|
|
7
|
+
crossorigin?: 'anonymous' | 'use-credentials'
|
|
8
|
+
integrity?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type AnalyticsProxy = {
|
|
12
|
+
track: (event: string, params?: Record<string, unknown>) => void
|
|
13
|
+
load: () => void
|
|
14
|
+
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nuxi dev",
|
|
8
8
|
"dev:playground": "PLAYGROUND_LAYERS=core,scripts pnpm -F playground dev",
|
|
9
|
-
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json"
|
|
9
|
+
"typecheck": "vue-tsc --noEmit -p ../../tsconfig.typecheck.json",
|
|
10
|
+
"lint": "eslint ."
|
|
10
11
|
},
|
|
11
12
|
"dependencies": {
|
|
12
13
|
"@nuxt/scripts": "catalog:"
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { ScrollTrigger as GSAPScrollTrigger } from 'gsap/ScrollTrigger'
|
|
3
|
+
|
|
2
4
|
import { SCROLL_SCENE_KEY, type ScrollSceneContext } from '../../composables/useScrollSteps'
|
|
3
5
|
|
|
4
6
|
const {
|
|
@@ -72,7 +74,7 @@
|
|
|
72
74
|
unregisterStep,
|
|
73
75
|
})
|
|
74
76
|
|
|
75
|
-
let st:
|
|
77
|
+
let st: GSAPScrollTrigger | null = null
|
|
76
78
|
|
|
77
79
|
onMounted(() => {
|
|
78
80
|
if (!containerRef.value) return
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ScrollSceneContext } from '../types/scroll'
|
|
2
2
|
|
|
3
3
|
export const SCROLL_SCENE_KEY = Symbol('motionScrollScene')
|
|
4
4
|
|
|
5
|
-
export type ScrollSceneContext
|
|
6
|
-
progress: Ref<number>
|
|
7
|
-
active: Ref<boolean>
|
|
8
|
-
name: string
|
|
9
|
-
stepCount: ComputedRef<number>
|
|
10
|
-
registerStep: (index: number) => void
|
|
11
|
-
unregisterStep: (index: number) => void
|
|
12
|
-
}
|
|
5
|
+
export type { ScrollSceneContext }
|
|
13
6
|
|
|
14
7
|
/**
|
|
15
8
|
* Step/waypoint state tracking — must be used inside a MotionScrollScene.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ScrollTrigger } from 'gsap/ScrollTrigger'
|
|
1
2
|
import type { MaybeRef } from 'vue'
|
|
2
3
|
|
|
3
4
|
type SectionProgressOptions = {
|
|
@@ -27,7 +28,7 @@ export function useSectionProgress(
|
|
|
27
28
|
const entering = computed(() => active.value && direction.value > 0)
|
|
28
29
|
const leaving = computed(() => active.value && direction.value < 0)
|
|
29
30
|
|
|
30
|
-
let st:
|
|
31
|
+
let st: ScrollTrigger | null = null
|
|
31
32
|
|
|
32
33
|
onMounted(() => {
|
|
33
34
|
const el = unref(trigger)
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
|
2
2
|
import LocomotiveScroll from 'locomotive-scroll'
|
|
3
|
-
|
|
4
|
-
export type ScrollState = {
|
|
5
|
-
scroll: number
|
|
6
|
-
limit: number
|
|
7
|
-
velocity: number
|
|
8
|
-
direction: number
|
|
9
|
-
progress: number
|
|
10
|
-
}
|
|
3
|
+
import type { ScrollState } from '../types/scroll'
|
|
11
4
|
|
|
12
5
|
export default defineNuxtPlugin({
|
|
13
6
|
name: 'scroll:locomotive-scroll',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './scroll'
|