meno-core 1.0.53 → 1.0.54
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/.claude/settings.local.json +1 -3
- package/bin/cli.ts +48 -57
- package/build-astro.ts +131 -113
- package/build-next.ts +109 -96
- package/build-static.test.ts +39 -10
- package/build-static.ts +120 -122
- package/dist/bin/cli.js +34 -38
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +12 -11
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-IGYR22T6.js → chunk-2FN4UOVO.js} +512 -239
- package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
- package/dist/chunks/chunk-3XER4E5W.js +168 -0
- package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-5ETZFREW.js} +9 -12
- package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
- package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
- package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-7HWQUVTU.js} +1578 -1349
- package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-AE3QK5QW.js} +110 -21
- package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
- package/dist/chunks/{chunk-GZHGVVW3.js → chunk-F6KTJYGV.js} +7 -7
- package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
- package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
- package/dist/chunks/{chunk-QB2LNO4W.js → chunk-GSYYA5GX.js} +2 -2
- package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-HIZMY3EP.js} +1 -1
- package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
- package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
- package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
- package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
- package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
- package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
- package/dist/chunks/{chunk-JGP5A3Y5.js → chunk-Q4OBWKXG.js} +40 -33
- package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
- package/dist/chunks/{chunk-R6XHAFBF.js → chunk-QTE32Y53.js} +250 -242
- package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-STDY3OVM.js} +214 -85
- package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
- package/dist/chunks/configService-PRJZF7Y6.js +14 -0
- package/dist/chunks/{constants-STK2YBIW.js → constants-KIQEYMAM.js} +2 -2
- package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
- package/dist/entries/server-router.js +14 -19
- package/dist/entries/server-router.js.map +2 -2
- package/dist/lib/client/index.js +638 -332
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +177 -235
- package/dist/lib/server/index.js.map +2 -2
- package/dist/lib/shared/index.js +80 -44
- package/dist/lib/shared/index.js.map +2 -2
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +38 -60
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/entries/server-router.tsx +1 -7
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +146 -143
- package/lib/client/ErrorBoundary.tsx +175 -127
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -2
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +513 -560
- package/lib/client/core/ComponentBuilder.ts +318 -146
- package/lib/client/core/ComponentRenderer.test.tsx +1 -2
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +241 -53
- package/lib/client/core/builders/linkBuilder.ts +71 -44
- package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
- package/lib/client/core/builders/listBuilder.ts +115 -86
- package/lib/client/core/builders/localeListBuilder.ts +95 -60
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +7 -7
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +8 -0
- package/lib/client/hmrCssReload.ts +14 -8
- package/lib/client/hmrWebSocket.ts +9 -14
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +12 -10
- package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
- package/lib/client/hooks/useVariables.ts +4 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
- package/lib/client/meno-filter/MenoFilter.ts +5 -9
- package/lib/client/meno-filter/bindings.ts +15 -40
- package/lib/client/meno-filter/init.ts +1 -1
- package/lib/client/meno-filter/renderer.ts +23 -29
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +3 -5
- package/lib/client/meno-filter/updates.ts +15 -21
- package/lib/client/navigation.test.ts +159 -159
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.test.ts +230 -228
- package/lib/client/responsiveStyleResolver.ts +13 -16
- package/lib/client/routing/RouteLoader.test.ts +23 -24
- package/lib/client/routing/RouteLoader.ts +22 -35
- package/lib/client/routing/Router.tsx +31 -3
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +15 -33
- package/lib/client/services/PrefetchService.test.ts +2 -2
- package/lib/client/services/PrefetchService.ts +10 -24
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +18 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +9 -6
- package/lib/client/styles/UtilityClassCollector.ts +19 -26
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -482
- package/lib/client/templateEngine.ts +200 -64
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +1 -1
- package/lib/server/__integration__/test-helpers.ts +84 -70
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +23 -38
- package/lib/server/astro/componentEmitter.ts +25 -36
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1750 -30
- package/lib/server/astro/nodeToAstro.ts +198 -187
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +105 -109
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +4 -12
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +14 -17
- package/lib/server/createServer.ts +5 -17
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +6 -17
- package/lib/server/fileWatcher.test.ts +124 -10
- package/lib/server/fileWatcher.ts +124 -118
- package/lib/server/index.ts +7 -1
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +33 -31
- package/lib/server/middleware/cors.test.ts +20 -20
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +5 -3
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +7 -5
- package/lib/server/middleware/logger.ts +10 -22
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +4 -3
- package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
- package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
- package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
- package/lib/server/providers/fileSystemPageProvider.ts +31 -12
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/components.ts +30 -34
- package/lib/server/routes/api/config.ts +0 -1
- package/lib/server/routes/api/core-routes.ts +47 -74
- package/lib/server/routes/api/functions.ts +8 -16
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +1 -3
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +23 -26
- package/lib/server/routes/pages.ts +34 -29
- package/lib/server/routes/static.ts +16 -4
- package/lib/server/runtime/bundler.ts +47 -32
- package/lib/server/runtime/fs.ts +3 -13
- package/lib/server/runtime/httpServer.ts +5 -9
- package/lib/server/services/ColorService.ts +32 -27
- package/lib/server/services/EnumService.test.ts +2 -6
- package/lib/server/services/EnumService.ts +7 -2
- package/lib/server/services/VariableService.test.ts +1 -5
- package/lib/server/services/VariableService.ts +6 -1
- package/lib/server/services/cmsService.test.ts +116 -78
- package/lib/server/services/cmsService.ts +24 -54
- package/lib/server/services/componentService.test.ts +122 -36
- package/lib/server/services/componentService.ts +54 -38
- package/lib/server/services/configService.test.ts +9 -31
- package/lib/server/services/configService.ts +20 -27
- package/lib/server/services/fileWatcherService.ts +40 -6
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +1 -3
- package/lib/server/services/pageService.ts +14 -13
- package/lib/server/ssr/attributeBuilder.ts +16 -6
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
- package/lib/server/ssr/htmlGenerator.test.ts +120 -43
- package/lib/server/ssr/htmlGenerator.ts +120 -85
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +25 -19
- package/lib/server/ssr/jsCollector.test.ts +3 -13
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +69 -28
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +196 -246
- package/lib/server/ssr/ssrRenderer.ts +609 -225
- package/lib/server/ssrRenderer.test.ts +1044 -950
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +1 -1
- package/lib/server/validateStyleCoverage.ts +18 -20
- package/lib/server/webflow/buildWebflow.ts +41 -53
- package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
- package/lib/server/webflow/nodeToWebflow.ts +195 -258
- package/lib/server/webflow/styleMapper.test.ts +15 -56
- package/lib/server/webflow/styleMapper.ts +33 -41
- package/lib/server/webflow/types.ts +1 -8
- package/lib/server/websocketManager.ts +16 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +49 -31
- package/lib/shared/colorVariableUtils.test.ts +5 -5
- package/lib/shared/colorVariableUtils.ts +3 -8
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +4 -8
- package/lib/shared/cssGeneration.test.ts +262 -144
- package/lib/shared/cssGeneration.ts +189 -516
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +5 -6
- package/lib/shared/cssProperties.ts +296 -112
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +1 -1
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +119 -0
- package/lib/shared/expressionEvaluator.ts +43 -24
- package/lib/shared/fontLoader.test.ts +19 -5
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +1 -5
- package/lib/shared/gradientUtils.ts +2 -6
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +1 -1
- package/lib/shared/i18n.ts +13 -34
- package/lib/shared/index.ts +4 -0
- package/lib/shared/inlineSvgStyleRules.ts +2 -4
- package/lib/shared/interactiveStyleMappings.test.ts +11 -33
- package/lib/shared/interactiveStyleMappings.ts +9 -16
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +6 -12
- package/lib/shared/itemTemplateUtils.ts +19 -35
- package/lib/shared/jsonRepair.ts +8 -2
- package/lib/shared/libraryLoader.test.ts +15 -49
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +24 -16
- package/lib/shared/nodeUtils.ts +49 -19
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +1 -1
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -48
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +14 -17
- package/lib/shared/paths/PathUtils.ts +9 -10
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +11 -9
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +14 -25
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
- package/lib/shared/registry/ClientRegistry.ts +0 -1
- package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
- package/lib/shared/registry/ComponentRegistry.ts +9 -11
- package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -1
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
- package/lib/shared/registry/nodeTypes/index.ts +10 -2
- package/lib/shared/responsiveScaling.test.ts +15 -31
- package/lib/shared/responsiveScaling.ts +55 -37
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
- package/lib/shared/richtext/htmlToTiptap.ts +1 -3
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +5 -10
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -11
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +62 -138
- package/lib/shared/tree/PathBuilder.ts +49 -39
- package/lib/shared/treePathUtils.test.ts +2 -10
- package/lib/shared/treePathUtils.ts +54 -59
- package/lib/shared/types/api.ts +1 -2
- package/lib/shared/types/cms.ts +25 -21
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +27 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +2 -2
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +48 -27
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +648 -321
- package/lib/shared/utilityClassMapper.test.ts +203 -92
- package/lib/shared/utilityClassMapper.ts +188 -246
- package/lib/shared/utilityClassNames.ts +326 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +12 -1
- package/lib/shared/validation/propValidator.test.ts +18 -20
- package/lib/shared/validation/propValidator.ts +12 -17
- package/lib/shared/validation/schemas.test.ts +24 -33
- package/lib/shared/validation/schemas.ts +469 -344
- package/lib/shared/validation/validators.test.ts +1 -6
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +11 -23
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
- package/lib/test-utils/factories/DomMockFactory.ts +7 -19
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +5 -9
- package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +12 -18
- package/lib/test-utils/mocks.ts +4 -2
- package/package.json +1 -1
- package/scripts/build-meno-filter.ts +1 -4
- package/vite.config.ts +4 -4
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
- package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
- /package/dist/chunks/{constants-STK2YBIW.js.map → constants-KIQEYMAM.js.map} +0 -0
- /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
|
@@ -37,7 +37,13 @@ import { NODE_TYPE, RAW_HTML_PREFIX } from '../../shared/constants';
|
|
|
37
37
|
import { extractInteractiveStyleMappings, hasInteractiveStyleMappings } from '../../shared/interactiveStyleMappings';
|
|
38
38
|
import type { ImageMetadataMap } from '../ssr/imageMetadata';
|
|
39
39
|
import { isI18nValue, resolveI18nValue, DEFAULT_I18N_CONFIG, buildLocalizedPath } from '../../shared/i18n';
|
|
40
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
transformCMSTemplate,
|
|
42
|
+
isTemplateExpression,
|
|
43
|
+
transformItemTemplate,
|
|
44
|
+
replaceItemMetaVars,
|
|
45
|
+
rewriteItemVar,
|
|
46
|
+
} from './templateTransformer';
|
|
41
47
|
import type { SlugMap } from '../../shared/slugTranslator';
|
|
42
48
|
import { buildSlugIndex, translatePath } from '../../shared/slugTranslator';
|
|
43
49
|
import { stripRawHtmlPrefixDeep, astroComponentName } from './astroEmitHelpers';
|
|
@@ -177,20 +183,12 @@ function localizeHref(href: string, ctx: AstroEmitContext): string {
|
|
|
177
183
|
|
|
178
184
|
function isStyleMapping(value: unknown): value is StyleMapping {
|
|
179
185
|
return (
|
|
180
|
-
typeof value === 'object' &&
|
|
181
|
-
value !== null &&
|
|
182
|
-
'_mapping' in value &&
|
|
183
|
-
(value as StyleMapping)._mapping === true
|
|
186
|
+
typeof value === 'object' && value !== null && '_mapping' in value && (value as StyleMapping)._mapping === true
|
|
184
187
|
);
|
|
185
188
|
}
|
|
186
189
|
|
|
187
190
|
function isLinkMapping(value: unknown): value is LinkMapping {
|
|
188
|
-
return (
|
|
189
|
-
typeof value === 'object' &&
|
|
190
|
-
value !== null &&
|
|
191
|
-
'_mapping' in value &&
|
|
192
|
-
(value as LinkMapping)._mapping === true
|
|
193
|
-
);
|
|
191
|
+
return typeof value === 'object' && value !== null && '_mapping' in value && (value as LinkMapping)._mapping === true;
|
|
194
192
|
}
|
|
195
193
|
|
|
196
194
|
/**
|
|
@@ -199,14 +197,12 @@ function isLinkMapping(value: unknown): value is LinkMapping {
|
|
|
199
197
|
function emitAttrValue(key: string, value: string, ctx: AstroEmitContext): string {
|
|
200
198
|
if (ctx.cmsMode && /\{\{cms\./.test(value)) {
|
|
201
199
|
const b = ctx.cmsEntryBinding || 'entry';
|
|
202
|
-
const w = (expr: string) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
200
|
+
const w = (expr: string) => (ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr);
|
|
203
201
|
const fullMatch = value.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
204
202
|
if (fullMatch) {
|
|
205
203
|
return `${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`;
|
|
206
204
|
}
|
|
207
|
-
const replaced = value.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fp) =>
|
|
208
|
-
`\${${w(`${b}.data.${fp.trim()}`)}}`
|
|
209
|
-
);
|
|
205
|
+
const replaced = value.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fp) => `\${${w(`${b}.data.${fp.trim()}`)}}`);
|
|
210
206
|
return `${key}={\`${replaced}\`}`;
|
|
211
207
|
}
|
|
212
208
|
if (ctx.listItemBinding && /\{\{/.test(value)) {
|
|
@@ -229,17 +225,10 @@ function emitAttrValue(key: string, value: string, ctx: AstroEmitContext): strin
|
|
|
229
225
|
}
|
|
230
226
|
|
|
231
227
|
function isHtmlMapping(value: unknown): value is HtmlMapping {
|
|
232
|
-
return (
|
|
233
|
-
typeof value === 'object' &&
|
|
234
|
-
value !== null &&
|
|
235
|
-
'_mapping' in value &&
|
|
236
|
-
(value as HtmlMapping)._mapping === true
|
|
237
|
-
);
|
|
228
|
+
return typeof value === 'object' && value !== null && '_mapping' in value && (value as HtmlMapping)._mapping === true;
|
|
238
229
|
}
|
|
239
230
|
|
|
240
|
-
function isResponsiveStyle(
|
|
241
|
-
style: StyleObject | ResponsiveStyleObject
|
|
242
|
-
): style is ResponsiveStyleObject {
|
|
231
|
+
function isResponsiveStyle(style: StyleObject | ResponsiveStyleObject): style is ResponsiveStyleObject {
|
|
243
232
|
return 'base' in style || 'tablet' in style || 'mobile' in style;
|
|
244
233
|
}
|
|
245
234
|
|
|
@@ -266,7 +255,7 @@ function escapeTemplateLiteral(s: string): string {
|
|
|
266
255
|
* Get all style mappings from a style value, collecting { prop, property, values } tuples
|
|
267
256
|
*/
|
|
268
257
|
function collectStyleMappings(
|
|
269
|
-
style: StyleObject | ResponsiveStyleObject | undefined
|
|
258
|
+
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
270
259
|
): Array<{ property: string; mapping: StyleMapping; breakpoint?: string }> {
|
|
271
260
|
if (!style) return [];
|
|
272
261
|
const result: Array<{ property: string; mapping: StyleMapping; breakpoint?: string }> = [];
|
|
@@ -299,14 +288,21 @@ function mappingToClassListEntries(
|
|
|
299
288
|
mapping: StyleMapping,
|
|
300
289
|
property: string,
|
|
301
290
|
breakpointPrefix: string,
|
|
302
|
-
ctx: AstroEmitContext
|
|
291
|
+
ctx: AstroEmitContext,
|
|
303
292
|
): string[] {
|
|
304
293
|
const entries: string[] = [];
|
|
305
294
|
const values = Object.entries(mapping.values);
|
|
306
295
|
if (values.length === 0) return entries;
|
|
307
296
|
|
|
297
|
+
// Mappings reference component props by bare identifier. Those identifiers
|
|
298
|
+
// only exist inside a component definition — on a page the reference would
|
|
299
|
+
// be an undefined variable (an Astro build error). Mirror the runtime, where
|
|
300
|
+
// resolveStyleMapping() receives no props at page scope and drops the
|
|
301
|
+
// property: emit no conditional entries outside a component def.
|
|
302
|
+
if (!ctx.isComponentDef) return entries;
|
|
303
|
+
|
|
308
304
|
// Generate utility class for each possible value
|
|
309
|
-
const propRef =
|
|
305
|
+
const propRef = mapping.prop;
|
|
310
306
|
|
|
311
307
|
if (values.length === 2) {
|
|
312
308
|
const [[val1, css1], [val2, css2]] = values;
|
|
@@ -342,11 +338,7 @@ function coerceValue(val: string): string | boolean {
|
|
|
342
338
|
/**
|
|
343
339
|
* Generate a Tailwind class name for a single property:value pair
|
|
344
340
|
*/
|
|
345
|
-
function getClassForValue(
|
|
346
|
-
property: string,
|
|
347
|
-
value: string | number,
|
|
348
|
-
breakpointPrefix: string
|
|
349
|
-
): string | null {
|
|
341
|
+
function getClassForValue(property: string, value: string | number, breakpointPrefix: string): string | null {
|
|
350
342
|
const twClass = propertyToTailwind(property, value);
|
|
351
343
|
if (!twClass) return null;
|
|
352
344
|
return breakpointPrefix ? `${breakpointPrefix}${twClass}` : twClass;
|
|
@@ -360,7 +352,7 @@ function buildClassAndStyleExpression(
|
|
|
360
352
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
361
353
|
interactiveStyles: InteractiveStyles | undefined,
|
|
362
354
|
elementClass: string | null,
|
|
363
|
-
ctx: AstroEmitContext
|
|
355
|
+
ctx: AstroEmitContext,
|
|
364
356
|
): { classExpr: string; styleAttr: string } {
|
|
365
357
|
// Static Tailwind classes from non-mapping styles
|
|
366
358
|
const result = style
|
|
@@ -379,11 +371,12 @@ function buildClassAndStyleExpression(
|
|
|
379
371
|
const mappings = collectStyleMappings(style);
|
|
380
372
|
|
|
381
373
|
for (const { property, mapping, breakpoint } of mappings) {
|
|
382
|
-
const bpValue =
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
374
|
+
const bpValue =
|
|
375
|
+
breakpoint === 'tablet'
|
|
376
|
+
? (ctx.breakpoints.tablet?.breakpoint ?? 1024)
|
|
377
|
+
: breakpoint === 'mobile'
|
|
378
|
+
? (ctx.breakpoints.mobile?.breakpoint ?? 540)
|
|
379
|
+
: 0;
|
|
387
380
|
const prefix = bpValue ? `max-[${bpValue}px]:` : '';
|
|
388
381
|
const entries = mappingToClassListEntries(mapping, property, prefix, ctx);
|
|
389
382
|
conditionals.push(...entries);
|
|
@@ -392,17 +385,6 @@ function buildClassAndStyleExpression(
|
|
|
392
385
|
// Build style attribute for dynamic (template expression) styles
|
|
393
386
|
let styleAttr = '';
|
|
394
387
|
if (Object.keys(dynamicStyles).length > 0 && ctx.isComponentDef) {
|
|
395
|
-
const styleParts: string[] = [];
|
|
396
|
-
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
397
|
-
// Convert {{propName}} to Astro expression in style
|
|
398
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
399
|
-
let trimmed = expr.trim();
|
|
400
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
401
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
402
|
-
return `\${${trimmed}}`;
|
|
403
|
-
});
|
|
404
|
-
styleParts.push(`${cssProp}: \${${resolved.includes('${') ? resolved.replace(/\$\{(.+?)\}/g, '$1') : `'${resolved}'`}}`);
|
|
405
|
-
}
|
|
406
388
|
// Build as template literal style attribute
|
|
407
389
|
const entries: string[] = [];
|
|
408
390
|
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
@@ -418,7 +400,12 @@ function buildClassAndStyleExpression(
|
|
|
418
400
|
}
|
|
419
401
|
|
|
420
402
|
// Handle interactive style mappings: emit --is-N CSS variables as inline style
|
|
421
|
-
if (
|
|
403
|
+
if (
|
|
404
|
+
interactiveStyles &&
|
|
405
|
+
interactiveStyles.length > 0 &&
|
|
406
|
+
ctx.isComponentDef &&
|
|
407
|
+
hasInteractiveStyleMappings(interactiveStyles)
|
|
408
|
+
) {
|
|
422
409
|
const { mappings } = extractInteractiveStyleMappings(interactiveStyles);
|
|
423
410
|
if (mappings.length > 0) {
|
|
424
411
|
// Group mappings by prop for efficient ternary generation
|
|
@@ -430,7 +417,9 @@ function buildClassAndStyleExpression(
|
|
|
430
417
|
|
|
431
418
|
if (entries.length === 2) {
|
|
432
419
|
const [[val1, css1], [val2, css2]] = entries;
|
|
433
|
-
varParts.push(
|
|
420
|
+
varParts.push(
|
|
421
|
+
`'${varName}': ${mapping.prop} === ${JSON.stringify(coerceValue(val1))} ? '${css1}' : '${css2}'`,
|
|
422
|
+
);
|
|
434
423
|
} else {
|
|
435
424
|
// Build a lookup object inline
|
|
436
425
|
const lookupEntries = entries
|
|
@@ -443,9 +432,7 @@ function buildClassAndStyleExpression(
|
|
|
443
432
|
|
|
444
433
|
// Merge with existing dynamic styles
|
|
445
434
|
if (varParts.length > 0) {
|
|
446
|
-
const existingStyleParts = styleAttr
|
|
447
|
-
? styleAttr.replace(/^ style=\{`/, '').replace(/`\}$/, '')
|
|
448
|
-
: '';
|
|
435
|
+
const existingStyleParts = styleAttr ? styleAttr.replace(/^ style=\{`/, '').replace(/`\}$/, '') : '';
|
|
449
436
|
const varStyleExpr = varParts.join(', ');
|
|
450
437
|
if (existingStyleParts) {
|
|
451
438
|
styleAttr = ` style={\`${existingStyleParts}; \${ Object.entries({${varStyleExpr}}).map(([k,v]) => \`\${k}:\${v}\`).join(';') }\`}`;
|
|
@@ -516,10 +503,7 @@ function hasTemplates(text: string): boolean {
|
|
|
516
503
|
/**
|
|
517
504
|
* Build element class name for interactive styles
|
|
518
505
|
*/
|
|
519
|
-
function buildElementClass(
|
|
520
|
-
ctx: AstroEmitContext,
|
|
521
|
-
label: string | undefined
|
|
522
|
-
): string {
|
|
506
|
+
function buildElementClass(ctx: AstroEmitContext, label: string | undefined): string {
|
|
523
507
|
return generateElementClassName({
|
|
524
508
|
fileType: ctx.fileType,
|
|
525
509
|
fileName: ctx.fileName,
|
|
@@ -528,9 +512,7 @@ function buildElementClass(
|
|
|
528
512
|
});
|
|
529
513
|
}
|
|
530
514
|
|
|
531
|
-
function isResponsiveStyleObject(
|
|
532
|
-
style: StyleObject | ResponsiveStyleObject
|
|
533
|
-
): style is ResponsiveStyleObject {
|
|
515
|
+
function isResponsiveStyleObject(style: StyleObject | ResponsiveStyleObject): style is ResponsiveStyleObject {
|
|
534
516
|
return 'base' in style || 'tablet' in style || 'mobile' in style;
|
|
535
517
|
}
|
|
536
518
|
|
|
@@ -539,14 +521,10 @@ function isResponsiveStyleObject(
|
|
|
539
521
|
* link roots, or `props.style` for a component/link-instance root. Used to
|
|
540
522
|
* replicate SSR's per-breakpoint merge of an instance override into the root.
|
|
541
523
|
*/
|
|
542
|
-
function getComponentRootStyle(
|
|
543
|
-
def
|
|
544
|
-
): StyleObject | ResponsiveStyleObject | undefined {
|
|
545
|
-
const root = def?.component?.structure as
|
|
546
|
-
| { style?: unknown; props?: { style?: unknown } }
|
|
547
|
-
| undefined;
|
|
524
|
+
function getComponentRootStyle(def: ComponentDefinition | undefined): StyleObject | ResponsiveStyleObject | undefined {
|
|
525
|
+
const root = def?.component?.structure as { style?: unknown; props?: { style?: unknown } } | undefined;
|
|
548
526
|
if (!root || typeof root !== 'object') return undefined;
|
|
549
|
-
const s =
|
|
527
|
+
const s = root.style ?? root.props?.style;
|
|
550
528
|
return s && typeof s === 'object' ? (s as StyleObject | ResponsiveStyleObject) : undefined;
|
|
551
529
|
}
|
|
552
530
|
|
|
@@ -559,7 +537,7 @@ function getComponentRootStyle(
|
|
|
559
537
|
function hasNonEmptyStyle(style: StyleObject | ResponsiveStyleObject): boolean {
|
|
560
538
|
if (isResponsiveStyleObject(style)) {
|
|
561
539
|
return Object.values(style).some(
|
|
562
|
-
(branch) => !!branch && typeof branch === 'object' && Object.keys(branch as object).length > 0
|
|
540
|
+
(branch) => !!branch && typeof branch === 'object' && Object.keys(branch as object).length > 0,
|
|
563
541
|
);
|
|
564
542
|
}
|
|
565
543
|
return Object.keys(style).length > 0;
|
|
@@ -583,22 +561,19 @@ function stripTemplateExpressionStyle<T extends StyleObject | ResponsiveStyleObj
|
|
|
583
561
|
if (isResponsiveStyleObject(style)) {
|
|
584
562
|
const out: Record<string, unknown> = {};
|
|
585
563
|
for (const [bp, branch] of Object.entries(style as Record<string, unknown>)) {
|
|
586
|
-
out[bp] = branch && typeof branch === 'object'
|
|
587
|
-
? cleanFlat(branch as Record<string, unknown>)
|
|
588
|
-
: branch;
|
|
564
|
+
out[bp] = branch && typeof branch === 'object' ? cleanFlat(branch as Record<string, unknown>) : branch;
|
|
589
565
|
}
|
|
590
566
|
return out as T;
|
|
591
567
|
}
|
|
592
568
|
return cleanFlat(style as Record<string, unknown>) as T;
|
|
593
569
|
}
|
|
594
570
|
|
|
595
|
-
|
|
596
571
|
/**
|
|
597
572
|
* Build HTML attributes string from node attributes
|
|
598
573
|
*/
|
|
599
574
|
function buildAttributesString(
|
|
600
575
|
attributes: Record<string, string | number | boolean> | undefined,
|
|
601
|
-
ctx: AstroEmitContext
|
|
576
|
+
ctx: AstroEmitContext,
|
|
602
577
|
): string {
|
|
603
578
|
if (!attributes) return '';
|
|
604
579
|
const parts: string[] = [];
|
|
@@ -651,7 +626,7 @@ function buildAttributesString(
|
|
|
651
626
|
} else if (ctx.cmsMode && /\{\{cms\./.test(strVal)) {
|
|
652
627
|
// CMS mode: transform {{cms.field}} in attributes
|
|
653
628
|
const b = ctx.cmsEntryBinding || 'entry';
|
|
654
|
-
const w = (expr: string) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
629
|
+
const w = (expr: string) => (ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr);
|
|
655
630
|
const fullMatch = strVal.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
656
631
|
if (fullMatch) {
|
|
657
632
|
parts.push(`${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`);
|
|
@@ -702,7 +677,7 @@ function resolveI18n(value: unknown, ctx: AstroEmitContext): unknown {
|
|
|
702
677
|
*/
|
|
703
678
|
export function nodeToAstro(
|
|
704
679
|
node: ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
705
|
-
ctx: AstroEmitContext
|
|
680
|
+
ctx: AstroEmitContext,
|
|
706
681
|
): string {
|
|
707
682
|
if (node === null || node === undefined) return '';
|
|
708
683
|
|
|
@@ -718,6 +693,18 @@ export function nodeToAstro(
|
|
|
718
693
|
ctx.needsI18nResolver = true;
|
|
719
694
|
return `${ind(ctx)}{r(${JSON.stringify(stripRawHtmlPrefixDeep(resolved))})}\n`;
|
|
720
695
|
}
|
|
696
|
+
// Page context without a locale: resolve through the default locale
|
|
697
|
+
// (resolveTranslation falls back exact → default → first available →
|
|
698
|
+
// empty) instead of stringifying the i18n object to "[object Object]".
|
|
699
|
+
if (isI18nValue(resolved)) {
|
|
700
|
+
const config = ctx.i18nConfig ?? DEFAULT_I18N_CONFIG;
|
|
701
|
+
const fallbackLocale = ctx.defaultLocale ?? config.defaultLocale;
|
|
702
|
+
const fallbackResolved = resolveI18nValue(resolved, fallbackLocale, config);
|
|
703
|
+
if (typeof fallbackResolved === 'string') {
|
|
704
|
+
return nodeToAstro(fallbackResolved, ctx);
|
|
705
|
+
}
|
|
706
|
+
return `${ind(ctx)}${String(fallbackResolved ?? '')}\n`;
|
|
707
|
+
}
|
|
721
708
|
// If resolution returned a non-string (e.g. array), stringify it
|
|
722
709
|
return `${ind(ctx)}${String(resolved ?? '')}\n`;
|
|
723
710
|
}
|
|
@@ -726,7 +713,12 @@ export function nodeToAstro(
|
|
|
726
713
|
if (typeof node === 'string') {
|
|
727
714
|
// CMS mode: transform {{cms.field}} expressions to entry data access
|
|
728
715
|
if (ctx.cmsMode && isTemplateExpression(node) && /\{\{cms\./.test(node)) {
|
|
729
|
-
const transformed = transformCMSTemplate(
|
|
716
|
+
const transformed = transformCMSTemplate(
|
|
717
|
+
node,
|
|
718
|
+
ctx.cmsEntryBinding || 'entry',
|
|
719
|
+
ctx.cmsRichTextFields,
|
|
720
|
+
ctx.cmsWrapFn,
|
|
721
|
+
);
|
|
730
722
|
return `${ind(ctx)}${transformed}\n`;
|
|
731
723
|
}
|
|
732
724
|
// List item binding: transform {{item.field}} expressions
|
|
@@ -821,7 +813,7 @@ function splitImageClasses(allClasses: string[]): { pictureClasses: string[]; im
|
|
|
821
813
|
for (const cls of allClasses) {
|
|
822
814
|
// Strip responsive prefix (e.g., "md:object-cover" -> "object-cover") for matching
|
|
823
815
|
const baseCls = cls.includes(':') ? cls.split(':').pop()! : cls;
|
|
824
|
-
if (IMG_TAILWIND_PREFIXES.some(p => baseCls.startsWith(p)) || IMG_OPACITY_PATTERN.test(baseCls)) {
|
|
816
|
+
if (IMG_TAILWIND_PREFIXES.some((p) => baseCls.startsWith(p)) || IMG_OPACITY_PATTERN.test(baseCls)) {
|
|
825
817
|
imgClasses.push(cls);
|
|
826
818
|
} else {
|
|
827
819
|
pictureClasses.push(cls);
|
|
@@ -852,7 +844,7 @@ function extractPxWidth(val: unknown): number | null {
|
|
|
852
844
|
*/
|
|
853
845
|
function computeSizesAttribute(
|
|
854
846
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
855
|
-
breakpoints: BreakpointConfig
|
|
847
|
+
breakpoints: BreakpointConfig,
|
|
856
848
|
): string {
|
|
857
849
|
if (!style) return DEFAULT_SIZES;
|
|
858
850
|
|
|
@@ -868,9 +860,7 @@ function computeSizesAttribute(
|
|
|
868
860
|
|
|
869
861
|
// Walk breakpoints from smallest to largest so the emitted media queries
|
|
870
862
|
// are ordered from narrowest to widest, with the unconditional base last.
|
|
871
|
-
const bpEntries = Object.entries(breakpoints).sort(
|
|
872
|
-
(a, b) => a[1].breakpoint - b[1].breakpoint
|
|
873
|
-
);
|
|
863
|
+
const bpEntries = Object.entries(breakpoints).sort((a, b) => a[1].breakpoint - b[1].breakpoint);
|
|
874
864
|
|
|
875
865
|
const parts: string[] = [];
|
|
876
866
|
// Track the "effective" width as we walk up: if a breakpoint doesn't set its
|
|
@@ -905,13 +895,34 @@ function computeSizesAttribute(
|
|
|
905
895
|
}
|
|
906
896
|
|
|
907
897
|
/**
|
|
908
|
-
* Merge additional CSS declarations into an existing ` style
|
|
909
|
-
* string. If no style attribute exists yet, builds one.
|
|
910
|
-
*
|
|
898
|
+
* Merge additional CSS declarations into an existing ` style` attribute
|
|
899
|
+
* string. If no style attribute exists yet, builds a static one. Handles all
|
|
900
|
+
* three attr shapes the emitter produces: static `style="..."`, dynamic
|
|
901
|
+
* template-literal `style={\`...\`}`, and dynamic expression `style={...}`.
|
|
902
|
+
* The inputs are raw CSS already escaped for HTML attribute context.
|
|
911
903
|
*/
|
|
912
904
|
function injectInlineStyle(styleAttr: string, extraCss: string): string {
|
|
913
905
|
if (!extraCss) return styleAttr;
|
|
914
906
|
if (!styleAttr) return ` style="${extraCss}"`;
|
|
907
|
+
|
|
908
|
+
// Dynamic template-literal style attr (` style={`...`}`): append the extra
|
|
909
|
+
// declarations inside the template literal so they survive the merge.
|
|
910
|
+
const dynLiteralMatch = styleAttr.match(/^ style=\{`([\s\S]*)`\}$/);
|
|
911
|
+
if (dynLiteralMatch) {
|
|
912
|
+
const existing = dynLiteralMatch[1];
|
|
913
|
+
const trimmed = existing.trimEnd();
|
|
914
|
+
const sep = trimmed.length > 0 && !trimmed.endsWith(';') ? ';' : '';
|
|
915
|
+
return ` style={\`${existing}${sep}${extraCss}\`}`;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// Dynamic expression style attr (` style={expr}`, e.g. the Object.entries()
|
|
919
|
+
// form for interactive style mappings): wrap the expression in a template
|
|
920
|
+
// literal and append the extra declarations after it.
|
|
921
|
+
const dynExprMatch = styleAttr.match(/^ style=\{([\s\S]*)\}$/);
|
|
922
|
+
if (dynExprMatch) {
|
|
923
|
+
return ` style={\`\${${dynExprMatch[1]}};${extraCss}\`}`;
|
|
924
|
+
}
|
|
925
|
+
|
|
915
926
|
return styleAttr.replace(/style="([^"]*)"/, (_, existing: string) => {
|
|
916
927
|
const trimmed = existing.trimEnd();
|
|
917
928
|
const sep = trimmed.length > 0 && !trimmed.endsWith(';') ? ';' : '';
|
|
@@ -932,7 +943,10 @@ const PICTURE_WIDTHS = [500, 800, 1080, 1600, 2400];
|
|
|
932
943
|
* identifier (`imgSubHeroPhoto`) for use as an ESM import variable.
|
|
933
944
|
*/
|
|
934
945
|
function imagePathToVarName(srcPath: string): string {
|
|
935
|
-
const stripped = srcPath
|
|
946
|
+
const stripped = srcPath
|
|
947
|
+
.replace(/^\/+/, '')
|
|
948
|
+
.replace(/^images\//, '')
|
|
949
|
+
.replace(/\.[^.]+$/, '');
|
|
936
950
|
const parts = stripped.split(/[/_\-\s.]+/).filter(Boolean);
|
|
937
951
|
if (parts.length === 0) return 'imgAsset';
|
|
938
952
|
const camel = parts
|
|
@@ -1003,9 +1017,7 @@ function registerStaticImageImport(src: string, ctx: AstroEmitContext): string {
|
|
|
1003
1017
|
* object-cover / opacity-* keep landing on the <img>. Returns null when the
|
|
1004
1018
|
* class expression is dynamic (class:list) — callers fall back to div wrap.
|
|
1005
1019
|
*/
|
|
1006
|
-
function splitStaticClassExpr(
|
|
1007
|
-
classExpr: string
|
|
1008
|
-
): { outerClasses: string[]; innerClasses: string[] } | null {
|
|
1020
|
+
function splitStaticClassExpr(classExpr: string): { outerClasses: string[]; innerClasses: string[] } | null {
|
|
1009
1021
|
if (classExpr.includes('class:list=')) return null;
|
|
1010
1022
|
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1011
1023
|
if (!classMatch) return { outerClasses: [], innerClasses: [] };
|
|
@@ -1018,10 +1030,7 @@ function splitStaticClassExpr(
|
|
|
1018
1030
|
* Format a static class+style pair as an Astro `pictureAttributes={{...}}`
|
|
1019
1031
|
* prop. `classValue` comes pre-split (outer layout classes only).
|
|
1020
1032
|
*/
|
|
1021
|
-
function formatPictureAttributesProp(
|
|
1022
|
-
classValue: string,
|
|
1023
|
-
styleAttr: string
|
|
1024
|
-
): string {
|
|
1033
|
+
function formatPictureAttributesProp(classValue: string, styleAttr: string): string {
|
|
1025
1034
|
const styleMatch = styleAttr.match(/style="([^"]*)"/);
|
|
1026
1035
|
const parts: string[] = [];
|
|
1027
1036
|
if (classValue) parts.push(`class: ${JSON.stringify(classValue)}`);
|
|
@@ -1045,7 +1054,7 @@ function emitStaticPictureImage(
|
|
|
1045
1054
|
ifExpr: string,
|
|
1046
1055
|
ifClose: string,
|
|
1047
1056
|
blurHash: string | undefined,
|
|
1048
|
-
ctx: AstroEmitContext
|
|
1057
|
+
ctx: AstroEmitContext,
|
|
1049
1058
|
): string {
|
|
1050
1059
|
const varName = registerStaticImageImport(src, ctx);
|
|
1051
1060
|
|
|
@@ -1093,9 +1102,7 @@ function emitStaticPictureImage(
|
|
|
1093
1102
|
// on the <picture>, inner img-specific classes as `class` on <Picture>.
|
|
1094
1103
|
if (split) {
|
|
1095
1104
|
const outerClassValue = split.outerClasses.join(' ');
|
|
1096
|
-
const innerClassAttr = split.innerClasses.length > 0
|
|
1097
|
-
? ` class="${split.innerClasses.join(' ')}"`
|
|
1098
|
-
: '';
|
|
1105
|
+
const innerClassAttr = split.innerClasses.length > 0 ? ` class="${split.innerClasses.join(' ')}"` : '';
|
|
1099
1106
|
const pictureAttrs = formatPictureAttributesProp(outerClassValue, styleAttr);
|
|
1100
1107
|
return `${ifExpr}${ind(ctx)}<Picture${pictureAttrs} src={${varName}}${altAttr}${innerClassAttr} formats={['avif','webp']} widths={${widthsLiteral}} sizes="${escapeJSX(sizesValue)}"${loadingAttr}${fetchpriorityAttr} />\n${ifClose}`;
|
|
1101
1108
|
}
|
|
@@ -1113,10 +1120,7 @@ function emitImageNode(node: HtmlNode, ctx: AstroEmitContext): string {
|
|
|
1113
1120
|
|
|
1114
1121
|
// Element class for interactive styles
|
|
1115
1122
|
let elementClass: string | null = null;
|
|
1116
|
-
if (
|
|
1117
|
-
(node.interactiveStyles && node.interactiveStyles.length > 0) ||
|
|
1118
|
-
node.generateElementClass
|
|
1119
|
-
) {
|
|
1123
|
+
if ((node.interactiveStyles && node.interactiveStyles.length > 0) || node.generateElementClass) {
|
|
1120
1124
|
elementClass = buildElementClass(ctx, node.label);
|
|
1121
1125
|
if (elementClass && node.interactiveStyles?.length && ctx.collectedInteractiveStyles) {
|
|
1122
1126
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
@@ -1127,7 +1131,7 @@ function emitImageNode(node: HtmlNode, ctx: AstroEmitContext): string {
|
|
|
1127
1131
|
style,
|
|
1128
1132
|
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1129
1133
|
elementClass,
|
|
1130
|
-
ctx
|
|
1134
|
+
ctx,
|
|
1131
1135
|
);
|
|
1132
1136
|
|
|
1133
1137
|
// Extract image-specific attributes
|
|
@@ -1166,7 +1170,7 @@ function emitImageNode(node: HtmlNode, ctx: AstroEmitContext): string {
|
|
|
1166
1170
|
emitIfOpen(node, ctx),
|
|
1167
1171
|
emitIfClose(node, ctx),
|
|
1168
1172
|
metadata?.blurHash,
|
|
1169
|
-
ctx
|
|
1173
|
+
ctx,
|
|
1170
1174
|
);
|
|
1171
1175
|
}
|
|
1172
1176
|
|
|
@@ -1198,12 +1202,8 @@ function emitImageNode(node: HtmlNode, ctx: AstroEmitContext): string {
|
|
|
1198
1202
|
// is a replaced element and doesn't paint CSS backgrounds reliably).
|
|
1199
1203
|
// Once the real image loads we clear the background on the wrapper so the
|
|
1200
1204
|
// low-quality placeholder disappears.
|
|
1201
|
-
const blurWrapperCss = hasBlur
|
|
1202
|
-
|
|
1203
|
-
: '';
|
|
1204
|
-
const blurOnload = hasBlur
|
|
1205
|
-
? ` onload="this.parentElement.style.backgroundImage=''"`
|
|
1206
|
-
: '';
|
|
1205
|
+
const blurWrapperCss = hasBlur ? `background-image:url(${escapeJSX(metadata!.blurHash!)});background-size:cover` : '';
|
|
1206
|
+
const blurOnload = hasBlur ? ` onload="this.parentElement.style.backgroundImage=''"` : '';
|
|
1207
1207
|
|
|
1208
1208
|
// Conditional rendering
|
|
1209
1209
|
const ifExpr = emitIfOpen(node, ctx);
|
|
@@ -1302,17 +1302,19 @@ function emitHtmlNode(node: HtmlNode, ctx: AstroEmitContext): string {
|
|
|
1302
1302
|
|
|
1303
1303
|
// Element class for interactive styles
|
|
1304
1304
|
let elementClass: string | null = null;
|
|
1305
|
-
if (
|
|
1306
|
-
(node.interactiveStyles && node.interactiveStyles.length > 0) ||
|
|
1307
|
-
node.generateElementClass
|
|
1308
|
-
) {
|
|
1305
|
+
if ((node.interactiveStyles && node.interactiveStyles.length > 0) || node.generateElementClass) {
|
|
1309
1306
|
elementClass = buildElementClass(ctx, label);
|
|
1310
1307
|
if (elementClass && node.interactiveStyles?.length && ctx.collectedInteractiveStyles) {
|
|
1311
1308
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
1312
1309
|
}
|
|
1313
1310
|
}
|
|
1314
1311
|
|
|
1315
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1312
|
+
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1313
|
+
style,
|
|
1314
|
+
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1315
|
+
elementClass,
|
|
1316
|
+
ctx,
|
|
1317
|
+
);
|
|
1316
1318
|
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1317
1319
|
|
|
1318
1320
|
// Dynamic tags use the variable name directly (capitalized, defined in frontmatter)
|
|
@@ -1369,7 +1371,7 @@ function emitComponentInstance(node: ComponentInstanceNode, ctx: AstroEmitContex
|
|
|
1369
1371
|
}
|
|
1370
1372
|
} else if (typeof value === 'string' && ctx.cmsMode && /\{\{cms\./.test(value)) {
|
|
1371
1373
|
const b = ctx.cmsEntryBinding || 'entry';
|
|
1372
|
-
const w = (expr: string) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
1374
|
+
const w = (expr: string) => (ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr);
|
|
1373
1375
|
const fullMatch = value.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
1374
1376
|
if (fullMatch) {
|
|
1375
1377
|
propParts.push(`${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`);
|
|
@@ -1433,9 +1435,9 @@ function emitComponentInstance(node: ComponentInstanceNode, ctx: AstroEmitContex
|
|
|
1433
1435
|
// root are dropped downstream (styleObjectToCSS skips mappings) /
|
|
1434
1436
|
// stripped here, falling back to the component's own emission.
|
|
1435
1437
|
const rootStyle = getComponentRootStyle(ctx.globalComponents[node.component]);
|
|
1436
|
-
const merged = (rootStyle
|
|
1437
|
-
|
|
1438
|
-
|
|
1438
|
+
const merged = (rootStyle ? deepMergeStyles(rootStyle, instanceStyle!) : instanceStyle!) as
|
|
1439
|
+
| StyleObject
|
|
1440
|
+
| ResponsiveStyleObject;
|
|
1439
1441
|
const cssSafe = stripTemplateExpressionStyle(merged);
|
|
1440
1442
|
if (hasNonEmptyStyle(cssSafe)) rules.push({ style: cssSafe }); // no prefix/postfix → `.cls {…}`
|
|
1441
1443
|
}
|
|
@@ -1460,22 +1462,14 @@ function emitComponentInstance(node: ComponentInstanceNode, ctx: AstroEmitContex
|
|
|
1460
1462
|
return `${ifExpr}${ind(ctx)}<${name}${propsStr} />\n${emitIfClose(node, ctx)}`;
|
|
1461
1463
|
}
|
|
1462
1464
|
|
|
1463
|
-
return (
|
|
1464
|
-
`${ifExpr}${ind(ctx)}<${name}${propsStr}>\n` +
|
|
1465
|
-
children +
|
|
1466
|
-
`${ind(ctx)}</${name}>\n${emitIfClose(node, ctx)}`
|
|
1467
|
-
);
|
|
1465
|
+
return `${ifExpr}${ind(ctx)}<${name}${propsStr}>\n` + children + `${ind(ctx)}</${name}>\n${emitIfClose(node, ctx)}`;
|
|
1468
1466
|
}
|
|
1469
1467
|
|
|
1470
1468
|
function emitSlotMarker(node: SlotMarker, ctx: AstroEmitContext): string {
|
|
1471
1469
|
if (node.default) {
|
|
1472
1470
|
const defaultContent = emitChildren(node.default as (ComponentNode | string)[] | string | undefined, ctx);
|
|
1473
1471
|
if (defaultContent.trim()) {
|
|
1474
|
-
return (
|
|
1475
|
-
`${ind(ctx)}<slot>\n` +
|
|
1476
|
-
defaultContent +
|
|
1477
|
-
`${ind(ctx)}</slot>\n`
|
|
1478
|
-
);
|
|
1472
|
+
return `${ind(ctx)}<slot>\n` + defaultContent + `${ind(ctx)}</slot>\n`;
|
|
1479
1473
|
}
|
|
1480
1474
|
}
|
|
1481
1475
|
return `${ind(ctx)}<slot />\n`;
|
|
@@ -1486,17 +1480,19 @@ function emitEmbedNode(node: EmbedNode, ctx: AstroEmitContext): string {
|
|
|
1486
1480
|
const style = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1487
1481
|
|
|
1488
1482
|
let elementClass: string | null = null;
|
|
1489
|
-
if (
|
|
1490
|
-
(node.interactiveStyles && node.interactiveStyles.length > 0) ||
|
|
1491
|
-
node.generateElementClass
|
|
1492
|
-
) {
|
|
1483
|
+
if ((node.interactiveStyles && node.interactiveStyles.length > 0) || node.generateElementClass) {
|
|
1493
1484
|
elementClass = buildElementClass(ctx, node.label);
|
|
1494
1485
|
if (elementClass && node.interactiveStyles?.length && ctx.collectedInteractiveStyles) {
|
|
1495
1486
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
1496
1487
|
}
|
|
1497
1488
|
}
|
|
1498
1489
|
|
|
1499
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1490
|
+
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1491
|
+
style,
|
|
1492
|
+
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1493
|
+
elementClass,
|
|
1494
|
+
ctx,
|
|
1495
|
+
);
|
|
1500
1496
|
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1501
1497
|
|
|
1502
1498
|
// Handle HTML mapping (prop-dependent content)
|
|
@@ -1561,10 +1557,7 @@ function emitLinkNode(node: LinkNode, ctx: AstroEmitContext): string {
|
|
|
1561
1557
|
const style = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1562
1558
|
|
|
1563
1559
|
let elementClass: string | null = null;
|
|
1564
|
-
if (
|
|
1565
|
-
(node.interactiveStyles && node.interactiveStyles.length > 0) ||
|
|
1566
|
-
node.generateElementClass
|
|
1567
|
-
) {
|
|
1560
|
+
if ((node.interactiveStyles && node.interactiveStyles.length > 0) || node.generateElementClass) {
|
|
1568
1561
|
elementClass = buildElementClass(ctx, node.label);
|
|
1569
1562
|
if (elementClass && node.interactiveStyles?.length && ctx.collectedInteractiveStyles) {
|
|
1570
1563
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
@@ -1572,7 +1565,12 @@ function emitLinkNode(node: LinkNode, ctx: AstroEmitContext): string {
|
|
|
1572
1565
|
}
|
|
1573
1566
|
|
|
1574
1567
|
// Build class expression with olink base class
|
|
1575
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1568
|
+
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1569
|
+
style,
|
|
1570
|
+
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1571
|
+
elementClass,
|
|
1572
|
+
ctx,
|
|
1573
|
+
);
|
|
1576
1574
|
let finalClassExpr = classExpr;
|
|
1577
1575
|
if (!classExpr.includes('olink')) {
|
|
1578
1576
|
if (classExpr) {
|
|
@@ -1622,7 +1620,7 @@ function emitLinkNode(node: LinkNode, ctx: AstroEmitContext): string {
|
|
|
1622
1620
|
}
|
|
1623
1621
|
} else if (ctx.cmsMode && /\{\{cms\./.test(href)) {
|
|
1624
1622
|
const b = ctx.cmsEntryBinding || 'entry';
|
|
1625
|
-
const w = (expr: string) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
1623
|
+
const w = (expr: string) => (ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr);
|
|
1626
1624
|
const fullMatch = href.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
1627
1625
|
if (fullMatch) {
|
|
1628
1626
|
hrefAttr = ` href={${w(`${b}.data.${fullMatch[1].trim()}`)}}`;
|
|
@@ -1660,10 +1658,7 @@ function emitImageTypeNode(node: any, ctx: AstroEmitContext): string {
|
|
|
1660
1658
|
const style = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1661
1659
|
|
|
1662
1660
|
let elementClass: string | null = null;
|
|
1663
|
-
if (
|
|
1664
|
-
(node.interactiveStyles && node.interactiveStyles.length > 0) ||
|
|
1665
|
-
node.generateElementClass
|
|
1666
|
-
) {
|
|
1661
|
+
if ((node.interactiveStyles && node.interactiveStyles.length > 0) || node.generateElementClass) {
|
|
1667
1662
|
elementClass = buildElementClass(ctx, node.label);
|
|
1668
1663
|
if (elementClass && node.interactiveStyles?.length && ctx.collectedInteractiveStyles) {
|
|
1669
1664
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
@@ -1674,7 +1669,7 @@ function emitImageTypeNode(node: any, ctx: AstroEmitContext): string {
|
|
|
1674
1669
|
style,
|
|
1675
1670
|
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1676
1671
|
elementClass,
|
|
1677
|
-
ctx
|
|
1672
|
+
ctx,
|
|
1678
1673
|
);
|
|
1679
1674
|
|
|
1680
1675
|
const src = node.src as string | undefined;
|
|
@@ -1694,7 +1689,7 @@ function emitImageTypeNode(node: any, ctx: AstroEmitContext): string {
|
|
|
1694
1689
|
'',
|
|
1695
1690
|
'',
|
|
1696
1691
|
staticMeta.blurHash,
|
|
1697
|
-
ctx
|
|
1692
|
+
ctx,
|
|
1698
1693
|
);
|
|
1699
1694
|
}
|
|
1700
1695
|
|
|
@@ -1718,12 +1713,8 @@ function emitImageTypeNode(node: any, ctx: AstroEmitContext): string {
|
|
|
1718
1713
|
const hasBlur = !!metadata.blurHash;
|
|
1719
1714
|
const useWrapper = hasAvif || hasBlur;
|
|
1720
1715
|
|
|
1721
|
-
const blurWrapperCss = hasBlur
|
|
1722
|
-
|
|
1723
|
-
: '';
|
|
1724
|
-
const blurOnload = hasBlur
|
|
1725
|
-
? ` onload="this.parentElement.style.backgroundImage=''"`
|
|
1726
|
-
: '';
|
|
1716
|
+
const blurWrapperCss = hasBlur ? `background-image:url(${escapeJSX(metadata.blurHash!)});background-size:cover` : '';
|
|
1717
|
+
const blurOnload = hasBlur ? ` onload="this.parentElement.style.backgroundImage=''"` : '';
|
|
1727
1718
|
|
|
1728
1719
|
if (useWrapper) {
|
|
1729
1720
|
const imgFillClasses = IMG_FILL_CLASSES.slice();
|
|
@@ -1812,19 +1803,17 @@ function emitListNode(node: ListNode, ctx: AstroEmitContext): string {
|
|
|
1812
1803
|
};
|
|
1813
1804
|
|
|
1814
1805
|
const children = node.children
|
|
1815
|
-
? (node.children as (ComponentNode | string)[])
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1806
|
+
? (node.children as (ComponentNode | string)[])
|
|
1807
|
+
.map((child, i) => {
|
|
1808
|
+
const childCtx = { ...innerCtx, elementPath: [...ctx.elementPath, i] };
|
|
1809
|
+
const out = nodeToAstro(child, childCtx);
|
|
1810
|
+
if (childCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1811
|
+
return out;
|
|
1812
|
+
})
|
|
1813
|
+
.join('')
|
|
1821
1814
|
: '';
|
|
1822
1815
|
|
|
1823
|
-
return (
|
|
1824
|
-
`${ind(ctx)}{${mapSource}.map((${itemAs}, ${indexVar}) => (\n` +
|
|
1825
|
-
children +
|
|
1826
|
-
`${ind(ctx)}))}\n`
|
|
1827
|
-
);
|
|
1816
|
+
return `${ind(ctx)}{${mapSource}.map((${itemAs}, ${indexVar}) => (\n` + children + `${ind(ctx)}))}\n`;
|
|
1828
1817
|
}
|
|
1829
1818
|
|
|
1830
1819
|
/**
|
|
@@ -1876,8 +1865,7 @@ function emitCollectionListNode(node: ListNode, ctx: AstroEmitContext): string {
|
|
|
1876
1865
|
// shape the templates expect ({{item.field}} → item.field), and synthesize the
|
|
1877
1866
|
// `_url`/`_id` meta the CMS data model exposes. Filter/sort above operate on the
|
|
1878
1867
|
// raw entries (e.data.*); this map runs last so it sees the final set.
|
|
1879
|
-
const urlExpr = ctx.collectionUrlExpr?.get(source)
|
|
1880
|
-
?? `\`/${source}/\${e.data.slug ?? e.id}\``;
|
|
1868
|
+
const urlExpr = ctx.collectionUrlExpr?.get(source) ?? `\`/${source}/\${e.data.slug ?? e.id}\``;
|
|
1881
1869
|
queryChain += `.then(items => items.map((e) => ({ ...e.data, _id: e.id, _url: ${urlExpr} })))`;
|
|
1882
1870
|
|
|
1883
1871
|
ctx.frontmatterLines.push(`const ${collectionVar} = ${queryChain};`);
|
|
@@ -1896,19 +1884,17 @@ function emitCollectionListNode(node: ListNode, ctx: AstroEmitContext): string {
|
|
|
1896
1884
|
};
|
|
1897
1885
|
|
|
1898
1886
|
const children = node.children
|
|
1899
|
-
? (node.children as (ComponentNode | string)[])
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1887
|
+
? (node.children as (ComponentNode | string)[])
|
|
1888
|
+
.map((child, i) => {
|
|
1889
|
+
const childCtx = { ...innerCtx, elementPath: [...ctx.elementPath, i] };
|
|
1890
|
+
const out = nodeToAstro(child, childCtx);
|
|
1891
|
+
if (childCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1892
|
+
return out;
|
|
1893
|
+
})
|
|
1894
|
+
.join('')
|
|
1905
1895
|
: '';
|
|
1906
1896
|
|
|
1907
|
-
return (
|
|
1908
|
-
`${ind(ctx)}{${collectionVar}.map((${itemAs}, ${indexVar}) => (\n` +
|
|
1909
|
-
children +
|
|
1910
|
-
`${ind(ctx)}))}\n`
|
|
1911
|
-
);
|
|
1897
|
+
return `${ind(ctx)}{${collectionVar}.map((${itemAs}, ${indexVar}) => (\n` + children + `${ind(ctx)}))}\n`;
|
|
1912
1898
|
}
|
|
1913
1899
|
|
|
1914
1900
|
/**
|
|
@@ -1932,7 +1918,10 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
1932
1918
|
const style = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1933
1919
|
|
|
1934
1920
|
let elementClass: string | null = null;
|
|
1935
|
-
if (
|
|
1921
|
+
if (
|
|
1922
|
+
(node.interactiveStyles && (node.interactiveStyles as InteractiveStyles).length > 0) ||
|
|
1923
|
+
node.generateElementClass
|
|
1924
|
+
) {
|
|
1936
1925
|
elementClass = buildElementClass(ctx, node.label);
|
|
1937
1926
|
if (elementClass && (node.interactiveStyles as InteractiveStyles)?.length && ctx.collectedInteractiveStyles) {
|
|
1938
1927
|
ctx.collectedInteractiveStyles.set(elementClass, node.interactiveStyles as InteractiveStyles);
|
|
@@ -1943,22 +1932,28 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
1943
1932
|
style,
|
|
1944
1933
|
node.interactiveStyles as InteractiveStyles | undefined,
|
|
1945
1934
|
elementClass,
|
|
1946
|
-
ctx
|
|
1935
|
+
ctx,
|
|
1947
1936
|
);
|
|
1948
1937
|
|
|
1949
1938
|
// Build item classes
|
|
1950
1939
|
const itemStyle = node.itemStyle as StyleObject | ResponsiveStyleObject | undefined;
|
|
1951
|
-
const itemResult = itemStyle
|
|
1940
|
+
const itemResult = itemStyle
|
|
1941
|
+
? responsiveStylesToTailwind(itemStyle, ctx.breakpoints, ctx.responsiveScales)
|
|
1942
|
+
: { classes: [], dynamicStyles: {} };
|
|
1952
1943
|
const itemClasses = itemResult.classes;
|
|
1953
1944
|
|
|
1954
1945
|
// Build active item classes (item + active combined)
|
|
1955
1946
|
const activeItemStyle = node.activeItemStyle as StyleObject | ResponsiveStyleObject | undefined;
|
|
1956
|
-
const activeResult = activeItemStyle
|
|
1947
|
+
const activeResult = activeItemStyle
|
|
1948
|
+
? responsiveStylesToTailwind(activeItemStyle, ctx.breakpoints, ctx.responsiveScales)
|
|
1949
|
+
: { classes: [], dynamicStyles: {} };
|
|
1957
1950
|
const activeItemClasses = [...itemClasses, ...activeResult.classes];
|
|
1958
1951
|
|
|
1959
1952
|
// Build separator classes
|
|
1960
1953
|
const separatorStyle = node.separatorStyle as StyleObject | ResponsiveStyleObject | undefined;
|
|
1961
|
-
const sepResult = separatorStyle
|
|
1954
|
+
const sepResult = separatorStyle
|
|
1955
|
+
? responsiveStylesToTailwind(separatorStyle, ctx.breakpoints, ctx.responsiveScales)
|
|
1956
|
+
: { classes: [], dynamicStyles: {} };
|
|
1962
1957
|
const separatorClasses = sepResult.classes;
|
|
1963
1958
|
|
|
1964
1959
|
// Build locale icon map
|
|
@@ -1971,7 +1966,9 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
1971
1966
|
|
|
1972
1967
|
// Flag classes
|
|
1973
1968
|
const flagStyle = node.flagStyle as StyleObject | ResponsiveStyleObject | undefined;
|
|
1974
|
-
const flagResult = flagStyle
|
|
1969
|
+
const flagResult = flagStyle
|
|
1970
|
+
? responsiveStylesToTailwind(flagStyle, ctx.breakpoints, ctx.responsiveScales)
|
|
1971
|
+
: { classes: [], dynamicStyles: {} };
|
|
1975
1972
|
const flagClasses = flagResult.classes;
|
|
1976
1973
|
|
|
1977
1974
|
// Build links
|
|
@@ -1993,9 +1990,16 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
1993
1990
|
// Display text
|
|
1994
1991
|
let displayText: string;
|
|
1995
1992
|
switch (displayType) {
|
|
1996
|
-
case 'code':
|
|
1997
|
-
|
|
1998
|
-
|
|
1993
|
+
case 'code':
|
|
1994
|
+
displayText = code.toUpperCase();
|
|
1995
|
+
break;
|
|
1996
|
+
case 'name':
|
|
1997
|
+
displayText = localeConfig.name;
|
|
1998
|
+
break;
|
|
1999
|
+
case 'nativeName':
|
|
2000
|
+
default:
|
|
2001
|
+
displayText = localeConfig.nativeName;
|
|
2002
|
+
break;
|
|
1999
2003
|
}
|
|
2000
2004
|
|
|
2001
2005
|
// Build link content
|
|
@@ -2007,7 +2011,9 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
2007
2011
|
}
|
|
2008
2012
|
linkContent += `<div>${escapeJSX(displayText)}</div>`;
|
|
2009
2013
|
|
|
2010
|
-
links.push(
|
|
2014
|
+
links.push(
|
|
2015
|
+
`${ind(ctx)} <a href="${escapeJSX(path)}"${hreflangAttr}${currentAttr} data-locale="${escapeJSX(code)}"${classAttr}>${linkContent}</a>`,
|
|
2016
|
+
);
|
|
2011
2017
|
}
|
|
2012
2018
|
|
|
2013
2019
|
// Join with separator
|
|
@@ -2023,7 +2029,8 @@ function emitLocaleListNode(node: LocaleListNode, ctx: AstroEmitContext): string
|
|
|
2023
2029
|
|
|
2024
2030
|
return (
|
|
2025
2031
|
`${ind(ctx)}<div data-locale-list="true"${containerClassExpr}${containerStyleAttr}${attrs}>\n` +
|
|
2026
|
-
linksContent +
|
|
2032
|
+
linksContent +
|
|
2033
|
+
'\n' +
|
|
2027
2034
|
`${ind(ctx)}</div>\n`
|
|
2028
2035
|
);
|
|
2029
2036
|
}
|
|
@@ -2111,6 +2118,10 @@ function emitIfClose(node: ComponentNode, ctx: AstroEmitContext): string {
|
|
|
2111
2118
|
if (typeof ifValue === 'boolean') return '';
|
|
2112
2119
|
|
|
2113
2120
|
if (typeof ifValue === 'object' && ifValue._mapping && ctx.isComponentDef) {
|
|
2121
|
+
// Degenerate mapping (no true values): emitIfOpen emitted only a
|
|
2122
|
+
// `{/* hidden */}` comment, not a `{cond && (` opener — close nothing.
|
|
2123
|
+
const hasTrueValue = Object.values(ifValue.values).some((v) => v === true);
|
|
2124
|
+
if (!hasTrueValue) return '';
|
|
2114
2125
|
return `${ind(ctx)})}\n`;
|
|
2115
2126
|
}
|
|
2116
2127
|
|
|
@@ -2139,7 +2150,7 @@ function emitIfClose(node: ComponentNode, ctx: AstroEmitContext): string {
|
|
|
2139
2150
|
|
|
2140
2151
|
function emitChildren(
|
|
2141
2152
|
children: (ComponentNode | string)[] | string | ComponentNode | null | undefined,
|
|
2142
|
-
ctx: AstroEmitContext
|
|
2153
|
+
ctx: AstroEmitContext,
|
|
2143
2154
|
): string {
|
|
2144
2155
|
if (!children) return '';
|
|
2145
2156
|
|