@qwickapps/react-framework 1.4.1 → 1.4.2
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/QUICK_START_GUIDE.md +82 -0
- package/README.md +221 -21
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +1 -2
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/SafeSpan.d.ts +1 -2
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/base/Container.d.ts +32 -0
- package/dist/components/base/Container.d.ts.map +1 -0
- package/dist/components/base/ContainerView.d.ts +65 -0
- package/dist/components/base/ContainerView.d.ts.map +1 -0
- package/dist/components/base/ModelView.d.ts +37 -46
- package/dist/components/base/ModelView.d.ts.map +1 -1
- package/dist/components/base/index.d.ts +3 -2
- package/dist/components/base/index.d.ts.map +1 -1
- package/dist/components/blocks/Article.d.ts +1 -2
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/Code-factory.d.ts +22 -0
- package/dist/components/blocks/Code-factory.d.ts.map +1 -0
- package/dist/components/blocks/Code-old.d.ts +31 -0
- package/dist/components/blocks/Code-old.d.ts.map +1 -0
- package/dist/components/blocks/Code.d.ts +30 -18
- package/dist/components/blocks/Code.d.ts.map +1 -1
- package/dist/components/blocks/HeroBlock.d.ts +1 -2
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts +1 -2
- package/dist/components/blocks/Image.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts +1 -2
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +35 -27
- package/dist/components/blocks/Text.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts +1 -2
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts +1 -2
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts +1 -2
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/input/SelectInputField.d.ts +1 -2
- package/dist/components/input/SelectInputField.d.ts.map +1 -1
- package/dist/components/pages/Page.d.ts +29 -47
- package/dist/components/pages/Page.d.ts.map +1 -1
- package/dist/components/pages/index.d.ts +2 -3
- package/dist/components/pages/index.d.ts.map +1 -1
- package/dist/components/shared/createSerializableView.d.ts +68 -0
- package/dist/components/shared/createSerializableView.d.ts.map +1 -0
- package/dist/components/shared/viewProps.d.ts +37 -0
- package/dist/components/shared/viewProps.d.ts.map +1 -0
- package/dist/index.esm.js +21782 -22580
- package/dist/index.js +21782 -22579
- package/dist/qa/ConsoleWarningTest.d.ts +5 -0
- package/dist/qa/ConsoleWarningTest.d.ts.map +1 -0
- package/dist/qa/StorageKeyTest.d.ts +6 -0
- package/dist/qa/StorageKeyTest.d.ts.map +1 -0
- package/dist/qa/ThemeStorageKeyTest.d.ts +6 -0
- package/dist/qa/ThemeStorageKeyTest.d.ts.map +1 -0
- package/dist/schemas/CodeSchema.d.ts +2 -2
- package/dist/schemas/CodeSchema.d.ts.map +1 -1
- package/dist/schemas/ContainerSchema.d.ts +12 -0
- package/dist/schemas/ContainerSchema.d.ts.map +1 -0
- package/dist/schemas/PageTemplateSchema.d.ts +3 -3
- package/dist/schemas/PageTemplateSchema.d.ts.map +1 -1
- package/dist/schemas/ViewModelSchema.d.ts +46 -6
- package/dist/schemas/ViewModelSchema.d.ts.map +1 -1
- package/dist/schemas/ViewSchema.d.ts +65 -0
- package/dist/schemas/ViewSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/transformers/ComponentTransformer.d.ts +27 -15
- package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -1
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -1
- package/dist/schemas/transformers/registry.d.ts +3 -0
- package/dist/schemas/transformers/registry.d.ts.map +1 -1
- package/dist/src/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
- package/dist/src/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
- package/dist/src/components/AccessibilityChecker.d.ts +12 -0
- package/dist/src/components/AccessibilityChecker.d.ts.map +1 -0
- package/dist/src/components/AccessibilityProvider.d.ts +64 -0
- package/dist/src/components/AccessibilityProvider.d.ts.map +1 -0
- package/dist/src/components/Breadcrumbs.d.ts +39 -0
- package/dist/src/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/src/components/ErrorBoundary.d.ts +46 -0
- package/dist/src/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/src/components/Html.d.ts +58 -0
- package/dist/src/components/Html.d.ts.map +1 -0
- package/dist/src/components/Logo.d.ts +56 -0
- package/dist/src/components/Logo.d.ts.map +1 -0
- package/dist/src/components/Markdown.d.ts +51 -0
- package/dist/src/components/Markdown.d.ts.map +1 -0
- package/dist/src/components/QwickApp.d.ts +69 -0
- package/dist/src/components/QwickApp.d.ts.map +1 -0
- package/dist/src/components/QwickAppsLogo.d.ts +25 -0
- package/dist/src/components/QwickAppsLogo.d.ts.map +1 -0
- package/dist/src/components/QwickIcon.d.ts +23 -0
- package/dist/src/components/QwickIcon.d.ts.map +1 -0
- package/dist/src/components/ResponsiveMenu.d.ts +38 -0
- package/dist/src/components/ResponsiveMenu.d.ts.map +1 -0
- package/dist/src/components/SafeSpan.d.ts +29 -0
- package/dist/src/components/SafeSpan.d.ts.map +1 -0
- package/dist/src/components/Scaffold.d.ts +57 -0
- package/dist/src/components/Scaffold.d.ts.map +1 -0
- package/dist/src/components/base/Container.d.ts +33 -0
- package/dist/src/components/base/Container.d.ts.map +1 -0
- package/dist/src/components/base/ModelView.d.ts +92 -0
- package/dist/src/components/base/ModelView.d.ts.map +1 -0
- package/dist/src/components/base/index.d.ts +12 -0
- package/dist/src/components/base/index.d.ts.map +1 -0
- package/dist/src/components/blocks/Article.d.ts +32 -0
- package/dist/src/components/blocks/Article.d.ts.map +1 -0
- package/dist/src/components/blocks/CardListGrid.d.ts +23 -0
- package/dist/src/components/blocks/CardListGrid.d.ts.map +1 -0
- package/dist/src/components/blocks/Code.d.ts +37 -0
- package/dist/src/components/blocks/Code.d.ts.map +1 -0
- package/dist/src/components/blocks/Content.d.ts +24 -0
- package/dist/src/components/blocks/Content.d.ts.map +1 -0
- package/dist/src/components/blocks/CoverImageHeader.d.ts +44 -0
- package/dist/src/components/blocks/CoverImageHeader.d.ts.map +1 -0
- package/dist/src/components/blocks/FeatureCard.d.ts +66 -0
- package/dist/src/components/blocks/FeatureCard.d.ts.map +1 -0
- package/dist/src/components/blocks/FeatureGrid.d.ts +48 -0
- package/dist/src/components/blocks/FeatureGrid.d.ts.map +1 -0
- package/dist/src/components/blocks/Footer.d.ts +56 -0
- package/dist/src/components/blocks/Footer.d.ts.map +1 -0
- package/dist/src/components/blocks/HeroBlock.d.ts +55 -0
- package/dist/src/components/blocks/HeroBlock.d.ts.map +1 -0
- package/dist/src/components/blocks/Image.d.ts +40 -0
- package/dist/src/components/blocks/Image.d.ts.map +1 -0
- package/dist/src/components/blocks/PageBannerHeader.d.ts +30 -0
- package/dist/src/components/blocks/PageBannerHeader.d.ts.map +1 -0
- package/dist/src/components/blocks/ProductCard.d.ts +57 -0
- package/dist/src/components/blocks/ProductCard.d.ts.map +1 -0
- package/dist/src/components/blocks/Section.d.ts +45 -0
- package/dist/src/components/blocks/Section.d.ts.map +1 -0
- package/dist/src/components/blocks/Text.d.ts +34 -0
- package/dist/src/components/blocks/Text.d.ts.map +1 -0
- package/dist/src/components/blocks/index.d.ts +41 -0
- package/dist/src/components/blocks/index.d.ts.map +1 -0
- package/dist/src/components/buttons/Button.d.ts +41 -0
- package/dist/src/components/buttons/Button.d.ts.map +1 -0
- package/dist/src/components/buttons/PaletteSwitcher.d.ts +24 -0
- package/dist/src/components/buttons/PaletteSwitcher.d.ts.map +1 -0
- package/dist/src/components/buttons/ThemeSwitcher.d.ts +24 -0
- package/dist/src/components/buttons/ThemeSwitcher.d.ts.map +1 -0
- package/dist/src/components/buttons/index.d.ts +11 -0
- package/dist/src/components/buttons/index.d.ts.map +1 -0
- package/dist/src/components/forms/FormBlock.d.ts +51 -0
- package/dist/src/components/forms/FormBlock.d.ts.map +1 -0
- package/dist/src/components/forms/index.d.ts +8 -0
- package/dist/src/components/forms/index.d.ts.map +1 -0
- package/dist/src/components/index.d.ts +41 -0
- package/dist/src/components/index.d.ts.map +1 -0
- package/dist/src/components/input/ChoiceInputField.d.ts +29 -0
- package/dist/src/components/input/ChoiceInputField.d.ts.map +1 -0
- package/dist/src/components/input/HtmlInputField.d.ts +33 -0
- package/dist/src/components/input/HtmlInputField.d.ts.map +1 -0
- package/dist/src/components/input/SelectInputField.d.ts +31 -0
- package/dist/src/components/input/SelectInputField.d.ts.map +1 -0
- package/dist/src/components/input/SwitchInputField.d.ts +27 -0
- package/dist/src/components/input/SwitchInputField.d.ts.map +1 -0
- package/dist/src/components/input/TextField.d.ts +18 -0
- package/dist/src/components/input/TextField.d.ts.map +1 -0
- package/dist/src/components/input/TextInputField.d.ts +34 -0
- package/dist/src/components/input/TextInputField.d.ts.map +1 -0
- package/dist/src/components/input/index.d.ts +19 -0
- package/dist/src/components/input/index.d.ts.map +1 -0
- package/dist/src/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
- package/dist/src/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
- package/dist/src/components/layout/CollapsibleLayout/index.d.ts +9 -0
- package/dist/src/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
- package/dist/src/components/layout/GridCell.d.ts +32 -0
- package/dist/src/components/layout/GridCell.d.ts.map +1 -0
- package/dist/src/components/layout/GridCellWrapper.d.ts +46 -0
- package/dist/src/components/layout/GridCellWrapper.d.ts.map +1 -0
- package/dist/src/components/layout/GridLayout.d.ts +50 -0
- package/dist/src/components/layout/GridLayout.d.ts.map +1 -0
- package/dist/src/components/layout/index.d.ts +14 -0
- package/dist/src/components/layout/index.d.ts.map +1 -0
- package/dist/src/components/menu/Menu.d.ts +1 -0
- package/dist/src/components/menu/Menu.d.ts.map +1 -0
- package/dist/src/components/menu/MenuItem.d.ts +31 -0
- package/dist/src/components/menu/MenuItem.d.ts.map +1 -0
- package/dist/src/components/menu/index.d.ts +7 -0
- package/dist/src/components/menu/index.d.ts.map +1 -0
- package/dist/src/components/pages/FormPage.d.ts +66 -0
- package/dist/src/components/pages/FormPage.d.ts.map +1 -0
- package/dist/src/components/pages/Page.d.ts +68 -0
- package/dist/src/components/pages/Page.d.ts.map +1 -0
- package/dist/src/components/pages/index.d.ts +10 -0
- package/dist/src/components/pages/index.d.ts.map +1 -0
- package/dist/src/components/shared/createSerializableView.d.ts +81 -0
- package/dist/src/components/shared/createSerializableView.d.ts.map +1 -0
- package/dist/src/components/shared/viewProps.d.ts +37 -0
- package/dist/src/components/shared/viewProps.d.ts.map +1 -0
- package/dist/src/config/AppConfig.d.ts +49 -0
- package/dist/src/config/AppConfig.d.ts.map +1 -0
- package/dist/src/config/AppConfigBuilder.d.ts +75 -0
- package/dist/src/config/AppConfigBuilder.d.ts.map +1 -0
- package/dist/src/config/index.d.ts +13 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/types.d.ts +130 -0
- package/dist/src/config/types.d.ts.map +1 -0
- package/dist/src/config.d.ts +15 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/contexts/DataContext.d.ts +139 -0
- package/dist/src/contexts/DataContext.d.ts.map +1 -0
- package/dist/src/contexts/DimensionsContext.d.ts +42 -0
- package/dist/src/contexts/DimensionsContext.d.ts.map +1 -0
- package/dist/src/contexts/PaletteContext.d.ts +53 -0
- package/dist/src/contexts/PaletteContext.d.ts.map +1 -0
- package/dist/src/contexts/PrintModeContext.d.ts +27 -0
- package/dist/src/contexts/PrintModeContext.d.ts.map +1 -0
- package/dist/src/contexts/QwickAppContext.d.ts +71 -0
- package/dist/src/contexts/QwickAppContext.d.ts.map +1 -0
- package/dist/src/contexts/ThemeContext.d.ts +65 -0
- package/dist/src/contexts/ThemeContext.d.ts.map +1 -0
- package/dist/src/contexts/index.d.ts +11 -0
- package/dist/src/contexts/index.d.ts.map +1 -0
- package/dist/src/hooks/index.d.ts +12 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/useBaseProps.d.ts +101 -0
- package/dist/src/hooks/useBaseProps.d.ts.map +1 -0
- package/dist/src/hooks/useDataBinding.d.ts +22 -0
- package/dist/src/hooks/useDataBinding.d.ts.map +1 -0
- package/dist/src/hooks/usePrintMode.d.ts +39 -0
- package/dist/src/hooks/usePrintMode.d.ts.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/palettes/PaletteAutumn.d.ts +10 -0
- package/dist/src/palettes/PaletteAutumn.d.ts.map +1 -0
- package/dist/src/palettes/PaletteCosmic.d.ts +10 -0
- package/dist/src/palettes/PaletteCosmic.d.ts.map +1 -0
- package/dist/src/palettes/PaletteDefault.d.ts +10 -0
- package/dist/src/palettes/PaletteDefault.d.ts.map +1 -0
- package/dist/src/palettes/PaletteOcean.d.ts +10 -0
- package/dist/src/palettes/PaletteOcean.d.ts.map +1 -0
- package/dist/src/palettes/PaletteSpring.d.ts +10 -0
- package/dist/src/palettes/PaletteSpring.d.ts.map +1 -0
- package/dist/src/palettes/PaletteWinter.d.ts +10 -0
- package/dist/src/palettes/PaletteWinter.d.ts.map +1 -0
- package/dist/src/palettes/index.d.ts +13 -0
- package/dist/src/palettes/index.d.ts.map +1 -0
- package/dist/src/schemas/ActionSchema.d.ts +21 -0
- package/dist/src/schemas/ActionSchema.d.ts.map +1 -0
- package/dist/src/schemas/ArticleSchema.d.ts +13 -0
- package/dist/src/schemas/ArticleSchema.d.ts.map +1 -0
- package/dist/src/schemas/ButtonSchema.d.ts +19 -0
- package/dist/src/schemas/ButtonSchema.d.ts.map +1 -0
- package/dist/src/schemas/CardListGridSchema.d.ts +17 -0
- package/dist/src/schemas/CardListGridSchema.d.ts.map +1 -0
- package/dist/src/schemas/ChoiceInputFieldSchema.d.ts +18 -0
- package/dist/src/schemas/ChoiceInputFieldSchema.d.ts.map +1 -0
- package/dist/src/schemas/CodeSchema.d.ts +18 -0
- package/dist/src/schemas/CodeSchema.d.ts.map +1 -0
- package/dist/src/schemas/CollapsibleLayoutSchema.d.ts +32 -0
- package/dist/src/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
- package/dist/src/schemas/ContainerSchema.d.ts +12 -0
- package/dist/src/schemas/ContainerSchema.d.ts.map +1 -0
- package/dist/src/schemas/ContentSchema.d.ts +21 -0
- package/dist/src/schemas/ContentSchema.d.ts.map +1 -0
- package/dist/src/schemas/CoverImageHeaderSchema.d.ts +28 -0
- package/dist/src/schemas/CoverImageHeaderSchema.d.ts.map +1 -0
- package/dist/src/schemas/FeatureCardSchema.d.ts +28 -0
- package/dist/src/schemas/FeatureCardSchema.d.ts.map +1 -0
- package/dist/src/schemas/FeatureGridSchema.d.ts +17 -0
- package/dist/src/schemas/FeatureGridSchema.d.ts.map +1 -0
- package/dist/src/schemas/FeatureItemSchema.d.ts +16 -0
- package/dist/src/schemas/FeatureItemSchema.d.ts.map +1 -0
- package/dist/src/schemas/FooterItemSchema.d.ts +15 -0
- package/dist/src/schemas/FooterItemSchema.d.ts.map +1 -0
- package/dist/src/schemas/FooterSchema.d.ts +20 -0
- package/dist/src/schemas/FooterSchema.d.ts.map +1 -0
- package/dist/src/schemas/FooterSectionSchema.d.ts +15 -0
- package/dist/src/schemas/FooterSectionSchema.d.ts.map +1 -0
- package/dist/src/schemas/FormBlockSchema.d.ts +19 -0
- package/dist/src/schemas/FormBlockSchema.d.ts.map +1 -0
- package/dist/src/schemas/GridCellSchema.d.ts +23 -0
- package/dist/src/schemas/GridCellSchema.d.ts.map +1 -0
- package/dist/src/schemas/GridLayoutSchema.d.ts +21 -0
- package/dist/src/schemas/GridLayoutSchema.d.ts.map +1 -0
- package/dist/src/schemas/HeaderActionSchema.d.ts +17 -0
- package/dist/src/schemas/HeaderActionSchema.d.ts.map +1 -0
- package/dist/src/schemas/HeroBlockSchema.d.ts +22 -0
- package/dist/src/schemas/HeroBlockSchema.d.ts.map +1 -0
- package/dist/src/schemas/HtmlInputFieldSchema.d.ts +18 -0
- package/dist/src/schemas/HtmlInputFieldSchema.d.ts.map +1 -0
- package/dist/src/schemas/HtmlSchema.d.ts +14 -0
- package/dist/src/schemas/HtmlSchema.d.ts.map +1 -0
- package/dist/src/schemas/ImageSchema.d.ts +32 -0
- package/dist/src/schemas/ImageSchema.d.ts.map +1 -0
- package/dist/src/schemas/LogoSchema.d.ts +35 -0
- package/dist/src/schemas/LogoSchema.d.ts.map +1 -0
- package/dist/src/schemas/MarkdownSchema.d.ts +14 -0
- package/dist/src/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/src/schemas/MetadataItemSchema.d.ts +13 -0
- package/dist/src/schemas/MetadataItemSchema.d.ts.map +1 -0
- package/dist/src/schemas/PageBannerHeaderSchema.d.ts +28 -0
- package/dist/src/schemas/PageBannerHeaderSchema.d.ts.map +1 -0
- package/dist/src/schemas/PageTemplateSchema.d.ts +31 -0
- package/dist/src/schemas/PageTemplateSchema.d.ts.map +1 -0
- package/dist/src/schemas/PaletteSwitcherSchema.d.ts +16 -0
- package/dist/src/schemas/PaletteSwitcherSchema.d.ts.map +1 -0
- package/dist/src/schemas/PrintConfigSchema.d.ts +31 -0
- package/dist/src/schemas/PrintConfigSchema.d.ts.map +1 -0
- package/dist/src/schemas/ProductCardSchema.d.ts +39 -0
- package/dist/src/schemas/ProductCardSchema.d.ts.map +1 -0
- package/dist/src/schemas/SafeSpanSchema.d.ts +13 -0
- package/dist/src/schemas/SafeSpanSchema.d.ts.map +1 -0
- package/dist/src/schemas/SectionSchema.d.ts +16 -0
- package/dist/src/schemas/SectionSchema.d.ts.map +1 -0
- package/dist/src/schemas/SelectInputFieldSchema.d.ts +27 -0
- package/dist/src/schemas/SelectInputFieldSchema.d.ts.map +1 -0
- package/dist/src/schemas/SwitchInputFieldSchema.d.ts +18 -0
- package/dist/src/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
- package/dist/src/schemas/TextInputFieldSchema.d.ts +22 -0
- package/dist/src/schemas/TextInputFieldSchema.d.ts.map +1 -0
- package/dist/src/schemas/TextSchema.d.ts +37 -0
- package/dist/src/schemas/TextSchema.d.ts.map +1 -0
- package/dist/src/schemas/ThemeSwitcherSchema.d.ts +19 -0
- package/dist/src/schemas/ThemeSwitcherSchema.d.ts.map +1 -0
- package/dist/src/schemas/ViewSchema.d.ts +66 -0
- package/dist/src/schemas/ViewSchema.d.ts.map +1 -0
- package/dist/src/schemas/index.d.ts +47 -0
- package/dist/src/schemas/index.d.ts.map +1 -0
- package/dist/src/schemas/transformers/ComponentTransformer.d.ts +128 -0
- package/dist/src/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
- package/dist/src/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
- package/dist/src/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
- package/dist/src/schemas/transformers/registry.d.ts +18 -0
- package/dist/src/schemas/transformers/registry.d.ts.map +1 -0
- package/dist/src/schemas/types/Serializable.d.ts +46 -0
- package/dist/src/schemas/types/Serializable.d.ts.map +1 -0
- package/dist/src/stories/_templates/SerializationTemplate.d.ts +44 -0
- package/dist/src/stories/_templates/SerializationTemplate.d.ts.map +1 -0
- package/dist/src/templates/TemplateResolver.d.ts +52 -0
- package/dist/src/templates/TemplateResolver.d.ts.map +1 -0
- package/dist/src/templates/index.d.ts +7 -0
- package/dist/src/templates/index.d.ts.map +1 -0
- package/dist/src/types/CacheProvider.d.ts +18 -0
- package/dist/src/types/CacheProvider.d.ts.map +1 -0
- package/dist/src/types/CollapsibleLayout.d.ts +142 -0
- package/dist/src/types/CollapsibleLayout.d.ts.map +1 -0
- package/dist/src/types/ContentProxy.d.ts +47 -0
- package/dist/src/types/ContentProxy.d.ts.map +1 -0
- package/dist/src/types/DataTypes.d.ts +185 -0
- package/dist/src/types/DataTypes.d.ts.map +1 -0
- package/dist/src/types/TemplateProvider.d.ts +10 -0
- package/dist/src/types/TemplateProvider.d.ts.map +1 -0
- package/dist/src/types/TemplateResolver.d.ts +23 -0
- package/dist/src/types/TemplateResolver.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +82 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/utils/breakpoints.d.ts +35 -0
- package/dist/src/utils/breakpoints.d.ts.map +1 -0
- package/dist/src/utils/cssUtils.d.ts +17 -0
- package/dist/src/utils/cssUtils.d.ts.map +1 -0
- package/dist/src/utils/customPaletteManager.d.ts +8 -0
- package/dist/src/utils/customPaletteManager.d.ts.map +1 -0
- package/dist/src/utils/dimensions.d.ts +34 -0
- package/dist/src/utils/dimensions.d.ts.map +1 -0
- package/dist/src/utils/htmlTransform.d.ts +44 -0
- package/dist/src/utils/htmlTransform.d.ts.map +1 -0
- package/dist/src/utils/index.d.ts +16 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/logger.d.ts +26 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/paletteUtils.d.ts +38 -0
- package/dist/src/utils/paletteUtils.d.ts.map +1 -0
- package/dist/src/utils/persistenceUtils.d.ts +31 -0
- package/dist/src/utils/persistenceUtils.d.ts.map +1 -0
- package/dist/src/utils/reactUtils.d.ts +33 -0
- package/dist/src/utils/reactUtils.d.ts.map +1 -0
- package/dist/src/utils/spacing.d.ts +34 -0
- package/dist/src/utils/spacing.d.ts.map +1 -0
- package/dist/src/utils/themePerformanceMonitor.d.ts +32 -0
- package/dist/src/utils/themePerformanceMonitor.d.ts.map +1 -0
- package/dist/src/utils/themeUtils.d.ts +27 -0
- package/dist/src/utils/themeUtils.d.ts.map +1 -0
- package/dist/utils/cssUtils.d.ts +17 -0
- package/dist/utils/cssUtils.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +5 -2
- package/scripts/bundle-css.cjs +27 -0
- package/scripts/create-project.sh +28 -0
- package/scripts/create-qwickapps-project.js +284 -0
- package/src/__tests__/components/base/Container.test.tsx +966 -0
- package/src/__tests__/schemas/PageTemplateSchema.test.ts +1 -1
- package/src/__tests__/schemas/ViewSchema.test.ts +805 -0
- package/src/__tests__/schemas/builders.test.ts +2 -2
- package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +19 -19
- package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +13 -13
- package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +39 -39
- package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +14 -14
- package/src/__tests__/schemas/transformers/TestAutomation.test.ts +8 -8
- package/src/__tests__/schemas/transformers/nested-serialization.test.tsx +181 -0
- package/src/__tests__/schemas/transformers/round-trip-component-serialization.test.tsx +458 -0
- package/src/__tests__/test_image_accessibility.test.tsx +226 -0
- package/src/__tests__/utils/optional-logging.test.ts +3 -3
- package/src/components/Html.tsx +24 -15
- package/src/components/Logo.tsx +2 -2
- package/src/components/Markdown.tsx +2 -7
- package/src/components/SafeSpan.tsx +2 -7
- package/src/components/base/Container.tsx +61 -0
- package/src/components/base/ModelView.tsx +225 -91
- package/src/components/base/index.ts +3 -2
- package/src/components/blocks/Article.tsx +2 -7
- package/src/components/blocks/CardListGrid.tsx +2 -2
- package/src/components/blocks/Code.tsx +91 -179
- package/src/components/blocks/Content.tsx +2 -2
- package/src/components/blocks/CoverImageHeader.tsx +2 -2
- package/src/components/blocks/HeroBlock.tsx +54 -146
- package/src/components/blocks/Image.tsx +82 -196
- package/src/components/blocks/PageBannerHeader.tsx +2 -2
- package/src/components/blocks/Section.tsx +79 -181
- package/src/components/blocks/Text.tsx +100 -198
- package/src/components/buttons/Button.tsx +85 -183
- package/src/components/buttons/PaletteSwitcher.tsx +2 -2
- package/src/components/buttons/ThemeSwitcher.tsx +2 -2
- package/src/components/forms/FormBlock.tsx +2 -2
- package/src/components/index.ts +5 -0
- package/src/components/input/ChoiceInputField.tsx +76 -160
- package/src/components/input/HtmlInputField.tsx +141 -264
- package/src/components/input/SelectInputField.tsx +48 -153
- package/src/components/input/SwitchInputField.tsx +41 -139
- package/src/components/input/TextInputField.tsx +39 -116
- package/src/components/layout/GridCell.tsx +36 -122
- package/src/components/layout/GridLayout.tsx +55 -127
- package/src/components/pages/Page.tsx +268 -276
- package/src/components/pages/index.ts +2 -3
- package/src/components/shared/createSerializableView.tsx +280 -0
- package/src/components/shared/viewProps.ts +207 -0
- package/src/config/__tests__/AppConfigBuilder.test.ts +2 -2
- package/src/contexts/DataContext.tsx +1 -1
- package/src/schemas/ButtonSchema.ts +3 -2
- package/src/schemas/CardListGridSchema.ts +3 -2
- package/src/schemas/ChoiceInputFieldSchema.ts +3 -2
- package/src/schemas/CodeSchema.ts +8 -6
- package/src/schemas/ContainerSchema.ts +25 -0
- package/src/schemas/FeatureCardSchema.ts +1 -1
- package/src/schemas/FormBlockSchema.ts +3 -2
- package/src/schemas/GridCellSchema.ts +4 -10
- package/src/schemas/GridLayoutSchema.ts +8 -14
- package/src/schemas/HeroBlockSchema.ts +3 -2
- package/src/schemas/HtmlInputFieldSchema.ts +3 -2
- package/src/schemas/ImageSchema.ts +3 -2
- package/src/schemas/PageTemplateSchema.ts +5 -5
- package/src/schemas/SectionSchema.ts +4 -12
- package/src/schemas/SelectInputFieldSchema.ts +3 -2
- package/src/schemas/SwitchInputFieldSchema.ts +2 -2
- package/src/schemas/TextInputFieldSchema.ts +3 -2
- package/src/schemas/ViewSchema.ts +570 -0
- package/src/schemas/index.ts +1 -1
- package/src/schemas/transformers/ComponentTransformer.ts +185 -163
- package/src/schemas/transformers/ReactNodeTransformer.ts +31 -28
- package/src/schemas/transformers/registry.ts +17 -10
- package/src/stories/Button.stories.tsx +24 -0
- package/src/stories/ChoiceInputField.stories.tsx +28 -1
- package/src/stories/Code.stories.tsx +61 -1
- package/src/stories/Container.stories.tsx +954 -0
- package/src/stories/FormBlock.stories.tsx +54 -0
- package/src/stories/FormComponents.stories.tsx +8 -13
- package/src/stories/GridCell.stories.tsx +23 -64
- package/src/stories/GridLayout.stories.tsx +22 -47
- package/src/stories/HeroBlock.stories.tsx +28 -0
- package/src/stories/HtmlInputField.stories.tsx +23 -1
- package/src/stories/Image.stories.tsx +45 -233
- package/src/stories/Markdown.stories.tsx +1 -1
- package/src/stories/Section.stories.tsx +38 -4
- package/src/stories/SelectInputField.stories.tsx +26 -1
- package/src/stories/Text.stories.tsx +22 -54
- package/src/stories/TextInputField.stories.tsx +24 -1
- package/src/stories/_templates/SerializationTemplate.tsx +165 -0
- package/src/templates/TemplateResolver.ts +2 -2
- package/src/types/CollapsibleLayout.ts +2 -2
- package/src/utils/cssUtils.ts +49 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/logger.ts +13 -13
- package/src/__tests__/components/base/ModelView.test.tsx +0 -220
- package/src/__tests__/schemas/ViewModelSchema.test.ts +0 -80
- package/src/components/blocks/Code.md +0 -529
- package/src/schemas/README.md +0 -661
- package/src/schemas/ViewModelSchema.ts +0 -115
- package/src/tests/ConsoleWarningTest.tsx +0 -30
- package/src/tests/StorageKeyTest.tsx +0 -110
- package/src/tests/ThemeStorageKeyTest.tsx +0 -114
|
@@ -28,11 +28,39 @@ const patternRegistry = new Map<string, PatternHandler>();
|
|
|
28
28
|
*/
|
|
29
29
|
export type PatternHandler = (element: Element) => any;
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Strict mode: throw on unregistered components
|
|
33
|
+
* When true, the transformer will throw errors instead of using fallback
|
|
34
|
+
*/
|
|
35
|
+
let strictMode = true;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fallback tag for unregistered components / html / text (legacy mode only)
|
|
39
|
+
*/
|
|
40
|
+
const FALLBACK_TAG = '__react_node__';
|
|
41
|
+
const FALLBACK_VERSION = '1.0.0';
|
|
42
|
+
|
|
31
43
|
/**
|
|
32
44
|
* Core transformer for React component serialization
|
|
33
45
|
* Provides static methods for component registration and transformation
|
|
34
46
|
*/
|
|
35
47
|
export class ComponentTransformer {
|
|
48
|
+
/**
|
|
49
|
+
* Enable or disable strict mode
|
|
50
|
+
* @param enabled - Whether to enable strict mode (throws on unregistered components)
|
|
51
|
+
*/
|
|
52
|
+
static setStrictMode(enabled: boolean): void {
|
|
53
|
+
strictMode = enabled;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Check if strict mode is enabled
|
|
58
|
+
* @returns True if strict mode is enabled
|
|
59
|
+
*/
|
|
60
|
+
static isStrictMode(): boolean {
|
|
61
|
+
return strictMode;
|
|
62
|
+
}
|
|
63
|
+
|
|
36
64
|
/**
|
|
37
65
|
* Register a component class for serialization
|
|
38
66
|
* Component must declare its own tagName and version via static properties
|
|
@@ -40,21 +68,26 @@ export class ComponentTransformer {
|
|
|
40
68
|
*/
|
|
41
69
|
static registerComponent(componentClass: SerializableConstructor): void {
|
|
42
70
|
const { tagName, version } = componentClass;
|
|
43
|
-
|
|
71
|
+
|
|
44
72
|
if (!tagName || typeof tagName !== 'string') {
|
|
45
73
|
throw new Error(`Component class must have a static 'tagName' property`);
|
|
46
74
|
}
|
|
47
|
-
|
|
75
|
+
|
|
48
76
|
if (!version || typeof version !== 'string') {
|
|
49
|
-
throw new Error(`Component class must have a static 'version' property`);
|
|
77
|
+
throw new Error(`Component class '${tagName}' must have a static 'version' property`);
|
|
50
78
|
}
|
|
51
|
-
|
|
79
|
+
|
|
80
|
+
if (typeof (componentClass as any).fromJson !== 'function') {
|
|
81
|
+
throw new Error(`Component class '${tagName}' must implement static 'fromJson' method`);
|
|
82
|
+
}
|
|
83
|
+
|
|
52
84
|
if (componentRegistry.has(tagName)) {
|
|
53
85
|
console.warn(`Component '${tagName}' is already registered. Overwriting existing registration.`);
|
|
54
86
|
}
|
|
55
|
-
|
|
87
|
+
|
|
88
|
+
console.log(`TEST: Registering component: ${tagName} (version ${version})`);
|
|
56
89
|
componentRegistry.set(tagName, componentClass);
|
|
57
|
-
|
|
90
|
+
|
|
58
91
|
// Register HTML patterns if component supports them
|
|
59
92
|
if (typeof (componentClass as any).registerPatternHandlers === 'function') {
|
|
60
93
|
(componentClass as any).registerPatternHandlers(ComponentTransformer);
|
|
@@ -63,185 +96,169 @@ export class ComponentTransformer {
|
|
|
63
96
|
|
|
64
97
|
/**
|
|
65
98
|
* Serialize React node(s) to JSON string
|
|
66
|
-
*
|
|
67
|
-
*
|
|
99
|
+
* In strict mode: throws on unregistered components
|
|
100
|
+
* In legacy mode: uses fallback tag for unregistered components/html/text
|
|
68
101
|
*/
|
|
69
102
|
static serialize(node: ReactNode | ReactNode[]): string {
|
|
70
|
-
const serializedData = ComponentTransformer.serializeNode(node);
|
|
103
|
+
const serializedData = ComponentTransformer.serializeNode(node as any);
|
|
71
104
|
return JSON.stringify(serializedData);
|
|
72
105
|
}
|
|
73
106
|
|
|
74
107
|
/**
|
|
75
108
|
* Deserialize JSON input to React node(s)
|
|
76
|
-
*
|
|
77
|
-
*
|
|
109
|
+
* In strict mode: throws on unregistered components
|
|
110
|
+
* In legacy mode: never throws; always returns a valid ReactNode (or array) or null
|
|
111
|
+
* - Strings: try JSON.parse; if fails, return the string as a text node
|
|
112
|
+
* - Objects/arrays: only schema objects are transformed; non-schema become text via JSON.stringify
|
|
78
113
|
*/
|
|
79
114
|
static deserialize(input: string | object | object[]): ReactNode | ReactNode[] {
|
|
80
|
-
let parsedData: any;
|
|
81
|
-
|
|
82
|
-
// Handle string input - parse JSON only if it looks like JSON
|
|
83
115
|
if (typeof input === 'string') {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
parsedData = JSON.parse(input);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
93
|
-
}
|
|
94
|
-
} else {
|
|
95
|
-
// For strings that contain JSON-like characters but aren't valid JSON, try to parse anyway
|
|
96
|
-
if (trimmed.includes('{') || trimmed.includes('[')) {
|
|
97
|
-
try {
|
|
98
|
-
parsedData = JSON.parse(input);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
// Treat as plain string
|
|
104
|
-
parsedData = input;
|
|
105
|
-
}
|
|
116
|
+
try {
|
|
117
|
+
const parsed = JSON.parse(input);
|
|
118
|
+
return ComponentTransformer.deserializeData(parsed);
|
|
119
|
+
} catch {
|
|
120
|
+
// Not JSON; plain string is a valid ReactNode
|
|
121
|
+
return input;
|
|
106
122
|
}
|
|
107
|
-
} else {
|
|
108
|
-
parsedData = input;
|
|
109
123
|
}
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
if (input == null) return null;
|
|
126
|
+
return ComponentTransformer.deserializeData(input as any);
|
|
112
127
|
}
|
|
113
128
|
|
|
114
129
|
/**
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
* Type guard for serialized component schema objects
|
|
131
|
+
* Requires: { tagName: string; version: string; data: any }
|
|
132
|
+
* Optional: key?: string
|
|
133
|
+
*/
|
|
134
|
+
private static isSerializedComponent(obj: any): obj is { tagName: string; version: string; data: any; key?: string } {
|
|
135
|
+
return !!obj
|
|
136
|
+
&& typeof obj === 'object'
|
|
137
|
+
&& typeof (obj as any).tagName === 'string'
|
|
138
|
+
&& typeof (obj as any).version === 'string'
|
|
139
|
+
&& 'data' in (obj as any);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Internal method to deserialize data back to React nodes
|
|
144
|
+
* @param data - Data to deserialize
|
|
145
|
+
* @returns React node(s)
|
|
118
146
|
*/
|
|
119
|
-
private static
|
|
120
|
-
if (
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
147
|
+
private static deserializeData(data: any): ReactNode | ReactNode[] {
|
|
148
|
+
if (data == null) return null;
|
|
123
149
|
|
|
124
|
-
//
|
|
125
|
-
if (Array.isArray(
|
|
126
|
-
return
|
|
150
|
+
// Arrays: map recursively
|
|
151
|
+
if (Array.isArray(data)) {
|
|
152
|
+
return data.map(item => ComponentTransformer.deserializeData(item));
|
|
127
153
|
}
|
|
128
154
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return node;
|
|
132
|
-
}
|
|
155
|
+
if (ComponentTransformer.isSerializedComponent(data)) {
|
|
156
|
+
const { key, tagName, data: componentData } = data;
|
|
133
157
|
|
|
134
|
-
// Handle plain objects (non-React elements)
|
|
135
|
-
if (typeof node === 'object' && node !== null && !('type' in node)) {
|
|
136
|
-
// For plain objects, try to serialize recursively or convert to string
|
|
137
158
|
try {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
159
|
+
const componentClass = componentRegistry.get(tagName);
|
|
160
|
+
|
|
161
|
+
if (!componentClass) {
|
|
162
|
+
if (strictMode) {
|
|
163
|
+
throw new Error(`Component '${tagName}' is not registered in strict mode`);
|
|
164
|
+
}
|
|
165
|
+
// Legacy fallback
|
|
166
|
+
const node = ComponentTransformer.deserializeUnregisteredComponent(componentData);
|
|
167
|
+
return key ? React.cloneElement(node as ReactElement, { key }) : node;
|
|
141
168
|
}
|
|
142
|
-
return serialized;
|
|
143
|
-
} catch {
|
|
144
|
-
return String(node);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
169
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (typeof componentType === 'function') {
|
|
155
|
-
// Find the tag name for this component
|
|
156
|
-
const tagName = ComponentTransformer.findTagNameForComponent(componentType);
|
|
157
|
-
if (tagName) {
|
|
158
|
-
const componentClass = componentRegistry.get(tagName)!;
|
|
159
|
-
// Create a temporary instance to call toJson
|
|
160
|
-
const instance = new (componentClass as any)(element.props);
|
|
161
|
-
const serializedData = instance.toJson();
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
tag: tagName,
|
|
165
|
-
version: componentClass.version,
|
|
166
|
-
data: serializedData
|
|
167
|
-
};
|
|
170
|
+
const node = componentClass.fromJson(data);
|
|
171
|
+
// Apply key if provided
|
|
172
|
+
return key ? React.cloneElement(node as ReactElement, { key }) : node;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (strictMode) {
|
|
175
|
+
throw error; // Re-throw in strict mode
|
|
168
176
|
}
|
|
177
|
+
console.error(`TEST: Error deserializing component '${tagName}':`, error);
|
|
169
178
|
}
|
|
170
|
-
|
|
171
|
-
// For unregistered components, use ReactNodeTransformer fallback
|
|
172
|
-
return ComponentTransformer.serializeUnregisteredComponent(element);
|
|
173
179
|
}
|
|
174
180
|
|
|
175
|
-
|
|
176
|
-
return String(
|
|
181
|
+
console.warn(`TEST: Unrecognized data:`, data);
|
|
182
|
+
return String(data);
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
/**
|
|
180
|
-
* Internal method to
|
|
181
|
-
* @param
|
|
182
|
-
* @returns
|
|
186
|
+
* Internal method to serialize a single React node
|
|
187
|
+
* @param node - React node to serialize
|
|
188
|
+
* @returns Serializable data structure { tagName, version, data }
|
|
183
189
|
*/
|
|
184
|
-
private static
|
|
185
|
-
if (
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
190
|
+
private static serializeNode(node: any): any {
|
|
191
|
+
if (node == null) return null;
|
|
188
192
|
|
|
189
|
-
// Handle arrays
|
|
190
|
-
if (Array.isArray(
|
|
191
|
-
return
|
|
193
|
+
// Handle arrays of nodes (produce array of schema objects/null)
|
|
194
|
+
if (Array.isArray(node)) {
|
|
195
|
+
return node.map(child => ComponentTransformer.serializeNode(child));
|
|
192
196
|
}
|
|
193
197
|
|
|
194
|
-
// Handle primitive values
|
|
195
|
-
if (typeof
|
|
196
|
-
return
|
|
198
|
+
// Handle primitive values (strings, numbers, booleans) - these are valid React children
|
|
199
|
+
if (typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {
|
|
200
|
+
return node;
|
|
197
201
|
}
|
|
198
202
|
|
|
199
|
-
//
|
|
200
|
-
if (typeof
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
// Handle unregistered components using ReactNodeTransformer
|
|
204
|
-
if (tag === '__react_node__') {
|
|
205
|
-
return ComponentTransformer.deserializeUnregisteredComponent(componentData);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const componentClass = componentRegistry.get(tag);
|
|
209
|
-
if (!componentClass) {
|
|
210
|
-
// Fallback to ReactNodeTransformer for unknown registered components
|
|
211
|
-
console.warn(`Unknown component: ${tag}. Using ReactNodeTransformer fallback.`);
|
|
212
|
-
return ComponentTransformer.deserializeUnregisteredComponent(componentData);
|
|
213
|
-
}
|
|
203
|
+
// React elements
|
|
204
|
+
if (typeof node === 'object' && 'type' in node) {
|
|
205
|
+
const element = node as ReactElement;
|
|
206
|
+
const key = element.key ? { key: String(element.key) } : {};
|
|
214
207
|
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
208
|
+
// Registered component?
|
|
209
|
+
const componentType = element.type;
|
|
210
|
+
if (typeof componentType === 'function') {
|
|
211
|
+
const tagName = ComponentTransformer.findTagNameForComponent(componentType);
|
|
212
|
+
if (tagName) {
|
|
213
|
+
console.log(`TEST: Serializing component instance of ${tagName}:`, element.props);
|
|
214
|
+
const componentClass = componentRegistry.get(tagName)!;
|
|
219
215
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
216
|
+
let serializedData: any = null;
|
|
217
|
+
console.log(`TEST: Element type:`, typeof (element as any).toJson);
|
|
218
|
+
console.log(`TEST: Component type:`, typeof (componentClass as any).toJson);
|
|
219
|
+
if (typeof (componentClass as any).toJson === 'function') {
|
|
220
|
+
console.log(`TEST: Serializing via component toJson method ${tagName}:`, element.props);
|
|
221
|
+
serializedData = (componentClass as any).toJson(element.props);
|
|
222
|
+
}
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
if (serializedData !== null) {
|
|
225
|
+
// Process children recursively if they exist in the data
|
|
226
|
+
if (serializedData.data && serializedData.data.children !== undefined) {
|
|
227
|
+
serializedData.data.children = ComponentTransformer.serializeNode(serializedData.data.children);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const result = {
|
|
231
|
+
...key,
|
|
232
|
+
...serializedData
|
|
233
|
+
};
|
|
234
|
+
console.log(`TEST: Serialized component ${tagName}:`, result);
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
} else if (strictMode) {
|
|
238
|
+
// In strict mode, throw if we can't find a tag name for the component
|
|
239
|
+
const componentName = (componentType as any).displayName || (componentType as any).name || 'Unknown';
|
|
240
|
+
throw new Error(`Unregistered component '${componentName}' cannot be serialized in strict mode`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
227
244
|
|
|
245
|
+
if (strictMode) {
|
|
246
|
+
throw new Error(`Cannot serialize unregistered node in strict mode: ${typeof node === 'object' && node && 'type' in node ? node.type : typeof node}`);
|
|
247
|
+
}
|
|
228
248
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
*/
|
|
234
|
-
private static serializeUnregisteredComponent(element: ReactElement): any {
|
|
235
|
-
return {
|
|
236
|
-
tag: '__react_node__',
|
|
237
|
-
version: '1.0.0',
|
|
238
|
-
data: ReactNodeTransformer.serialize(element)
|
|
249
|
+
const result = {
|
|
250
|
+
tagName: FALLBACK_TAG,
|
|
251
|
+
version: FALLBACK_VERSION,
|
|
252
|
+
data: ReactNodeTransformer.serialize(node)
|
|
239
253
|
};
|
|
254
|
+
console.log(`TEST: Serialized unregistered node as ${FALLBACK_TAG}:`, result, node);
|
|
255
|
+
console.log(`TEST: Component Registry:`, componentRegistry);
|
|
256
|
+
return result;
|
|
240
257
|
}
|
|
241
258
|
|
|
242
259
|
/**
|
|
243
|
-
* Deserialize unregistered
|
|
244
|
-
* @param data - Serialized data
|
|
260
|
+
* Deserialize unregistered nodes using ReactNodeTransformer
|
|
261
|
+
* @param data - Serialized data from ReactNodeTransformer
|
|
245
262
|
* @returns React node
|
|
246
263
|
*/
|
|
247
264
|
private static deserializeUnregisteredComponent(data: any): ReactNode {
|
|
@@ -254,14 +271,30 @@ export class ComponentTransformer {
|
|
|
254
271
|
* @returns Tag name or null if not found
|
|
255
272
|
*/
|
|
256
273
|
private static findTagNameForComponent(componentType: any): string | null {
|
|
257
|
-
|
|
258
|
-
for (const [tagName, registeredClass] of entries) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
274
|
+
// Direct constructor match
|
|
275
|
+
for (const [tagName, registeredClass] of componentRegistry.entries()) {
|
|
276
|
+
if (registeredClass === componentType) return tagName;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// If the component exposes a tagName, prefer it
|
|
280
|
+
const explicitTag = componentType?.tagName;
|
|
281
|
+
if (typeof explicitTag === 'string' && componentRegistry.has(explicitTag)) {
|
|
282
|
+
return explicitTag;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Unwrap common HOC/wrapper names
|
|
286
|
+
const name: string | undefined = componentType?.displayName || componentType?.name;
|
|
287
|
+
if (name) {
|
|
288
|
+
// ForwardRef(Typography) -> Typography, Styled(Typography) -> Typography
|
|
289
|
+
// WithDataBinding(Text) -> Text, TextWithDataBinding -> Text
|
|
290
|
+
const unwrapped =
|
|
291
|
+
name.replace(/^[A-Za-z]+?\(([^)]+)\)$/, '$1')
|
|
292
|
+
.replace(/WithDataBinding$/, '');
|
|
293
|
+
|
|
294
|
+
if (componentRegistry.has(unwrapped)) return unwrapped;
|
|
295
|
+
if (componentRegistry.has(name)) return name;
|
|
264
296
|
}
|
|
297
|
+
|
|
265
298
|
return null;
|
|
266
299
|
}
|
|
267
300
|
|
|
@@ -310,7 +343,6 @@ export class ComponentTransformer {
|
|
|
310
343
|
* @returns React node if pattern matches, null otherwise
|
|
311
344
|
*/
|
|
312
345
|
static transformHTMLElement(element: Element): ReactNode | null {
|
|
313
|
-
// Find matching pattern handler
|
|
314
346
|
for (const [pattern, handler] of patternRegistry) {
|
|
315
347
|
if (element.matches(pattern)) {
|
|
316
348
|
try {
|
|
@@ -322,7 +354,7 @@ export class ComponentTransformer {
|
|
|
322
354
|
}
|
|
323
355
|
}
|
|
324
356
|
}
|
|
325
|
-
return null;
|
|
357
|
+
return null;
|
|
326
358
|
}
|
|
327
359
|
|
|
328
360
|
/**
|
|
@@ -331,13 +363,9 @@ export class ComponentTransformer {
|
|
|
331
363
|
* @returns Array of React nodes
|
|
332
364
|
*/
|
|
333
365
|
static transformHTML(html: string): ReactNode[] {
|
|
334
|
-
if (!html.trim())
|
|
335
|
-
return [];
|
|
336
|
-
}
|
|
337
|
-
|
|
366
|
+
if (!html.trim()) return [];
|
|
338
367
|
const parser = new DOMParser();
|
|
339
368
|
const doc = parser.parseFromString(html, 'text/html');
|
|
340
|
-
|
|
341
369
|
return Array.from(doc.body.children).map((element, index) =>
|
|
342
370
|
ComponentTransformer.transformElement(element, `element-${index}`)
|
|
343
371
|
);
|
|
@@ -350,28 +378,22 @@ export class ComponentTransformer {
|
|
|
350
378
|
* @returns React node
|
|
351
379
|
*/
|
|
352
380
|
private static transformElement(element: Element, key: string): ReactNode {
|
|
353
|
-
// Try to find a registered pattern handler
|
|
354
381
|
const transformedNode = ComponentTransformer.transformHTMLElement(element);
|
|
355
|
-
if (transformedNode)
|
|
356
|
-
return transformedNode;
|
|
357
|
-
}
|
|
382
|
+
if (transformedNode) return transformedNode;
|
|
358
383
|
|
|
359
|
-
// No pattern matched - check for nested transformable content
|
|
360
384
|
const children = Array.from(element.children);
|
|
361
|
-
const hasTransformableChildren = children.some(child =>
|
|
385
|
+
const hasTransformableChildren = children.some(child =>
|
|
362
386
|
Array.from(patternRegistry.keys()).some(pattern => child.matches(pattern))
|
|
363
387
|
);
|
|
364
388
|
|
|
365
389
|
if (hasTransformableChildren) {
|
|
366
|
-
// Transform children recursively
|
|
367
390
|
const transformedChildren = children.map((child, index) =>
|
|
368
391
|
ComponentTransformer.transformElement(child, `${key}-${index}`)
|
|
369
392
|
);
|
|
370
|
-
|
|
371
|
-
// Create element with transformed children
|
|
393
|
+
|
|
372
394
|
return React.createElement(
|
|
373
395
|
element.tagName.toLowerCase(),
|
|
374
|
-
{
|
|
396
|
+
{
|
|
375
397
|
key,
|
|
376
398
|
className: element.className || undefined,
|
|
377
399
|
id: element.id || undefined
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { ReactNode,
|
|
12
|
-
import
|
|
11
|
+
import { ReactElement, ReactNode, createElement, isValidElement } from 'react';
|
|
12
|
+
import { Html } from '../../components/Html';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Transformer for standard React content and HTML elements
|
|
@@ -45,12 +45,23 @@ export class ReactNodeTransformer {
|
|
|
45
45
|
// Handle React elements
|
|
46
46
|
if (isValidElement(node)) {
|
|
47
47
|
const element = node as ReactElement;
|
|
48
|
-
|
|
48
|
+
console.log(`TEST: isValidElement:`, element);
|
|
49
|
+
|
|
50
|
+
const comp: any = element.type;
|
|
51
|
+
const rawName =
|
|
52
|
+
typeof comp === 'string'
|
|
53
|
+
? comp
|
|
54
|
+
: comp?.render?.name || comp?.name || comp?.muiName || comp?.displayName || 'Anonymous';
|
|
55
|
+
|
|
56
|
+
// Normalize wrapper names like ForwardRef(Typography), Styled(Typography)
|
|
57
|
+
const displayName =
|
|
58
|
+
typeof rawName === 'string'
|
|
59
|
+
? (rawName.match(/^[A-Za-z]+?\(([^)]+)\)$/)?.[1] || rawName)
|
|
60
|
+
: 'Anonymous';
|
|
61
|
+
|
|
49
62
|
return {
|
|
50
63
|
type: 'react-element',
|
|
51
|
-
elementType:
|
|
52
|
-
? element.type
|
|
53
|
-
: (element.type as any).name || 'Anonymous',
|
|
64
|
+
elementType: displayName,
|
|
54
65
|
props: ReactNodeTransformer.serializeProps(element.props),
|
|
55
66
|
key: element.key
|
|
56
67
|
};
|
|
@@ -94,16 +105,16 @@ export class ReactNodeTransformer {
|
|
|
94
105
|
switch (data.type) {
|
|
95
106
|
case 'primitive':
|
|
96
107
|
return data.value;
|
|
97
|
-
|
|
108
|
+
|
|
98
109
|
case 'string':
|
|
99
110
|
return data.value;
|
|
100
|
-
|
|
111
|
+
|
|
101
112
|
case 'array':
|
|
102
113
|
return data.children?.map((child: any) => ReactNodeTransformer.deserialize(child)) || [];
|
|
103
|
-
|
|
114
|
+
|
|
104
115
|
case 'react-element':
|
|
105
116
|
return ReactNodeTransformer.deserializeReactElement(data);
|
|
106
|
-
|
|
117
|
+
|
|
107
118
|
case 'object':
|
|
108
119
|
const result: any = {};
|
|
109
120
|
if (data.data && typeof data.data === 'object') {
|
|
@@ -112,7 +123,7 @@ export class ReactNodeTransformer {
|
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
return result;
|
|
115
|
-
|
|
126
|
+
|
|
116
127
|
default:
|
|
117
128
|
return String(data.value || data);
|
|
118
129
|
}
|
|
@@ -165,23 +176,15 @@ export class ReactNodeTransformer {
|
|
|
165
176
|
// Handle HTML elements
|
|
166
177
|
if (typeof elementType === 'string') {
|
|
167
178
|
const deserializedProps = ReactNodeTransformer.deserializeProps(props);
|
|
179
|
+
console.log(`TEST: Create Element:`, elementType, deserializedProps);
|
|
168
180
|
return createElement(elementType, { key, ...deserializedProps });
|
|
169
181
|
}
|
|
170
|
-
|
|
171
|
-
// For unknown component types, check if we have HTML content
|
|
172
|
-
if (props && typeof props.children === 'string' && props.children.includes('<')) {
|
|
173
|
-
// Use SafeSpan component to render HTML content safely
|
|
174
|
-
return createElement(SafeSpan, { key, html: props.children });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Fallback to div with text content
|
|
178
|
-
const textContent = ReactNodeTransformer.extractTextContent(props);
|
|
179
|
-
return createElement('div', { key }, textContent || `Unknown component: ${elementType}`);
|
|
180
|
-
|
|
181
182
|
} catch (error) {
|
|
182
183
|
console.warn('Error deserializing React element:', error);
|
|
183
|
-
return createElement('div', { key }, `Error rendering component: ${elementType}`);
|
|
184
184
|
}
|
|
185
|
+
|
|
186
|
+
// Use Html component to render HTML content safely
|
|
187
|
+
return createElement(Html, { key, children: props.children });
|
|
185
188
|
}
|
|
186
189
|
|
|
187
190
|
/**
|
|
@@ -214,23 +217,23 @@ export class ReactNodeTransformer {
|
|
|
214
217
|
*/
|
|
215
218
|
private static extractTextContent(props: any): string | null {
|
|
216
219
|
if (!props) return null;
|
|
217
|
-
|
|
220
|
+
|
|
218
221
|
if (typeof props.children === 'string') {
|
|
219
222
|
return props.children;
|
|
220
223
|
}
|
|
221
|
-
|
|
224
|
+
|
|
222
225
|
if (props.title && typeof props.title === 'string') {
|
|
223
226
|
return props.title;
|
|
224
227
|
}
|
|
225
|
-
|
|
228
|
+
|
|
226
229
|
if (props.label && typeof props.label === 'string') {
|
|
227
230
|
return props.label;
|
|
228
231
|
}
|
|
229
|
-
|
|
232
|
+
|
|
230
233
|
if (props.text && typeof props.text === 'string') {
|
|
231
234
|
return props.text;
|
|
232
235
|
}
|
|
233
|
-
|
|
236
|
+
|
|
234
237
|
return null;
|
|
235
238
|
}
|
|
236
239
|
}
|
|
@@ -8,27 +8,34 @@
|
|
|
8
8
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { Container } from '../../components/base/Container';
|
|
12
12
|
import { Code } from '../../components/blocks/Code';
|
|
13
|
-
import {
|
|
13
|
+
import { HeroBlock } from '../../components/blocks/HeroBlock';
|
|
14
14
|
import { Image } from '../../components/blocks/Image';
|
|
15
|
+
import { Section } from '../../components/blocks/Section';
|
|
15
16
|
import { Text } from '../../components/blocks/Text';
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import { GridLayout } from '../../components/layout/GridLayout';
|
|
19
|
-
import { GridCell } from '../../components/layout/GridCell';
|
|
20
|
-
import { TextInputField } from '../../components/input/TextInputField';
|
|
21
|
-
import { SelectInputField } from '../../components/input/SelectInputField';
|
|
22
|
-
import { HtmlInputField } from '../../components/input/HtmlInputField';
|
|
17
|
+
import { Button } from '../../components/buttons/Button';
|
|
18
|
+
import { FormBlock } from '../../components/forms/FormBlock';
|
|
23
19
|
import { ChoiceInputField } from '../../components/input/ChoiceInputField';
|
|
20
|
+
import { HtmlInputField } from '../../components/input/HtmlInputField';
|
|
21
|
+
import { SelectInputField } from '../../components/input/SelectInputField';
|
|
24
22
|
import { SwitchInputField } from '../../components/input/SwitchInputField';
|
|
25
|
-
import {
|
|
23
|
+
import { TextInputField } from '../../components/input/TextInputField';
|
|
24
|
+
import { GridCell } from '../../components/layout/GridCell';
|
|
25
|
+
import { GridLayout } from '../../components/layout/GridLayout';
|
|
26
|
+
import { ComponentTransformer } from './ComponentTransformer';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Register all serializable components with the ComponentTransformer
|
|
29
30
|
* This function should be called once during application initialization
|
|
31
|
+
*
|
|
32
|
+
* Phase 0: Foundation in place - ready for component migration
|
|
33
|
+
* Phase 1+: Components will be migrated to createSerializableView factory
|
|
30
34
|
*/
|
|
31
35
|
export function registerSerializableComponents(): void {
|
|
36
|
+
// Register Container component - Base layout component with child serialization support
|
|
37
|
+
ComponentTransformer.registerComponent(Container as any);
|
|
38
|
+
|
|
32
39
|
// Register Code component - First production component with serialization support
|
|
33
40
|
ComponentTransformer.registerComponent(Code as any);
|
|
34
41
|
|