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
|
@@ -5,25 +5,35 @@ import type { ResponsiveScales } from './responsiveScaling';
|
|
|
5
5
|
|
|
6
6
|
describe('utilityClassMapper', () => {
|
|
7
7
|
describe('stylesToClasses', () => {
|
|
8
|
-
test('converts padding to utility class', () => {
|
|
8
|
+
test('converts padding to arbitrary-value utility class', () => {
|
|
9
9
|
const classes = stylesToClasses({ padding: '10px' });
|
|
10
|
-
expect(classes).toContain('p-10px');
|
|
10
|
+
expect(classes).toContain('p-[10px]');
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
test('converts display flex to
|
|
13
|
+
test('converts display flex to Tailwind static utility', () => {
|
|
14
14
|
const classes = stylesToClasses({ display: 'flex' });
|
|
15
|
-
expect(classes).toContain('
|
|
15
|
+
expect(classes).toContain('flex');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('converts display none to hidden', () => {
|
|
19
|
+
const classes = stylesToClasses({ display: 'none' });
|
|
20
|
+
expect(classes).toContain('hidden');
|
|
16
21
|
});
|
|
17
22
|
|
|
18
23
|
test('converts multiple properties', () => {
|
|
19
24
|
const classes = stylesToClasses({ padding: '10px', margin: '20px' });
|
|
20
|
-
expect(classes).toContain('p-10px');
|
|
21
|
-
expect(classes).toContain('m-20px');
|
|
25
|
+
expect(classes).toContain('p-[10px]');
|
|
26
|
+
expect(classes).toContain('m-[20px]');
|
|
22
27
|
});
|
|
23
28
|
|
|
24
29
|
test('handles percentage values', () => {
|
|
25
30
|
const classes = stylesToClasses({ width: '50%' });
|
|
26
|
-
expect(classes).toContain('w-
|
|
31
|
+
expect(classes).toContain('w-[50%]');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('maps width 100% to w-full', () => {
|
|
35
|
+
const classes = stylesToClasses({ width: '100%' });
|
|
36
|
+
expect(classes).toContain('w-full');
|
|
27
37
|
});
|
|
28
38
|
|
|
29
39
|
test('handles auto values', () => {
|
|
@@ -31,9 +41,9 @@ describe('utilityClassMapper', () => {
|
|
|
31
41
|
expect(classes).toContain('m-auto');
|
|
32
42
|
});
|
|
33
43
|
|
|
34
|
-
test('handles values with spaces', () => {
|
|
44
|
+
test('handles values with spaces (underscore encoding)', () => {
|
|
35
45
|
const classes = stylesToClasses({ padding: '92px 0' });
|
|
36
|
-
expect(classes).toContain('p-
|
|
46
|
+
expect(classes).toContain('p-[92px_0]');
|
|
37
47
|
});
|
|
38
48
|
|
|
39
49
|
test('returns empty array for null', () => {
|
|
@@ -41,60 +51,110 @@ describe('utilityClassMapper', () => {
|
|
|
41
51
|
expect(stylesToClasses(undefined)).toEqual([]);
|
|
42
52
|
});
|
|
43
53
|
|
|
44
|
-
test('handles color variables', () => {
|
|
54
|
+
test('handles color variables (Tailwind v4 var shorthand)', () => {
|
|
45
55
|
const classes = stylesToClasses({ color: 'text' });
|
|
46
|
-
expect(classes).toContain('
|
|
56
|
+
expect(classes).toContain('text-(--text)');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('handles background color tokens', () => {
|
|
60
|
+
const classes = stylesToClasses({ backgroundColor: 'primary' });
|
|
61
|
+
expect(classes).toContain('bg-(--primary)');
|
|
47
62
|
});
|
|
48
63
|
|
|
49
|
-
test('
|
|
64
|
+
test('handles font-size with explicit value', () => {
|
|
65
|
+
const classes = stylesToClasses({ fontSize: '48px' });
|
|
66
|
+
expect(classes).toContain('text-[48px]');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('handles font-size variables with length hint', () => {
|
|
70
|
+
const classes = stylesToClasses({ fontSize: 'var(--font-size-lg)' });
|
|
71
|
+
expect(classes).toContain('text-(length:--font-size-lg)');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('font-weight var carries a number hint (not misread as font-family)', () => {
|
|
75
|
+
// `font-*` is shared by weight/family; without the hint a var binding resolves to
|
|
76
|
+
// font-family (`font-family: 450`), so the weight never applies and the family changes.
|
|
77
|
+
expect(stylesToClasses({ fontWeight: 'var(--h-fw)' })).toContain('font-(number:--h-fw)');
|
|
78
|
+
expect(stylesToClasses({ fontFamily: 'var(--l-ff)' })).toContain('font-(--l-ff)');
|
|
79
|
+
// round-trips back to the right property
|
|
80
|
+
expect(classToStyle('font-(number:--h-fw)')).toEqual({ prop: 'fontWeight', value: 'var(--h-fw)' });
|
|
81
|
+
expect(classToStyle('font-(--l-ff)')).toEqual({ prop: 'fontFamily', value: 'var(--l-ff)' });
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('converts shadow preset to shadow- class', () => {
|
|
50
85
|
const classes = stylesToClasses({ boxShadow: '2' });
|
|
51
|
-
expect(classes).toContain('
|
|
86
|
+
expect(classes).toContain('shadow-2');
|
|
52
87
|
});
|
|
53
88
|
|
|
54
|
-
test('converts gradient preset to
|
|
89
|
+
test('converts gradient preset to bg-gradient- class', () => {
|
|
55
90
|
const classes = stylesToClasses({ background: '1' });
|
|
56
|
-
expect(classes).toContain('
|
|
91
|
+
expect(classes).toContain('bg-gradient-1');
|
|
57
92
|
});
|
|
58
93
|
|
|
59
|
-
test('converts border preset to
|
|
94
|
+
test('converts border preset to border-preset- class', () => {
|
|
60
95
|
const classes = stylesToClasses({ border: '0' });
|
|
61
|
-
expect(classes).toContain('
|
|
96
|
+
expect(classes).toContain('border-preset-0');
|
|
62
97
|
});
|
|
63
98
|
|
|
64
99
|
test('handles aspectRatio with slash value', () => {
|
|
65
100
|
const classes = stylesToClasses({ aspectRatio: '1/1' });
|
|
66
|
-
expect(classes).toContain('
|
|
101
|
+
expect(classes).toContain('aspect-[1/1]');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('handles CSS function values', () => {
|
|
105
|
+
const classes = stylesToClasses({ transform: 'translateY(-50%)' });
|
|
106
|
+
expect(classes).toContain('transform-[translateY(-50%)]');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('handles grid template repeat()', () => {
|
|
110
|
+
const classes = stylesToClasses({ gridTemplateColumns: 'repeat(3, 1fr)' });
|
|
111
|
+
expect(classes).toContain('grid-cols-[repeat(3,_1fr)]');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('handles z-index Tailwind-style bare number', () => {
|
|
115
|
+
const classes = stylesToClasses({ zIndex: 10 });
|
|
116
|
+
expect(classes).toContain('z-10');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('handles opacity on Tailwind 0-100 scale', () => {
|
|
120
|
+
const classes = stylesToClasses({ opacity: 0.5 });
|
|
121
|
+
expect(classes).toContain('opacity-50');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('handles properties without a Tailwind root via arbitrary properties', () => {
|
|
125
|
+
const classes = stylesToClasses({ textOverflow: 'ellipsis' });
|
|
126
|
+
expect(classes).toContain('[text-overflow:ellipsis]');
|
|
67
127
|
});
|
|
68
128
|
|
|
69
129
|
test('align-items stretch maps to a distinct class from flex-start', () => {
|
|
70
|
-
// Regression: stretch
|
|
71
|
-
//
|
|
72
|
-
// — exactly what made Finsweet's mobile CTA buttons line
|
|
73
|
-
// left instead of stretching to full width.
|
|
130
|
+
// Regression: stretch must never share a class with flex-start,
|
|
131
|
+
// otherwise imported `align-items: stretch` silently renders as
|
|
132
|
+
// flex-start — exactly what made Finsweet's mobile CTA buttons line
|
|
133
|
+
// up to the left instead of stretching to full width.
|
|
74
134
|
const stretchClasses = stylesToClasses({ alignItems: 'stretch' });
|
|
75
135
|
const flexStartClasses = stylesToClasses({ alignItems: 'flex-start' });
|
|
76
|
-
expect(stretchClasses).toContain('
|
|
77
|
-
expect(flexStartClasses).toContain('
|
|
78
|
-
expect(stretchClasses).not.toContain('
|
|
79
|
-
expect(classToStyle('
|
|
136
|
+
expect(stretchClasses).toContain('items-stretch');
|
|
137
|
+
expect(flexStartClasses).toContain('items-start');
|
|
138
|
+
expect(stretchClasses).not.toContain('items-start');
|
|
139
|
+
expect(classToStyle('items-stretch')).toEqual({ prop: 'alignItems', value: 'stretch' });
|
|
80
140
|
});
|
|
81
141
|
|
|
82
142
|
test('justify-content space-evenly maps to a distinct class from flex-end', () => {
|
|
83
|
-
// Same bug shape as align-items: `space-evenly`
|
|
84
|
-
//
|
|
143
|
+
// Same bug shape as align-items: `space-evenly` must not alias to
|
|
144
|
+
// flex-end, silently changing layout.
|
|
85
145
|
const evenly = stylesToClasses({ justifyContent: 'space-evenly' });
|
|
86
146
|
const end = stylesToClasses({ justifyContent: 'flex-end' });
|
|
87
|
-
expect(evenly).toContain('
|
|
88
|
-
expect(end).toContain('
|
|
89
|
-
expect(evenly).not.toContain('
|
|
90
|
-
expect(classToStyle('
|
|
147
|
+
expect(evenly).toContain('justify-evenly');
|
|
148
|
+
expect(end).toContain('justify-end');
|
|
149
|
+
expect(evenly).not.toContain('justify-end');
|
|
150
|
+
expect(classToStyle('justify-evenly')).toEqual({ prop: 'justifyContent', value: 'space-evenly' });
|
|
91
151
|
});
|
|
92
152
|
});
|
|
93
153
|
|
|
94
154
|
describe('responsiveStylesToClasses', () => {
|
|
95
155
|
test('handles flat style object', () => {
|
|
96
156
|
const classes = responsiveStylesToClasses({ padding: '10px' });
|
|
97
|
-
expect(classes).toContain('p-10px');
|
|
157
|
+
expect(classes).toContain('p-[10px]');
|
|
98
158
|
});
|
|
99
159
|
|
|
100
160
|
test('handles responsive styles with base', () => {
|
|
@@ -102,17 +162,17 @@ describe('utilityClassMapper', () => {
|
|
|
102
162
|
base: { padding: '10px' },
|
|
103
163
|
tablet: { padding: '20px' },
|
|
104
164
|
});
|
|
105
|
-
expect(classes).toContain('p-10px');
|
|
106
|
-
expect(classes).toContain('
|
|
165
|
+
expect(classes).toContain('p-[10px]');
|
|
166
|
+
expect(classes).toContain('tablet:p-[20px]');
|
|
107
167
|
});
|
|
108
168
|
|
|
109
|
-
test('handles mobile styles with
|
|
169
|
+
test('handles mobile styles with mobile: variant prefix', () => {
|
|
110
170
|
const classes = responsiveStylesToClasses({
|
|
111
171
|
base: { padding: '10px' },
|
|
112
172
|
mobile: { padding: '5px' },
|
|
113
173
|
});
|
|
114
|
-
expect(classes).toContain('p-10px');
|
|
115
|
-
expect(classes).toContain('
|
|
174
|
+
expect(classes).toContain('p-[10px]');
|
|
175
|
+
expect(classes).toContain('mobile:p-[5px]');
|
|
116
176
|
});
|
|
117
177
|
|
|
118
178
|
test('returns empty array for null', () => {
|
|
@@ -130,39 +190,39 @@ describe('utilityClassMapper', () => {
|
|
|
130
190
|
padding: { tablet: 0.75, mobile: 0.5 },
|
|
131
191
|
};
|
|
132
192
|
|
|
133
|
-
test('consumes scalable mobile override into base clamp; no
|
|
193
|
+
test('consumes scalable mobile override into base clamp; no mobile: class emitted', () => {
|
|
134
194
|
clearRegistry();
|
|
135
195
|
const classes = responsiveStylesToClasses(
|
|
136
196
|
{ base: { fontSize: '150px' }, mobile: { fontSize: '94px' } },
|
|
137
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
197
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
138
198
|
);
|
|
139
|
-
// base became
|
|
140
|
-
const
|
|
141
|
-
expect(
|
|
142
|
-
expect(getStyleValue(
|
|
143
|
-
expect(getStyleValue(
|
|
144
|
-
// no
|
|
145
|
-
expect(classes.some((c) => c.startsWith('
|
|
199
|
+
// base became an arbitrary class wrapping clamp(94px, ..., 150px)
|
|
200
|
+
const clamped = classes.find((c) => c.startsWith('text-[clamp('));
|
|
201
|
+
expect(clamped).toBeDefined();
|
|
202
|
+
expect(String(getStyleValue(clamped!))).toMatch(/^clamp\(94px,/);
|
|
203
|
+
expect(String(getStyleValue(clamped!))).toContain(', 150px)');
|
|
204
|
+
// no mobile:text-* emitted
|
|
205
|
+
expect(classes.some((c) => c.startsWith('mobile:text-'))).toBe(false);
|
|
146
206
|
});
|
|
147
207
|
|
|
148
|
-
test('mobile-only non-scalable property (display) stays as
|
|
208
|
+
test('mobile-only non-scalable property (display) stays as mobile: class', () => {
|
|
149
209
|
clearRegistry();
|
|
150
210
|
const classes = responsiveStylesToClasses(
|
|
151
211
|
{
|
|
152
212
|
base: { fontSize: '150px' },
|
|
153
213
|
mobile: { fontSize: '94px', display: 'none' },
|
|
154
214
|
},
|
|
155
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
215
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
156
216
|
);
|
|
157
217
|
// fontSize consumed into base clamp
|
|
158
|
-
const
|
|
159
|
-
expect(
|
|
160
|
-
expect(getStyleValue(
|
|
218
|
+
const clamped = classes.find((c) => c.startsWith('text-[clamp('));
|
|
219
|
+
expect(clamped).toBeDefined();
|
|
220
|
+
expect(String(getStyleValue(clamped!))).toMatch(/^clamp\(94px,/);
|
|
161
221
|
// display:none survives on mobile
|
|
162
|
-
expect(classes).toContain('
|
|
222
|
+
expect(classes).toContain('mobile:hidden');
|
|
163
223
|
});
|
|
164
224
|
|
|
165
|
-
test('tablet override stays as
|
|
225
|
+
test('tablet override stays as tablet: class (unchanged behavior)', () => {
|
|
166
226
|
clearRegistry();
|
|
167
227
|
const classes = responsiveStylesToClasses(
|
|
168
228
|
{
|
|
@@ -170,71 +230,71 @@ describe('utilityClassMapper', () => {
|
|
|
170
230
|
tablet: { fontSize: '120px' },
|
|
171
231
|
mobile: { fontSize: '94px' },
|
|
172
232
|
},
|
|
173
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
233
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
174
234
|
);
|
|
175
|
-
expect(classes).toContain('
|
|
235
|
+
expect(classes).toContain('tablet:text-[120px]');
|
|
176
236
|
// mobile consumed
|
|
177
|
-
expect(classes.some((c) => c.startsWith('
|
|
237
|
+
expect(classes.some((c) => c.startsWith('mobile:text-'))).toBe(false);
|
|
178
238
|
});
|
|
179
239
|
|
|
180
240
|
test('no mobile override → base passes through unchanged (no consumption)', () => {
|
|
181
241
|
clearRegistry();
|
|
182
242
|
const classes = responsiveStylesToClasses(
|
|
183
243
|
{ base: { fontSize: '150px' } },
|
|
184
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
244
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
185
245
|
);
|
|
186
|
-
expect(classes).toContain('
|
|
187
|
-
expect(classes.some((c) =>
|
|
246
|
+
expect(classes).toContain('text-[150px]');
|
|
247
|
+
expect(classes.some((c) => c.startsWith('text-[clamp('))).toBe(false);
|
|
188
248
|
});
|
|
189
249
|
|
|
190
|
-
test('mismatched units (rem vs px) → falls back,
|
|
250
|
+
test('mismatched units (rem vs px) → falls back, mobile: class still emitted', () => {
|
|
191
251
|
clearRegistry();
|
|
192
252
|
const classes = responsiveStylesToClasses(
|
|
193
253
|
{ base: { fontSize: '10rem' }, mobile: { fontSize: '94px' } },
|
|
194
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
254
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
195
255
|
);
|
|
196
|
-
expect(classes).toContain('
|
|
197
|
-
expect(classes).toContain('
|
|
256
|
+
expect(classes).toContain('text-[10rem]');
|
|
257
|
+
expect(classes).toContain('mobile:text-[94px]');
|
|
198
258
|
});
|
|
199
259
|
|
|
200
260
|
test('non-scalable mobile override (display) is not consumed', () => {
|
|
201
261
|
clearRegistry();
|
|
202
262
|
const classes = responsiveStylesToClasses(
|
|
203
263
|
{ base: { display: 'flex' }, mobile: { display: 'block' } },
|
|
204
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
264
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
205
265
|
);
|
|
206
|
-
expect(classes).toContain('
|
|
207
|
-
expect(classes).toContain('
|
|
266
|
+
expect(classes).toContain('flex');
|
|
267
|
+
expect(classes).toContain('mobile:block');
|
|
208
268
|
});
|
|
209
269
|
|
|
210
|
-
test('fluidActive off → no consumption,
|
|
270
|
+
test('fluidActive off → no consumption, mobile: class emitted', () => {
|
|
211
271
|
clearRegistry();
|
|
212
272
|
const classes = responsiveStylesToClasses(
|
|
213
273
|
{ base: { fontSize: '150px' }, mobile: { fontSize: '94px' } },
|
|
214
|
-
{ fluidActive: false, responsiveScales: fluidScales }
|
|
274
|
+
{ fluidActive: false, responsiveScales: fluidScales },
|
|
215
275
|
);
|
|
216
|
-
expect(classes).toContain('
|
|
217
|
-
expect(classes).toContain('
|
|
276
|
+
expect(classes).toContain('text-[150px]');
|
|
277
|
+
expect(classes).toContain('mobile:text-[94px]');
|
|
218
278
|
});
|
|
219
279
|
|
|
220
280
|
test('fluidActive on but responsiveScales disabled → no consumption', () => {
|
|
221
281
|
clearRegistry();
|
|
222
282
|
const classes = responsiveStylesToClasses(
|
|
223
283
|
{ base: { fontSize: '150px' }, mobile: { fontSize: '94px' } },
|
|
224
|
-
{ fluidActive: true, responsiveScales: { ...fluidScales, enabled: false } }
|
|
284
|
+
{ fluidActive: true, responsiveScales: { ...fluidScales, enabled: false } },
|
|
225
285
|
);
|
|
226
|
-
expect(classes).toContain('
|
|
227
|
-
expect(classes).toContain('
|
|
286
|
+
expect(classes).toContain('text-[150px]');
|
|
287
|
+
expect(classes).toContain('mobile:text-[94px]');
|
|
228
288
|
});
|
|
229
289
|
|
|
230
290
|
test('clamp math: MIN=94px, MAX=150px, fluidRange 320–1700', () => {
|
|
231
291
|
clearRegistry();
|
|
232
292
|
const classes = responsiveStylesToClasses(
|
|
233
293
|
{ base: { fontSize: '150px' }, mobile: { fontSize: '94px' } },
|
|
234
|
-
{ fluidActive: true, responsiveScales: fluidScales }
|
|
294
|
+
{ fluidActive: true, responsiveScales: fluidScales },
|
|
235
295
|
);
|
|
236
|
-
const
|
|
237
|
-
const value = String(getStyleValue(
|
|
296
|
+
const clamped = classes.find((c) => c.startsWith('text-[clamp('))!;
|
|
297
|
+
const value = String(getStyleValue(clamped));
|
|
238
298
|
// slope = (150-94)/(1700-320) = 56/1380 ≈ 0.04058 px/px → slopeVw ≈ 4.058vw
|
|
239
299
|
// intercept = 94 - 0.04058*320 = 94 - 12.9855 ≈ 81.0145px
|
|
240
300
|
expect(value).toMatch(/clamp\(94px,\s*81\.0145px\s*\+\s*4\.058vw,\s*150px\)/);
|
|
@@ -244,22 +304,27 @@ describe('utilityClassMapper', () => {
|
|
|
244
304
|
|
|
245
305
|
describe('classToStyle', () => {
|
|
246
306
|
test('parses padding class', () => {
|
|
247
|
-
const style = classToStyle('p-10px');
|
|
307
|
+
const style = classToStyle('p-[10px]');
|
|
248
308
|
expect(style).toEqual({ prop: 'padding', value: '10px' });
|
|
249
309
|
});
|
|
250
310
|
|
|
251
|
-
test('parses
|
|
252
|
-
const style = classToStyle('
|
|
311
|
+
test('parses static flex utility', () => {
|
|
312
|
+
const style = classToStyle('flex');
|
|
253
313
|
expect(style).toEqual({ prop: 'display', value: 'flex' });
|
|
254
314
|
});
|
|
255
315
|
|
|
256
|
-
test('
|
|
257
|
-
const style = classToStyle('
|
|
316
|
+
test('parses hidden utility', () => {
|
|
317
|
+
const style = classToStyle('hidden');
|
|
318
|
+
expect(style).toEqual({ prop: 'display', value: 'none' });
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('handles tablet variant prefix', () => {
|
|
322
|
+
const style = classToStyle('tablet:p-[20px]');
|
|
258
323
|
expect(style).toEqual({ prop: 'padding', value: '20px' });
|
|
259
324
|
});
|
|
260
325
|
|
|
261
|
-
test('handles mobile prefix', () => {
|
|
262
|
-
const style = classToStyle('
|
|
326
|
+
test('handles mobile variant prefix', () => {
|
|
327
|
+
const style = classToStyle('mobile:p-[5px]');
|
|
263
328
|
expect(style).toEqual({ prop: 'padding', value: '5px' });
|
|
264
329
|
});
|
|
265
330
|
|
|
@@ -268,32 +333,69 @@ describe('utilityClassMapper', () => {
|
|
|
268
333
|
expect(classToStyle('unknown-class')).toBeNull();
|
|
269
334
|
});
|
|
270
335
|
|
|
336
|
+
test('decodes underscores back to spaces', () => {
|
|
337
|
+
const style = classToStyle('p-[92px_0]');
|
|
338
|
+
expect(style).toEqual({ prop: 'padding', value: '92px 0' });
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test('decodes color variables to bare tokens', () => {
|
|
342
|
+
const style = classToStyle('bg-(--primary)');
|
|
343
|
+
expect(style).toEqual({ prop: 'backgroundColor', value: 'primary' });
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test('decodes non-color variables to var() values', () => {
|
|
347
|
+
const style = classToStyle('w-(--site-width)');
|
|
348
|
+
expect(style).toEqual({ prop: 'width', value: 'var(--site-width)' });
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test('disambiguates text- by value: font-size vs color', () => {
|
|
352
|
+
expect(classToStyle('text-[14px]')).toEqual({ prop: 'fontSize', value: '14px' });
|
|
353
|
+
expect(classToStyle('text-[#fff]')).toEqual({ prop: 'color', value: '#fff' });
|
|
354
|
+
expect(classToStyle('text-(length:--font-size-lg)')).toEqual({
|
|
355
|
+
prop: 'fontSize',
|
|
356
|
+
value: 'var(--font-size-lg)',
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test('decodes keyword utilities', () => {
|
|
361
|
+
expect(classToStyle('w-full')).toEqual({ prop: 'width', value: '100%' });
|
|
362
|
+
expect(classToStyle('h-screen')).toEqual({ prop: 'height', value: '100vh' });
|
|
363
|
+
expect(classToStyle('rounded-full')).toEqual({ prop: 'borderRadius', value: '9999px' });
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
test('decodes arbitrary-property classes', () => {
|
|
367
|
+
expect(classToStyle('[text-overflow:ellipsis]')).toEqual({ prop: 'textOverflow', value: 'ellipsis' });
|
|
368
|
+
});
|
|
369
|
+
|
|
271
370
|
test('parses shadow preset class', () => {
|
|
272
|
-
const style = classToStyle('
|
|
371
|
+
const style = classToStyle('shadow-2');
|
|
273
372
|
expect(style).toEqual({ prop: 'boxShadow', value: '0 4px 12px rgba(0, 0, 0, 0.1)' });
|
|
274
373
|
});
|
|
275
374
|
|
|
276
375
|
test('parses gradient preset class', () => {
|
|
277
|
-
const style = classToStyle('
|
|
278
|
-
expect(style).toEqual({
|
|
376
|
+
const style = classToStyle('bg-gradient-1');
|
|
377
|
+
expect(style).toEqual({
|
|
378
|
+
prop: 'background',
|
|
379
|
+
value: 'linear-gradient(90deg, rgba(10,22,40,0.85) 0%, rgba(10,22,40,0.2) 100%)',
|
|
380
|
+
});
|
|
279
381
|
});
|
|
280
382
|
|
|
281
383
|
test('parses border preset class', () => {
|
|
282
|
-
const style = classToStyle('
|
|
384
|
+
const style = classToStyle('border-preset-0');
|
|
283
385
|
expect(style).toEqual({ prop: 'border', value: '1px solid var(--border)' });
|
|
284
386
|
});
|
|
285
387
|
});
|
|
286
388
|
|
|
287
389
|
describe('classesToStyles', () => {
|
|
288
390
|
test('converts base classes to style object', () => {
|
|
289
|
-
const styles = classesToStyles(['p-10px', 'm-20px']);
|
|
391
|
+
const styles = classesToStyles(['p-[10px]', 'm-[20px]']);
|
|
290
392
|
expect(styles).toEqual({
|
|
291
393
|
base: { padding: '10px', margin: '20px' },
|
|
292
394
|
});
|
|
293
395
|
});
|
|
294
396
|
|
|
295
397
|
test('handles responsive classes', () => {
|
|
296
|
-
const styles = classesToStyles(['p-10px', '
|
|
398
|
+
const styles = classesToStyles(['p-[10px]', 'tablet:p-[20px]']);
|
|
297
399
|
expect(styles).toEqual({
|
|
298
400
|
base: { padding: '10px' },
|
|
299
401
|
tablet: { padding: '20px' },
|
|
@@ -301,7 +403,7 @@ describe('utilityClassMapper', () => {
|
|
|
301
403
|
});
|
|
302
404
|
|
|
303
405
|
test('handles mobile classes', () => {
|
|
304
|
-
const styles = classesToStyles(['p-10px', '
|
|
406
|
+
const styles = classesToStyles(['p-[10px]', 'mobile:p-[5px]']);
|
|
305
407
|
expect(styles).toEqual({
|
|
306
408
|
base: { padding: '10px' },
|
|
307
409
|
mobile: { padding: '5px' },
|
|
@@ -313,10 +415,19 @@ describe('utilityClassMapper', () => {
|
|
|
313
415
|
});
|
|
314
416
|
|
|
315
417
|
test('removes empty breakpoints', () => {
|
|
316
|
-
const styles = classesToStyles(['p-10px']);
|
|
418
|
+
const styles = classesToStyles(['p-[10px]']);
|
|
317
419
|
expect(styles).toEqual({ base: { padding: '10px' } });
|
|
318
420
|
expect(styles?.tablet).toBeUndefined();
|
|
319
421
|
expect(styles?.mobile).toBeUndefined();
|
|
320
422
|
});
|
|
423
|
+
|
|
424
|
+
test('round-trips styles → classes → styles', () => {
|
|
425
|
+
const original = {
|
|
426
|
+
base: { padding: '92px 0', display: 'flex', color: 'primary', width: '100%' },
|
|
427
|
+
mobile: { padding: '12px 0' },
|
|
428
|
+
};
|
|
429
|
+
const classes = responsiveStylesToClasses(original);
|
|
430
|
+
expect(classesToStyles(classes)).toEqual(original);
|
|
431
|
+
});
|
|
321
432
|
});
|
|
322
433
|
});
|