@qwickapps/react-framework 1.3.0
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/LICENSE +44 -0
- package/README.md +794 -0
- package/dist/components/AccessibilityChecker.d.ts +12 -0
- package/dist/components/AccessibilityChecker.d.ts.map +1 -0
- package/dist/components/Html.d.ts +48 -0
- package/dist/components/Html.d.ts.map +1 -0
- package/dist/components/Logo.d.ts +79 -0
- package/dist/components/Logo.d.ts.map +1 -0
- package/dist/components/Markdown.d.ts +47 -0
- package/dist/components/Markdown.d.ts.map +1 -0
- package/dist/components/QwickApp.d.ts +56 -0
- package/dist/components/QwickApp.d.ts.map +1 -0
- package/dist/components/QwickAppsLogo.d.ts +25 -0
- package/dist/components/QwickAppsLogo.d.ts.map +1 -0
- package/dist/components/ResponsiveMenu.d.ts +38 -0
- package/dist/components/ResponsiveMenu.d.ts.map +1 -0
- package/dist/components/SafeSpan.d.ts +23 -0
- package/dist/components/SafeSpan.d.ts.map +1 -0
- package/dist/components/Scaffold.d.ts +57 -0
- package/dist/components/Scaffold.d.ts.map +1 -0
- package/dist/components/blocks/Article.d.ts +23 -0
- package/dist/components/blocks/Article.d.ts.map +1 -0
- package/dist/components/blocks/CardListGrid.d.ts +23 -0
- package/dist/components/blocks/CardListGrid.d.ts.map +1 -0
- package/dist/components/blocks/Code.d.ts +21 -0
- package/dist/components/blocks/Code.d.ts.map +1 -0
- package/dist/components/blocks/Content.d.ts +24 -0
- package/dist/components/blocks/Content.d.ts.map +1 -0
- package/dist/components/blocks/CoverImageHeader.d.ts +44 -0
- package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -0
- package/dist/components/blocks/FeatureCard.d.ts +66 -0
- package/dist/components/blocks/FeatureCard.d.ts.map +1 -0
- package/dist/components/blocks/FeatureGrid.d.ts +48 -0
- package/dist/components/blocks/FeatureGrid.d.ts.map +1 -0
- package/dist/components/blocks/Footer.d.ts +56 -0
- package/dist/components/blocks/Footer.d.ts.map +1 -0
- package/dist/components/blocks/HeroBlock.d.ts +33 -0
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -0
- package/dist/components/blocks/PageBannerHeader.d.ts +30 -0
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -0
- package/dist/components/blocks/ProductCard.d.ts +57 -0
- package/dist/components/blocks/ProductCard.d.ts.map +1 -0
- package/dist/components/blocks/Section.d.ts +40 -0
- package/dist/components/blocks/Section.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +37 -0
- package/dist/components/blocks/index.d.ts.map +1 -0
- package/dist/components/buttons/Button.d.ts +38 -0
- package/dist/components/buttons/Button.d.ts.map +1 -0
- package/dist/components/buttons/PaletteSwitcher.d.ts +24 -0
- package/dist/components/buttons/PaletteSwitcher.d.ts.map +1 -0
- package/dist/components/buttons/ThemeSwitcher.d.ts +24 -0
- package/dist/components/buttons/ThemeSwitcher.d.ts.map +1 -0
- package/dist/components/buttons/index.d.ts +11 -0
- package/dist/components/buttons/index.d.ts.map +1 -0
- package/dist/components/forms/FormBlock.d.ts +45 -0
- package/dist/components/forms/FormBlock.d.ts.map +1 -0
- package/dist/components/forms/index.d.ts +8 -0
- package/dist/components/forms/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +32 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/input/ChoiceInputField.d.ts +30 -0
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -0
- package/dist/components/input/HtmlInputField.d.ts +29 -0
- package/dist/components/input/HtmlInputField.d.ts.map +1 -0
- package/dist/components/input/SelectInputField.d.ts +29 -0
- package/dist/components/input/SelectInputField.d.ts.map +1 -0
- package/dist/components/input/TextField.d.ts +18 -0
- package/dist/components/input/TextField.d.ts.map +1 -0
- package/dist/components/input/TextInputField.d.ts +32 -0
- package/dist/components/input/TextInputField.d.ts.map +1 -0
- package/dist/components/input/index.d.ts +17 -0
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/layout/GridCell.d.ts +16 -0
- package/dist/components/layout/GridCell.d.ts.map +1 -0
- package/dist/components/layout/GridCellWrapper.d.ts +46 -0
- package/dist/components/layout/GridCellWrapper.d.ts.map +1 -0
- package/dist/components/layout/GridLayout.d.ts +38 -0
- package/dist/components/layout/GridLayout.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +12 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/menu/Menu.d.ts +1 -0
- package/dist/components/menu/Menu.d.ts.map +1 -0
- package/dist/components/menu/MenuItem.d.ts +31 -0
- package/dist/components/menu/MenuItem.d.ts.map +1 -0
- package/dist/components/menu/index.d.ts +7 -0
- package/dist/components/menu/index.d.ts.map +1 -0
- package/dist/components/pages/FormPage.d.ts +66 -0
- package/dist/components/pages/FormPage.d.ts.map +1 -0
- package/dist/components/pages/Page.d.ts +124 -0
- package/dist/components/pages/Page.d.ts.map +1 -0
- package/dist/components/pages/index.d.ts +11 -0
- package/dist/components/pages/index.d.ts.map +1 -0
- package/dist/contexts/DataContext.d.ts +139 -0
- package/dist/contexts/DataContext.d.ts.map +1 -0
- package/dist/contexts/DimensionsContext.d.ts +42 -0
- package/dist/contexts/DimensionsContext.d.ts.map +1 -0
- package/dist/contexts/PaletteContext.d.ts +53 -0
- package/dist/contexts/PaletteContext.d.ts.map +1 -0
- package/dist/contexts/QwickAppContext.d.ts +71 -0
- package/dist/contexts/QwickAppContext.d.ts.map +1 -0
- package/dist/contexts/ThemeContext.d.ts +65 -0
- package/dist/contexts/ThemeContext.d.ts.map +1 -0
- package/dist/contexts/index.d.ts +9 -0
- package/dist/contexts/index.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useBaseProps.d.ts +101 -0
- package/dist/hooks/useBaseProps.d.ts.map +1 -0
- package/dist/hooks/useDataBinding.d.ts +22 -0
- package/dist/hooks/useDataBinding.d.ts.map +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.css +1 -0
- package/dist/index.esm.js +24143 -0
- package/dist/index.js +24245 -0
- package/dist/palettes/PaletteAutumn.d.ts +10 -0
- package/dist/palettes/PaletteAutumn.d.ts.map +1 -0
- package/dist/palettes/PaletteCosmic.d.ts +10 -0
- package/dist/palettes/PaletteCosmic.d.ts.map +1 -0
- package/dist/palettes/PaletteDefault.d.ts +10 -0
- package/dist/palettes/PaletteDefault.d.ts.map +1 -0
- package/dist/palettes/PaletteOcean.d.ts +10 -0
- package/dist/palettes/PaletteOcean.d.ts.map +1 -0
- package/dist/palettes/PaletteSpring.d.ts +10 -0
- package/dist/palettes/PaletteSpring.d.ts.map +1 -0
- package/dist/palettes/PaletteWinter.d.ts +10 -0
- package/dist/palettes/PaletteWinter.d.ts.map +1 -0
- package/dist/palettes/index.d.ts +13 -0
- package/dist/palettes/index.d.ts.map +1 -0
- package/dist/schemas/ActionSchema.d.ts +21 -0
- package/dist/schemas/ActionSchema.d.ts.map +1 -0
- package/dist/schemas/ArticleSchema.d.ts +13 -0
- package/dist/schemas/ArticleSchema.d.ts.map +1 -0
- package/dist/schemas/Builders.d.ts +7 -0
- package/dist/schemas/Builders.d.ts.map +1 -0
- package/dist/schemas/ButtonSchema.d.ts +19 -0
- package/dist/schemas/ButtonSchema.d.ts.map +1 -0
- package/dist/schemas/CardListGridSchema.d.ts +17 -0
- package/dist/schemas/CardListGridSchema.d.ts.map +1 -0
- package/dist/schemas/ChoiceInputFieldSchema.d.ts +18 -0
- package/dist/schemas/ChoiceInputFieldSchema.d.ts.map +1 -0
- package/dist/schemas/CodeSchema.d.ts +18 -0
- package/dist/schemas/CodeSchema.d.ts.map +1 -0
- package/dist/schemas/ContentSchema.d.ts +20 -0
- package/dist/schemas/ContentSchema.d.ts.map +1 -0
- package/dist/schemas/CoverImageHeaderSchema.d.ts +28 -0
- package/dist/schemas/CoverImageHeaderSchema.d.ts.map +1 -0
- package/dist/schemas/FeatureCardSchema.d.ts +28 -0
- package/dist/schemas/FeatureCardSchema.d.ts.map +1 -0
- package/dist/schemas/FeatureGridSchema.d.ts +17 -0
- package/dist/schemas/FeatureGridSchema.d.ts.map +1 -0
- package/dist/schemas/FeatureItemSchema.d.ts +16 -0
- package/dist/schemas/FeatureItemSchema.d.ts.map +1 -0
- package/dist/schemas/FooterItemSchema.d.ts +15 -0
- package/dist/schemas/FooterItemSchema.d.ts.map +1 -0
- package/dist/schemas/FooterSchema.d.ts +20 -0
- package/dist/schemas/FooterSchema.d.ts.map +1 -0
- package/dist/schemas/FooterSectionSchema.d.ts +15 -0
- package/dist/schemas/FooterSectionSchema.d.ts.map +1 -0
- package/dist/schemas/FormBlockSchema.d.ts +19 -0
- package/dist/schemas/FormBlockSchema.d.ts.map +1 -0
- package/dist/schemas/HeaderActionSchema.d.ts +17 -0
- package/dist/schemas/HeaderActionSchema.d.ts.map +1 -0
- package/dist/schemas/HeroBlockSchema.d.ts +22 -0
- package/dist/schemas/HeroBlockSchema.d.ts.map +1 -0
- package/dist/schemas/HtmlInputFieldSchema.d.ts +18 -0
- package/dist/schemas/HtmlInputFieldSchema.d.ts.map +1 -0
- package/dist/schemas/MetadataItemSchema.d.ts +13 -0
- package/dist/schemas/MetadataItemSchema.d.ts.map +1 -0
- package/dist/schemas/PageBannerHeaderSchema.d.ts +28 -0
- package/dist/schemas/PageBannerHeaderSchema.d.ts.map +1 -0
- package/dist/schemas/PaletteSwitcherSchema.d.ts +16 -0
- package/dist/schemas/PaletteSwitcherSchema.d.ts.map +1 -0
- package/dist/schemas/ProductCardSchema.d.ts +39 -0
- package/dist/schemas/ProductCardSchema.d.ts.map +1 -0
- package/dist/schemas/SafeSpanSchema.d.ts +13 -0
- package/dist/schemas/SafeSpanSchema.d.ts.map +1 -0
- package/dist/schemas/SectionSchema.d.ts +17 -0
- package/dist/schemas/SectionSchema.d.ts.map +1 -0
- package/dist/schemas/SelectInputFieldSchema.d.ts +27 -0
- package/dist/schemas/SelectInputFieldSchema.d.ts.map +1 -0
- package/dist/schemas/TextInputFieldSchema.d.ts +22 -0
- package/dist/schemas/TextInputFieldSchema.d.ts.map +1 -0
- package/dist/schemas/ThemeSwitcherSchema.d.ts +19 -0
- package/dist/schemas/ThemeSwitcherSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +33 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/types.d.ts +7 -0
- package/dist/schemas/types.d.ts.map +1 -0
- package/dist/templates/TemplateResolver.d.ts +52 -0
- package/dist/templates/TemplateResolver.d.ts.map +1 -0
- package/dist/templates/index.d.ts +7 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/tests/ConsoleWarningTest.d.ts +5 -0
- package/dist/tests/ConsoleWarningTest.d.ts.map +1 -0
- package/dist/tests/StorageKeyTest.d.ts +6 -0
- package/dist/tests/StorageKeyTest.d.ts.map +1 -0
- package/dist/tests/ThemeStorageKeyTest.d.ts +6 -0
- package/dist/tests/ThemeStorageKeyTest.d.ts.map +1 -0
- package/dist/types/CacheProvider.d.ts +18 -0
- package/dist/types/CacheProvider.d.ts.map +1 -0
- package/dist/types/ContentProxy.d.ts +47 -0
- package/dist/types/ContentProxy.d.ts.map +1 -0
- package/dist/types/DataBinding.d.ts +7 -0
- package/dist/types/DataBinding.d.ts.map +1 -0
- package/dist/types/DataProvider.d.ts +7 -0
- package/dist/types/DataProvider.d.ts.map +1 -0
- package/dist/types/DataTypes.d.ts +185 -0
- package/dist/types/DataTypes.d.ts.map +1 -0
- package/dist/types/TemplateProvider.d.ts +10 -0
- package/dist/types/TemplateProvider.d.ts.map +1 -0
- package/dist/types/TemplateResolver.d.ts +23 -0
- package/dist/types/TemplateResolver.d.ts.map +1 -0
- package/dist/types/index.d.ts +81 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/breakpoints.d.ts +35 -0
- package/dist/utils/breakpoints.d.ts.map +1 -0
- package/dist/utils/customPaletteManager.d.ts +8 -0
- package/dist/utils/customPaletteManager.d.ts.map +1 -0
- package/dist/utils/dimensions.d.ts +34 -0
- package/dist/utils/dimensions.d.ts.map +1 -0
- package/dist/utils/htmlTransform.d.ts +44 -0
- package/dist/utils/htmlTransform.d.ts.map +1 -0
- package/dist/utils/index.d.ts +15 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/paletteUtils.d.ts +38 -0
- package/dist/utils/paletteUtils.d.ts.map +1 -0
- package/dist/utils/persistenceUtils.d.ts +31 -0
- package/dist/utils/persistenceUtils.d.ts.map +1 -0
- package/dist/utils/reactUtils.d.ts +24 -0
- package/dist/utils/reactUtils.d.ts.map +1 -0
- package/dist/utils/spacing.d.ts +34 -0
- package/dist/utils/spacing.d.ts.map +1 -0
- package/dist/utils/themePerformanceMonitor.d.ts +32 -0
- package/dist/utils/themePerformanceMonitor.d.ts.map +1 -0
- package/dist/utils/themeUtils.d.ts +27 -0
- package/dist/utils/themeUtils.d.ts.map +1 -0
- package/package.json +141 -0
- package/src/__tests__/components/Logo.test.js +172 -0
- package/src/__tests__/contexts/DataContext.test.js +505 -0
- package/src/__tests__/contexts/PaletteContext.test.js +115 -0
- package/src/__tests__/contexts/ThemeContext.test.js +123 -0
- package/src/__tests__/utils/paletteUtils.test.js +142 -0
- package/src/__tests__/utils/themeUtils.test.js +142 -0
- package/src/components/AccessibilityChecker.tsx +264 -0
- package/src/components/Html.tsx +191 -0
- package/src/components/Logo.css +217 -0
- package/src/components/Logo.tsx +370 -0
- package/src/components/Markdown.tsx +191 -0
- package/src/components/QwickApp.css +257 -0
- package/src/components/QwickApp.tsx +157 -0
- package/src/components/QwickAppsLogo.tsx +77 -0
- package/src/components/ResponsiveMenu.css +416 -0
- package/src/components/ResponsiveMenu.tsx +310 -0
- package/src/components/SafeSpan.tsx +128 -0
- package/src/components/Scaffold.css +541 -0
- package/src/components/Scaffold.tsx +463 -0
- package/src/components/__tests__/Article.test.tsx +419 -0
- package/src/components/__tests__/Button.test.tsx +702 -0
- package/src/components/__tests__/CardListGrid.test.tsx +478 -0
- package/src/components/__tests__/ChoiceInputField.test.tsx +864 -0
- package/src/components/__tests__/Code.test.tsx +595 -0
- package/src/components/__tests__/Content.integration.test.tsx +193 -0
- package/src/components/__tests__/Content.test.tsx +504 -0
- package/src/components/__tests__/CoverImageHeader.test.tsx +456 -0
- package/src/components/__tests__/FeatureCard.integration.test.tsx +384 -0
- package/src/components/__tests__/FeatureGrid.integration.test.tsx +364 -0
- package/src/components/__tests__/FeatureGrid.test.tsx +494 -0
- package/src/components/__tests__/Footer.test.tsx +544 -0
- package/src/components/__tests__/FormBlock.test.tsx +857 -0
- package/src/components/__tests__/HeroBlock.integration.test.tsx +272 -0
- package/src/components/__tests__/HeroBlock.test.tsx +463 -0
- package/src/components/__tests__/Html.test.tsx +174 -0
- package/src/components/__tests__/HtmlInputField.test.tsx +856 -0
- package/src/components/__tests__/Markdown.test.tsx +233 -0
- package/src/components/__tests__/PageBannerHeader.test.tsx +614 -0
- package/src/components/__tests__/PaletteSwitcher.test.tsx +864 -0
- package/src/components/__tests__/ProductCard.test.tsx +377 -0
- package/src/components/__tests__/SafeSpan.integration.test.tsx +123 -0
- package/src/components/__tests__/SafeSpan.simple.test.tsx +65 -0
- package/src/components/__tests__/SafeSpan.test.tsx +388 -0
- package/src/components/__tests__/Section.integration.test.tsx +288 -0
- package/src/components/__tests__/Section.test.tsx +494 -0
- package/src/components/__tests__/SelectInputField.test.tsx +886 -0
- package/src/components/__tests__/TextInputField.test.tsx +749 -0
- package/src/components/__tests__/ThemeSwitcher.test.tsx +777 -0
- package/src/components/blocks/Article.tsx +194 -0
- package/src/components/blocks/CardListGrid.tsx +132 -0
- package/src/components/blocks/Code.tsx +313 -0
- package/src/components/blocks/Content.tsx +265 -0
- package/src/components/blocks/CoverImageHeader.css +17 -0
- package/src/components/blocks/CoverImageHeader.tsx +435 -0
- package/src/components/blocks/FeatureCard.tsx +321 -0
- package/src/components/blocks/FeatureGrid.tsx +147 -0
- package/src/components/blocks/Footer.tsx +343 -0
- package/src/components/blocks/HeroBlock.tsx +280 -0
- package/src/components/blocks/PageBannerHeader.tsx +471 -0
- package/src/components/blocks/ProductCard.tsx +472 -0
- package/src/components/blocks/Section.tsx +209 -0
- package/src/components/blocks/index.ts +37 -0
- package/src/components/buttons/Button.tsx +233 -0
- package/src/components/buttons/PaletteSwitcher.tsx +268 -0
- package/src/components/buttons/ThemeSwitcher.tsx +283 -0
- package/src/components/buttons/index.ts +11 -0
- package/src/components/forms/FormBlock.tsx +291 -0
- package/src/components/forms/index.ts +7 -0
- package/src/components/index.ts +37 -0
- package/src/components/input/ChoiceInputField.tsx +188 -0
- package/src/components/input/HtmlInputField.tsx +326 -0
- package/src/components/input/SelectInputField.tsx +197 -0
- package/src/components/input/TextField.tsx +47 -0
- package/src/components/input/TextInputField.tsx +144 -0
- package/src/components/input/index.ts +17 -0
- package/src/components/layout/GridCell.tsx +46 -0
- package/src/components/layout/GridCellWrapper.tsx +87 -0
- package/src/components/layout/GridLayout.tsx +169 -0
- package/src/components/layout/index.ts +13 -0
- package/src/components/menu/Menu.tsx +0 -0
- package/src/components/menu/MenuItem.tsx +32 -0
- package/src/components/menu/index.ts +6 -0
- package/src/components/pages/FormPage.tsx +108 -0
- package/src/components/pages/Page.css +460 -0
- package/src/components/pages/Page.tsx +345 -0
- package/src/components/pages/index.ts +11 -0
- package/src/contexts/DataContext.tsx +355 -0
- package/src/contexts/DimensionsContext.tsx +154 -0
- package/src/contexts/PaletteContext.tsx +217 -0
- package/src/contexts/QwickAppContext.tsx +95 -0
- package/src/contexts/ThemeContext.tsx +376 -0
- package/src/contexts/index.ts +9 -0
- package/src/hooks/__tests__/useDataBinding.test.tsx.disabled +229 -0
- package/src/hooks/index.ts +11 -0
- package/src/hooks/useBaseProps.ts +267 -0
- package/src/hooks/useDataBinding.ts +77 -0
- package/src/index.ts +23 -0
- package/src/palettes/PaletteAutumn.css +172 -0
- package/src/palettes/PaletteAutumn.ts +16 -0
- package/src/palettes/PaletteCosmic.css +172 -0
- package/src/palettes/PaletteCosmic.ts +16 -0
- package/src/palettes/PaletteDefault.css +178 -0
- package/src/palettes/PaletteDefault.ts +17 -0
- package/src/palettes/PaletteOcean.css +172 -0
- package/src/palettes/PaletteOcean.ts +16 -0
- package/src/palettes/PaletteSpring.css +160 -0
- package/src/palettes/PaletteSpring.ts +16 -0
- package/src/palettes/PaletteWinter.css +172 -0
- package/src/palettes/PaletteWinter.ts +16 -0
- package/src/palettes/index.css +12 -0
- package/src/palettes/index.ts +29 -0
- package/src/schemas/ActionSchema.ts +140 -0
- package/src/schemas/ArticleSchema.ts +35 -0
- package/src/schemas/ButtonSchema.ts +99 -0
- package/src/schemas/CardListGridSchema.ts +102 -0
- package/src/schemas/ChoiceInputFieldSchema.ts +89 -0
- package/src/schemas/CodeSchema.ts +88 -0
- package/src/schemas/ContentSchema.ts +128 -0
- package/src/schemas/CoverImageHeaderSchema.ts +208 -0
- package/src/schemas/FeatureCardSchema.ts +161 -0
- package/src/schemas/FeatureGridSchema.ts +87 -0
- package/src/schemas/FeatureItemSchema.ts +68 -0
- package/src/schemas/FooterItemSchema.ts +57 -0
- package/src/schemas/FooterSchema.ts +116 -0
- package/src/schemas/FooterSectionSchema.ts +50 -0
- package/src/schemas/FormBlockSchema.ts +102 -0
- package/src/schemas/HeaderActionSchema.ts +83 -0
- package/src/schemas/HeroBlockSchema.ts +149 -0
- package/src/schemas/HtmlInputFieldSchema.ts +88 -0
- package/src/schemas/MetadataItemSchema.ts +35 -0
- package/src/schemas/PageBannerHeaderSchema.ts +206 -0
- package/src/schemas/PaletteSwitcherSchema.ts +66 -0
- package/src/schemas/ProductCardSchema.ts +264 -0
- package/src/schemas/SafeSpanSchema.ts +36 -0
- package/src/schemas/SectionSchema.ts +106 -0
- package/src/schemas/SelectInputFieldSchema.ts +137 -0
- package/src/schemas/TextInputFieldSchema.ts +129 -0
- package/src/schemas/ThemeSwitcherSchema.ts +97 -0
- package/src/schemas/__tests__/builders.test.ts +313 -0
- package/src/schemas/index.ts +34 -0
- package/src/setupTests.js +60 -0
- package/src/stories/Article.stories.tsx +549 -0
- package/src/stories/Button.stories.tsx +498 -0
- package/src/stories/CardListGrid.stories.tsx +539 -0
- package/src/stories/ChoiceInputField.stories.tsx +591 -0
- package/src/stories/Code.stories.tsx +711 -0
- package/src/stories/Content.stories.tsx +463 -0
- package/src/stories/CoverImageHeader.stories.tsx +794 -0
- package/src/stories/DataBinding.advanced.stories.tsx +548 -0
- package/src/stories/DataBinding.stories.tsx +452 -0
- package/src/stories/DataProvider.stories.tsx +1361 -0
- package/src/stories/FeatureCard.stories.tsx +642 -0
- package/src/stories/FeatureGrid.stories.tsx +669 -0
- package/src/stories/Footer.stories.tsx +724 -0
- package/src/stories/FormBlock.stories.tsx +834 -0
- package/src/stories/HeroBlock.stories.tsx +442 -0
- package/src/stories/Html.stories.tsx +264 -0
- package/src/stories/HtmlInputField.stories.tsx +558 -0
- package/src/stories/Introduction.stories.tsx +721 -0
- package/src/stories/LayoutBlocks.stories.tsx +382 -0
- package/src/stories/LayoutSystem.stories.tsx +253 -0
- package/src/stories/Logo.stories.tsx +400 -0
- package/src/stories/Markdown.stories.tsx +349 -0
- package/src/stories/Page.stories.tsx +762 -0
- package/src/stories/PageBannerHeader.stories.tsx +949 -0
- package/src/stories/PaletteSwitcher.stories.tsx +156 -0
- package/src/stories/ProductCard.stories.tsx +504 -0
- package/src/stories/QwickApp.stories.tsx +461 -0
- package/src/stories/ResponsiveMenu.stories.tsx +299 -0
- package/src/stories/SafeSpan.stories.tsx +612 -0
- package/src/stories/Section.stories.tsx +613 -0
- package/src/stories/SelectInputField.stories.tsx +605 -0
- package/src/stories/TextInputField.stories.tsx +526 -0
- package/src/stories/ThemeSwitcher.stories.tsx +170 -0
- package/src/stories/form/FormComponents.stories.tsx +588 -0
- package/src/templates/TemplateResolver.ts +156 -0
- package/src/templates/index.ts +6 -0
- package/src/tests/ConsoleWarningTest.tsx +30 -0
- package/src/tests/StorageKeyTest.tsx +110 -0
- package/src/tests/ThemeStorageKeyTest.tsx +114 -0
- package/src/types/CacheProvider.ts +14 -0
- package/src/types/ContentProxy.ts +99 -0
- package/src/types/DataTypes.ts +196 -0
- package/src/types/TemplateProvider.ts +9 -0
- package/src/types/TemplateResolver.ts +26 -0
- package/src/types/index.ts +99 -0
- package/src/utils/__tests__/createDataDrivenComponent.test.tsx.disabled +193 -0
- package/src/utils/__tests__/htmlTransform.test.tsx +255 -0
- package/src/utils/breakpoints.ts +87 -0
- package/src/utils/customPaletteManager.js +214 -0
- package/src/utils/dimensions.ts +147 -0
- package/src/utils/htmlTransform.tsx +323 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/logger.ts +28 -0
- package/src/utils/paletteUtils.ts +78 -0
- package/src/utils/persistenceUtils.ts +107 -0
- package/src/utils/reactUtils.tsx +37 -0
- package/src/utils/spacing.ts +155 -0
- package/src/utils/themePerformanceMonitor.js +113 -0
- package/src/utils/themeUtils.ts +67 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML Transform Utilities - Shared transformation logic for HTML content
|
|
3
|
+
*
|
|
4
|
+
* Provides configurable HTML element transformation rules to convert
|
|
5
|
+
* standard HTML elements into Framework components.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Box, Typography } from '@mui/material';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import Code from '../components/blocks/Code';
|
|
13
|
+
import Section from '../components/blocks/Section';
|
|
14
|
+
import { Button } from '../components/buttons/Button';
|
|
15
|
+
import SafeSpan from '../components/SafeSpan';
|
|
16
|
+
|
|
17
|
+
export interface TransformRule {
|
|
18
|
+
selector: string;
|
|
19
|
+
transform: (element: Element, key: string) => React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TransformConfig {
|
|
23
|
+
rules: TransformRule[];
|
|
24
|
+
sanitize?: boolean;
|
|
25
|
+
sanitizeOptions?: any;
|
|
26
|
+
fallbackComponent?: (element: Element, key: string) => React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default transformation rules for article/blog content
|
|
31
|
+
*/
|
|
32
|
+
export const defaultArticleRules: TransformRule[] = [
|
|
33
|
+
// Pre + Code blocks → Code component with syntax highlighting
|
|
34
|
+
{
|
|
35
|
+
selector: 'pre',
|
|
36
|
+
transform: (element: Element, key: string) => {
|
|
37
|
+
const codeChild = element.querySelector('code');
|
|
38
|
+
if (!codeChild) return null;
|
|
39
|
+
|
|
40
|
+
const language = Array.from(codeChild.classList)
|
|
41
|
+
.find(cls => cls.startsWith('language-'))
|
|
42
|
+
?.replace('language-', '') || 'text';
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Box key={key} sx={{ my: 1.5 }}>
|
|
46
|
+
<Code
|
|
47
|
+
language={language}
|
|
48
|
+
showCopy={true}
|
|
49
|
+
showLineNumbers={false}
|
|
50
|
+
>
|
|
51
|
+
{codeChild.textContent || ''}
|
|
52
|
+
</Code>
|
|
53
|
+
</Box>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// Standalone complex code blocks → Code component
|
|
59
|
+
{
|
|
60
|
+
selector: 'code',
|
|
61
|
+
transform: (element: Element, key: string) => {
|
|
62
|
+
// Skip if inside pre (already handled above)
|
|
63
|
+
if (element.closest('pre')) return null;
|
|
64
|
+
|
|
65
|
+
const text = element.textContent || '';
|
|
66
|
+
const hasMultipleLines = text.includes('\n');
|
|
67
|
+
const hasComplexContent = element.children.length > 0;
|
|
68
|
+
|
|
69
|
+
// Check if code is in an inline context (would violate DOM nesting rules)
|
|
70
|
+
const inlineParents = ['p', 'span', 'a', 'strong', 'em', 'b', 'i', 'u', 'small'];
|
|
71
|
+
const isInInlineContext = inlineParents.some(tag => element.closest(tag));
|
|
72
|
+
|
|
73
|
+
if ((hasMultipleLines || hasComplexContent) && !isInInlineContext) {
|
|
74
|
+
return (
|
|
75
|
+
<Box key={key} sx={{ my: 1.5 }}>
|
|
76
|
+
<Code
|
|
77
|
+
language="text"
|
|
78
|
+
showCopy={true}
|
|
79
|
+
showLineNumbers={false}
|
|
80
|
+
>
|
|
81
|
+
{text}
|
|
82
|
+
</Code>
|
|
83
|
+
</Box>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return null; // Let default handling take over
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Blog sections → Section component
|
|
92
|
+
{
|
|
93
|
+
selector: 'section.blog-section',
|
|
94
|
+
transform: (element: Element, key: string) => {
|
|
95
|
+
const children = Array.from(element.children);
|
|
96
|
+
const title = element.querySelector('h2')?.textContent || '';
|
|
97
|
+
const content = children.filter(child => child.tagName !== 'H2');
|
|
98
|
+
const spacing = element.getAttribute('data-padding') || 'none';
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<Section key={key} padding={spacing as any}>
|
|
102
|
+
<Box sx={{ maxWidth: 'lg', mx: 'auto' }}>
|
|
103
|
+
{title && (
|
|
104
|
+
<Typography variant="h4" component="h2" sx={{ mb: 2 }}>
|
|
105
|
+
{title}
|
|
106
|
+
</Typography>
|
|
107
|
+
)}
|
|
108
|
+
<Box>
|
|
109
|
+
{content.map((child, index) =>
|
|
110
|
+
transformElement(child, `${key}-${index}`, { rules: defaultArticleRules })
|
|
111
|
+
)}
|
|
112
|
+
</Box>
|
|
113
|
+
</Box>
|
|
114
|
+
</Section>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// Button elements → Button component
|
|
120
|
+
{
|
|
121
|
+
selector: 'button',
|
|
122
|
+
transform: (element: Element, key: string) => {
|
|
123
|
+
const text = element.textContent || '';
|
|
124
|
+
const variant = element.getAttribute('data-variant') || 'contained';
|
|
125
|
+
const disabled = element.hasAttribute('disabled');
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<Button
|
|
129
|
+
key={key}
|
|
130
|
+
variant={variant as any}
|
|
131
|
+
disabled={disabled}
|
|
132
|
+
>
|
|
133
|
+
{text}
|
|
134
|
+
</Button>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Transform rules optimized for Markdown content
|
|
142
|
+
*/
|
|
143
|
+
export const defaultMarkdownRules: TransformRule[] = [
|
|
144
|
+
// Pre + Code blocks → Code component (same as article)
|
|
145
|
+
{
|
|
146
|
+
selector: 'pre',
|
|
147
|
+
transform: (element: Element, key: string) => {
|
|
148
|
+
const codeChild = element.querySelector('code');
|
|
149
|
+
if (!codeChild) return null;
|
|
150
|
+
|
|
151
|
+
const language = Array.from(codeChild.classList)
|
|
152
|
+
.find(cls => cls.startsWith('language-'))
|
|
153
|
+
?.replace('language-', '') || 'text';
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<Box key={key} sx={{ my: 1.5 }}>
|
|
157
|
+
<Code
|
|
158
|
+
language={language}
|
|
159
|
+
showCopy={true}
|
|
160
|
+
showLineNumbers={false}
|
|
161
|
+
>
|
|
162
|
+
{codeChild.textContent || ''}
|
|
163
|
+
</Code>
|
|
164
|
+
</Box>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
// Inline code → preserve as regular code element (no transformation)
|
|
170
|
+
{
|
|
171
|
+
selector: 'code',
|
|
172
|
+
transform: (element: Element, key: string) => {
|
|
173
|
+
// Skip if inside pre (already handled above)
|
|
174
|
+
if (element.closest('pre')) return null;
|
|
175
|
+
|
|
176
|
+
// For Markdown, keep inline code as-is
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Default fallback component - renders element as-is with SafeSpan content
|
|
184
|
+
*/
|
|
185
|
+
export const defaultFallback = (element: Element, key: string): React.ReactNode => {
|
|
186
|
+
const tagName = element.tagName.toLowerCase();
|
|
187
|
+
|
|
188
|
+
// Check if this is a void element (self-closing)
|
|
189
|
+
const voidElements = new Set([
|
|
190
|
+
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
|
|
191
|
+
'link', 'meta', 'param', 'source', 'track', 'wbr'
|
|
192
|
+
]);
|
|
193
|
+
|
|
194
|
+
const props = {
|
|
195
|
+
key,
|
|
196
|
+
...(element.className ? { className: element.className } : {}),
|
|
197
|
+
...(element.id ? { id: element.id } : {}),
|
|
198
|
+
...Object.fromEntries(
|
|
199
|
+
Array.from(element.attributes)
|
|
200
|
+
.filter(attr => !['class', 'id'].includes(attr.name))
|
|
201
|
+
.map(attr => [attr.name, attr.value])
|
|
202
|
+
)
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
if (voidElements.has(tagName)) {
|
|
206
|
+
// Void elements can't have children
|
|
207
|
+
return React.createElement(tagName, props);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Regular elements with content
|
|
211
|
+
return React.createElement(
|
|
212
|
+
tagName,
|
|
213
|
+
props,
|
|
214
|
+
React.createElement(SafeSpan, { html: element.innerHTML })
|
|
215
|
+
);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Check if an element needs recursive processing
|
|
220
|
+
*/
|
|
221
|
+
function needsRecursiveTransform(element: Element, rules: TransformRule[]): boolean {
|
|
222
|
+
const children = Array.from(element.children);
|
|
223
|
+
|
|
224
|
+
return children.some(child => {
|
|
225
|
+
// Check if any rule applies to this child
|
|
226
|
+
const matchingRule = rules.find(rule => child.matches(rule.selector));
|
|
227
|
+
if (matchingRule) return true;
|
|
228
|
+
|
|
229
|
+
// Check if child has transformable descendants
|
|
230
|
+
return rules.some(rule => child.querySelector(rule.selector));
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Transform a single HTML element to React component
|
|
236
|
+
*/
|
|
237
|
+
export function transformElement(
|
|
238
|
+
element: Element,
|
|
239
|
+
key: string,
|
|
240
|
+
config: TransformConfig = { rules: defaultArticleRules }
|
|
241
|
+
): React.ReactNode {
|
|
242
|
+
const { rules, fallbackComponent = defaultFallback } = config;
|
|
243
|
+
|
|
244
|
+
// Try to find a matching rule for this element
|
|
245
|
+
const matchingRule = rules.find(rule => element.matches(rule.selector));
|
|
246
|
+
if (matchingRule) {
|
|
247
|
+
const result = matchingRule.transform(element, key);
|
|
248
|
+
if (result !== null) return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Check if this element needs recursive processing
|
|
252
|
+
if (needsRecursiveTransform(element, rules)) {
|
|
253
|
+
const children = Array.from(element.children);
|
|
254
|
+
const tagName = element.tagName.toLowerCase();
|
|
255
|
+
|
|
256
|
+
const transformedChildren = children.map((child, index) =>
|
|
257
|
+
transformElement(child, `${key}-${index}`, config)
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
return React.createElement(
|
|
261
|
+
tagName,
|
|
262
|
+
{
|
|
263
|
+
key,
|
|
264
|
+
...(element.className ? { className: element.className } : {}),
|
|
265
|
+
...(element.id ? { id: element.id } : {}),
|
|
266
|
+
...Object.fromEntries(
|
|
267
|
+
Array.from(element.attributes)
|
|
268
|
+
.filter(attr => !['class', 'id'].includes(attr.name))
|
|
269
|
+
.map(attr => [attr.name, attr.value])
|
|
270
|
+
)
|
|
271
|
+
},
|
|
272
|
+
...transformedChildren
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// No transformation needed - use fallback
|
|
277
|
+
return fallbackComponent(element, key);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Transform HTML string to React components
|
|
282
|
+
*/
|
|
283
|
+
export function transformHtmlToReact(
|
|
284
|
+
html: string,
|
|
285
|
+
config: TransformConfig = { rules: defaultArticleRules }
|
|
286
|
+
): React.ReactNode[] {
|
|
287
|
+
if (!html.trim()) return [];
|
|
288
|
+
|
|
289
|
+
const parser = new DOMParser();
|
|
290
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
291
|
+
|
|
292
|
+
return Array.from(doc.body.children).map((element, index) =>
|
|
293
|
+
transformElement(element, index.toString(), config)
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Strip header elements from HTML content (for articles)
|
|
299
|
+
*/
|
|
300
|
+
export function stripHeaderFromContent(html: string): string {
|
|
301
|
+
const parser = new DOMParser();
|
|
302
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
303
|
+
|
|
304
|
+
// Remove header elements that are handled by PageBannerHeader
|
|
305
|
+
const elementsToRemove = [
|
|
306
|
+
'header.blog-header',
|
|
307
|
+
'.blog-header',
|
|
308
|
+
'header[class*="blog"]',
|
|
309
|
+
];
|
|
310
|
+
|
|
311
|
+
elementsToRemove.forEach(selector => {
|
|
312
|
+
const elements = doc.querySelectorAll(selector);
|
|
313
|
+
elements.forEach(el => el.remove());
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// Remove standalone h1 if it's the first child and looks like a title
|
|
317
|
+
const firstChild = doc.body.firstElementChild;
|
|
318
|
+
if (firstChild && firstChild.tagName === 'H1') {
|
|
319
|
+
firstChild.remove();
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return doc.body.innerHTML;
|
|
323
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions and types for QwickApps React Framework
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
export * from './customPaletteManager';
|
|
7
|
+
export * from './dimensions';
|
|
8
|
+
export * from './logger';
|
|
9
|
+
export * from './paletteUtils';
|
|
10
|
+
export * from './persistenceUtils';
|
|
11
|
+
export * from './reactUtils';
|
|
12
|
+
export * from './spacing';
|
|
13
|
+
export * from './themePerformanceMonitor';
|
|
14
|
+
export * from './themeUtils';
|
|
15
|
+
|
|
16
|
+
// Old data binding utilities removed - using new schema system in schemas/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QwickApps React Framework - Logger Utility
|
|
3
|
+
*
|
|
4
|
+
* Re-exports from @qwickapps/logging with framework-specific loggers
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Re-export everything from the logging package
|
|
10
|
+
export * from '@qwickapps/logging';
|
|
11
|
+
|
|
12
|
+
// Import createLogger and Logger type to create framework-specific loggers
|
|
13
|
+
import { createLogger, Logger } from '@qwickapps/logging';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Framework-specific loggers
|
|
17
|
+
*/
|
|
18
|
+
export const loggers: Record<string, Logger> = {
|
|
19
|
+
scaffold: createLogger('Scaffold'),
|
|
20
|
+
navigation: createLogger('Navigation'),
|
|
21
|
+
auth: createLogger('Auth'),
|
|
22
|
+
theme: createLogger('Theme'),
|
|
23
|
+
palette: createLogger('Palette'),
|
|
24
|
+
form: createLogger('Form'),
|
|
25
|
+
layout: createLogger('Layout'),
|
|
26
|
+
menu: createLogger('Menu'),
|
|
27
|
+
router: createLogger('Router'),
|
|
28
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Palette utilities for QwickApps Theme System
|
|
2
|
+
|
|
3
|
+
import { PaletteConfig } from '../contexts/PaletteContext';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Available palette options
|
|
7
|
+
*/
|
|
8
|
+
export const AVAILABLE_PALETTES: PaletteConfig[] = [
|
|
9
|
+
{ id: 'default', name: 'Default', description: 'Classic blue and neutral colors', primaryColor: '#007bff' },
|
|
10
|
+
{ id: 'winter', name: 'Winter', description: 'Cool blues and icy whites', primaryColor: '#0077be' },
|
|
11
|
+
{ id: 'autumn', name: 'Autumn', description: 'Warm oranges and golden yellows', primaryColor: '#ea580c' },
|
|
12
|
+
{ id: 'spring', name: 'Spring', description: 'Fresh greens and soft pinks', primaryColor: '#16a34a' },
|
|
13
|
+
{ id: 'ocean', name: 'Ocean', description: 'Deep blues and aqua teals', primaryColor: '#0891b2' }
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get the current palette from CSS variables
|
|
18
|
+
*/
|
|
19
|
+
export const getCurrentPalette = (): string => {
|
|
20
|
+
const root = document.documentElement;
|
|
21
|
+
return root.getAttribute('data-palette') || 'default';
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Set palette and update CSS variables
|
|
26
|
+
*/
|
|
27
|
+
export const setPalette = (palette: string): void => {
|
|
28
|
+
const root = document.documentElement;
|
|
29
|
+
root.setAttribute('data-palette', palette);
|
|
30
|
+
|
|
31
|
+
// Trigger custom event for palette change
|
|
32
|
+
window.dispatchEvent(new CustomEvent('paletteChange', { detail: { palette } }));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get palette display name
|
|
37
|
+
*/
|
|
38
|
+
export const getPaletteName = (paletteId: string): string => {
|
|
39
|
+
const palette = AVAILABLE_PALETTES.find(p => p.id === paletteId);
|
|
40
|
+
return palette ? palette.name : paletteId;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get palette configuration by ID
|
|
45
|
+
*/
|
|
46
|
+
export const getPaletteConfig = (paletteId: string): PaletteConfig | undefined => {
|
|
47
|
+
return AVAILABLE_PALETTES.find(p => p.id === paletteId);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Initialize palette system
|
|
52
|
+
*/
|
|
53
|
+
export const initializePalette = (): void => {
|
|
54
|
+
const savedPalette = localStorage.getItem('palette') || 'default';
|
|
55
|
+
setPalette(savedPalette);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Save palette preference to localStorage
|
|
60
|
+
*/
|
|
61
|
+
export const savePalettePreference = (palette: string): void => {
|
|
62
|
+
localStorage.setItem('palette', palette);
|
|
63
|
+
setPalette(palette);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get CSS custom property value
|
|
68
|
+
*/
|
|
69
|
+
export const getCSSVariable = (property: string): string => {
|
|
70
|
+
return getComputedStyle(document.documentElement).getPropertyValue(property).trim();
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Set CSS custom property value
|
|
75
|
+
*/
|
|
76
|
+
export const setCSSVariable = (property: string, value: string): void => {
|
|
77
|
+
document.documentElement.style.setProperty(property, value);
|
|
78
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence utilities for theme and palette preferences
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ThemeMode } from '../contexts/ThemeContext';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Load user theme preference from localStorage
|
|
11
|
+
*/
|
|
12
|
+
export const loadUserThemePreference = (storageKey: string | null): ThemeMode | null => {
|
|
13
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const saved = localStorage.getItem(storageKey) as ThemeMode;
|
|
19
|
+
if (saved && ['light', 'dark', 'system'].includes(saved)) {
|
|
20
|
+
return saved;
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.warn('[persistenceUtils] Theme localStorage read failed:', error);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Save user theme preference to localStorage
|
|
31
|
+
*/
|
|
32
|
+
export const saveUserThemePreference = (storageKey: string | null, theme: ThemeMode): void => {
|
|
33
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
localStorage.setItem(storageKey, theme);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.warn('[persistenceUtils] Theme localStorage write failed:', error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Clear user theme preference from localStorage
|
|
46
|
+
*/
|
|
47
|
+
export const clearUserThemePreference = (storageKey: string | null): void => {
|
|
48
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
localStorage.removeItem(storageKey);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn('[persistenceUtils] Theme localStorage clear failed:', error);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Load user palette preference from localStorage
|
|
61
|
+
*/
|
|
62
|
+
export const loadUserPalettePreference = (storageKey: string | null, availablePalettes: string[]): string | null => {
|
|
63
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const saved = localStorage.getItem(storageKey);
|
|
69
|
+
if (saved && availablePalettes.includes(saved)) {
|
|
70
|
+
return saved;
|
|
71
|
+
}
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.warn('[persistenceUtils] Palette localStorage read failed:', error);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Save user palette preference to localStorage
|
|
81
|
+
*/
|
|
82
|
+
export const saveUserPalettePreference = (storageKey: string | null, palette: string): void => {
|
|
83
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
localStorage.setItem(storageKey, palette);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.warn('[persistenceUtils] Palette localStorage write failed:', error);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Clear user palette preference from localStorage
|
|
96
|
+
*/
|
|
97
|
+
export const clearUserPalettePreference = (storageKey: string | null): void => {
|
|
98
|
+
if (!storageKey || typeof window === 'undefined') {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
localStorage.removeItem(storageKey);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.warn('[persistenceUtils] Palette localStorage clear failed:', error);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QwickApps React Framework - React Utilities
|
|
3
|
+
* This module provides utility functions for React components in the QwickApps React Framework.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useLocation, useNavigate } from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
/** Location type for React Router */
|
|
11
|
+
type LocationType = { pathname: string, search: string, hash: string };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Custom hook to get the current location
|
|
15
|
+
* @returns {object | undefined} - The location object if React Router is available, otherwise undefined
|
|
16
|
+
*/
|
|
17
|
+
export const useSafeLocation = (): LocationType | undefined => {
|
|
18
|
+
try {
|
|
19
|
+
return useLocation();
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.warn('React Router context not available:', error);
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Custom hook to get the navigate function
|
|
28
|
+
* @returns {Function | undefined} - The navigate function if React Router is available, otherwise undefined
|
|
29
|
+
*/
|
|
30
|
+
export const useSafeNavigate = (): Function | undefined => {
|
|
31
|
+
try {
|
|
32
|
+
return useNavigate();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.warn('React Router context not available:', error);
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
};
|