@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,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold - Complete application scaffolding system
|
|
3
|
+
*
|
|
4
|
+
* Provides proper Material UI compliant layout scaffolding with:
|
|
5
|
+
* - AppBar with responsive behavior
|
|
6
|
+
* - Navigation rail/drawer with proper item limits
|
|
7
|
+
* - Bottom navigation with 3-5 items
|
|
8
|
+
* - Content area with proper spacing to avoid overlap
|
|
9
|
+
* - Responsive breakpoints following Material Design
|
|
10
|
+
*
|
|
11
|
+
* Material UI Navigation Guidelines:
|
|
12
|
+
* - Bottom Navigation: 3-5 destinations (excess in drawer)
|
|
13
|
+
* - Navigation Rail: 3-7 destinations (excess in drawer)
|
|
14
|
+
* - Navigation Drawer: All items, organized by priority
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import React, { useState, useEffect } from 'react';
|
|
20
|
+
import { useQwickApp } from '../contexts/QwickAppContext';
|
|
21
|
+
import Logo from './Logo';
|
|
22
|
+
import ThemeSwitcher from './buttons/ThemeSwitcher';
|
|
23
|
+
import PaletteSwitcher from './buttons/PaletteSwitcher';
|
|
24
|
+
import { RadioButtonUnchecked as DefaultIcon } from '@mui/icons-material';
|
|
25
|
+
import './Scaffold.css';
|
|
26
|
+
import { useSafeLocation, useSafeNavigate } from '../utils/reactUtils';
|
|
27
|
+
import { loggers } from '../utils/logger';
|
|
28
|
+
import type { MenuItem } from './menu/MenuItem';
|
|
29
|
+
|
|
30
|
+
const logger = loggers.scaffold;
|
|
31
|
+
|
|
32
|
+
export interface AppBarProps {
|
|
33
|
+
/** Title to display in the app bar */
|
|
34
|
+
title?: string;
|
|
35
|
+
/** Actions to display on the right side */
|
|
36
|
+
actions?: React.ReactNode;
|
|
37
|
+
/** Whether to show the menu button (for drawer toggle) */
|
|
38
|
+
showMenuButton?: boolean;
|
|
39
|
+
/** Custom logo override */
|
|
40
|
+
logo?: React.ReactNode;
|
|
41
|
+
/** Logo position when in app bar */
|
|
42
|
+
logoPosition?: 'left' | 'center';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ScaffoldProps {
|
|
46
|
+
/** Child components (page content) */
|
|
47
|
+
children: React.ReactNode;
|
|
48
|
+
/** Primary navigation items */
|
|
49
|
+
navigationItems: MenuItem[];
|
|
50
|
+
/** App bar configuration */
|
|
51
|
+
appBar?: AppBarProps;
|
|
52
|
+
/** Additional CSS class */
|
|
53
|
+
className?: string;
|
|
54
|
+
/** Whether to show app bar (default: true) */
|
|
55
|
+
showAppBar?: boolean;
|
|
56
|
+
/** Custom app bar height (default: 64px) */
|
|
57
|
+
appBarHeight?: number;
|
|
58
|
+
/** Application name for display purposes */
|
|
59
|
+
appName?: string;
|
|
60
|
+
/** Whether to show theme switcher in app bar (default: false) */
|
|
61
|
+
showThemeSwitcher?: boolean;
|
|
62
|
+
/** Whether to show palette switcher in app bar (default: false) */
|
|
63
|
+
showPaletteSwitcher?: boolean;
|
|
64
|
+
/** Callback when logo is clicked */
|
|
65
|
+
onLogoClick?: () => void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type ScreenSize = 'mobile' | 'tablet' | 'desktop';
|
|
69
|
+
|
|
70
|
+
// Material UI breakpoints
|
|
71
|
+
const BREAKPOINTS = {
|
|
72
|
+
mobile: 600, // < 600px
|
|
73
|
+
tablet: 1024, // 600px - 1024px
|
|
74
|
+
desktop: 1024, // > 1024px
|
|
75
|
+
} as const;
|
|
76
|
+
|
|
77
|
+
const Scaffold: React.FC<ScaffoldProps> = ({
|
|
78
|
+
children,
|
|
79
|
+
navigationItems = [],
|
|
80
|
+
appBar,
|
|
81
|
+
className = '',
|
|
82
|
+
showAppBar = true,
|
|
83
|
+
appBarHeight = 64,
|
|
84
|
+
appName: propAppName,
|
|
85
|
+
showThemeSwitcher = false,
|
|
86
|
+
showPaletteSwitcher = false,
|
|
87
|
+
onLogoClick,
|
|
88
|
+
}) => {
|
|
89
|
+
const [screenSize, setScreenSize] = useState<ScreenSize>('desktop');
|
|
90
|
+
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
|
91
|
+
const [isRailExpanded, setIsRailExpanded] = useState(false);
|
|
92
|
+
// Use navigation items directly since Page no longer provides menu items
|
|
93
|
+
const combinedMenuItems = navigationItems;
|
|
94
|
+
|
|
95
|
+
// React Router hooks (if available)
|
|
96
|
+
const location = useSafeLocation();
|
|
97
|
+
const navigate = useSafeNavigate();
|
|
98
|
+
const currentPath = location?.pathname;
|
|
99
|
+
|
|
100
|
+
// Debug logging for navigation
|
|
101
|
+
React.useEffect(() => {
|
|
102
|
+
if (currentPath) {
|
|
103
|
+
logger.debug('Current path changed to:', currentPath);
|
|
104
|
+
}
|
|
105
|
+
}, [currentPath]);
|
|
106
|
+
|
|
107
|
+
const { appName: contextAppName, logo: contextLogo } = useQwickApp();
|
|
108
|
+
const appName = propAppName || contextAppName;
|
|
109
|
+
|
|
110
|
+
// Page context integration is simplified - only used for route detection if needed
|
|
111
|
+
// Page-specific menu items and actions are now handled by header components
|
|
112
|
+
|
|
113
|
+
// Determine current screen size using Material UI breakpoints
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
const updateScreenSize = () => {
|
|
116
|
+
const width = window.innerWidth;
|
|
117
|
+
if (width < BREAKPOINTS.mobile) {
|
|
118
|
+
setScreenSize('mobile');
|
|
119
|
+
} else if (width <= BREAKPOINTS.tablet) {
|
|
120
|
+
setScreenSize('tablet');
|
|
121
|
+
} else {
|
|
122
|
+
setScreenSize('desktop');
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
updateScreenSize();
|
|
127
|
+
window.addEventListener('resize', updateScreenSize);
|
|
128
|
+
return () => window.removeEventListener('resize', updateScreenSize);
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
// Page context now only contains route information
|
|
132
|
+
// Page-specific actions and menu items are handled by header components
|
|
133
|
+
|
|
134
|
+
// Sort items by priority
|
|
135
|
+
const sortedItems = [...combinedMenuItems].sort((a, b) => (a.priority || 999) - (b.priority || 999));
|
|
136
|
+
|
|
137
|
+
// Material UI Guidelines: Split items based on screen size
|
|
138
|
+
const getNavigationSplit = () => {
|
|
139
|
+
switch (screenSize) {
|
|
140
|
+
case 'mobile':
|
|
141
|
+
// Bottom Nav: 3-5 items, rest in drawer
|
|
142
|
+
const bottomNavItems = sortedItems.slice(0, 5);
|
|
143
|
+
const drawerItems = sortedItems.slice(5);
|
|
144
|
+
return { primaryItems: bottomNavItems, drawerItems };
|
|
145
|
+
|
|
146
|
+
case 'tablet':
|
|
147
|
+
// Nav Rail: 3-7 items, rest in drawer
|
|
148
|
+
const railItems = sortedItems.slice(0, 7);
|
|
149
|
+
const railDrawerItems = sortedItems.slice(7);
|
|
150
|
+
return { primaryItems: railItems, drawerItems: railDrawerItems };
|
|
151
|
+
|
|
152
|
+
case 'desktop':
|
|
153
|
+
// App Bar: 5-7 items, rest in drawer
|
|
154
|
+
const appBarItems = sortedItems.slice(0, 7);
|
|
155
|
+
const appBarDrawerItems = sortedItems.slice(7);
|
|
156
|
+
return { primaryItems: appBarItems, drawerItems: appBarDrawerItems };
|
|
157
|
+
|
|
158
|
+
default:
|
|
159
|
+
return { primaryItems: sortedItems, drawerItems: [] };
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const { primaryItems, drawerItems } = getNavigationSplit();
|
|
164
|
+
|
|
165
|
+
// Enhanced app bar configuration with page integration
|
|
166
|
+
const enhancedAppBar = React.useMemo(() => {
|
|
167
|
+
const baseAppBar = appBar || {};
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
...baseAppBar,
|
|
171
|
+
title: baseAppBar.title || appName,
|
|
172
|
+
actions: baseAppBar.actions,
|
|
173
|
+
};
|
|
174
|
+
}, [appBar, appName]);
|
|
175
|
+
|
|
176
|
+
// Get the logo to display
|
|
177
|
+
const displayLogo = enhancedAppBar?.logo || contextLogo || <Logo name={enhancedAppBar?.title || appName} size="small" />;
|
|
178
|
+
|
|
179
|
+
// Toggle drawer
|
|
180
|
+
const toggleDrawer = () => {
|
|
181
|
+
setIsDrawerOpen(!isDrawerOpen);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Toggle rail expansion (tablet only)
|
|
185
|
+
const toggleRail = () => {
|
|
186
|
+
setIsRailExpanded(!isRailExpanded);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// Render menu item with proper touch targets (48px minimum)
|
|
190
|
+
const renderMenuItem = (item: MenuItem, variant: 'bottom' | 'rail' | 'appbar' | 'drawer' = 'appbar') => {
|
|
191
|
+
// Determine if this item is active
|
|
192
|
+
const isActiveItem = item.active ||
|
|
193
|
+
(item.route && currentPath === item.route) ||
|
|
194
|
+
(!item.active && !item.route && currentPath && currentPath === `/${item.id}`);
|
|
195
|
+
|
|
196
|
+
// Debug logging for route matching
|
|
197
|
+
if (item.route) {
|
|
198
|
+
logger.debug(`Route matching for ${item.id}: ${currentPath} === ${item.route} = ${isActiveItem}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Handle click - automatic navigation if no onClick provided
|
|
202
|
+
const handleClick = () => {
|
|
203
|
+
if (item.disabled) return;
|
|
204
|
+
|
|
205
|
+
// Enhanced same-route detection
|
|
206
|
+
const isSameRoute = isActiveItem && item.route === currentPath;
|
|
207
|
+
|
|
208
|
+
if (isSameRoute) {
|
|
209
|
+
logger.debug(`Navigation prevented: Already on route ${item.route}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (item.onClick) {
|
|
214
|
+
try {
|
|
215
|
+
item.onClick();
|
|
216
|
+
} catch (error) {
|
|
217
|
+
logger.error('Menu item onClick error:', error);
|
|
218
|
+
}
|
|
219
|
+
} else if (item.route) {
|
|
220
|
+
if (navigate === undefined) {
|
|
221
|
+
logger.error('No navigation function available! Cannot navigate to:', item.route);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Robust navigation with comprehensive error handling
|
|
225
|
+
try {
|
|
226
|
+
logger.debug(`Navigating from ${currentPath} to ${item.route}`);
|
|
227
|
+
|
|
228
|
+
// Additional safety check to prevent same-route navigation
|
|
229
|
+
if (currentPath && currentPath === item.route) {
|
|
230
|
+
logger.debug('Final check: Same route detected, skipping navigation');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Perform navigation with React Router v6
|
|
235
|
+
navigate(item.route);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
238
|
+
logger.error('Navigation error caught:', error);
|
|
239
|
+
logger.error('Navigation context:', {
|
|
240
|
+
from: currentPath,
|
|
241
|
+
to: item.route,
|
|
242
|
+
isActiveItem,
|
|
243
|
+
itemId: item.id,
|
|
244
|
+
errorMessage
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Fallback: use window.location for critical navigation
|
|
248
|
+
if (item.route && item.route !== currentPath) {
|
|
249
|
+
try {
|
|
250
|
+
logger.debug('Attempting fallback navigation using window.location');
|
|
251
|
+
window.location.pathname = item.route;
|
|
252
|
+
} catch (fallbackError) {
|
|
253
|
+
logger.error('Fallback navigation also failed:', fallbackError);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// For primary navigation (bottom, rail, appbar), enforce icon requirement
|
|
261
|
+
const needsIcon = variant !== 'drawer';
|
|
262
|
+
const displayIcon = item.icon || (needsIcon ? <DefaultIcon /> : null);
|
|
263
|
+
|
|
264
|
+
const content = (
|
|
265
|
+
<>
|
|
266
|
+
{displayIcon && (
|
|
267
|
+
<span className={`menu-item-icon menu-item-icon-${variant}`}>
|
|
268
|
+
{displayIcon}
|
|
269
|
+
</span>
|
|
270
|
+
)}
|
|
271
|
+
<span className={`menu-item-label menu-item-label-${variant}`}>
|
|
272
|
+
{item.label}
|
|
273
|
+
</span>
|
|
274
|
+
{item.badge && (
|
|
275
|
+
<span className="menu-item-badge">{item.badge}</span>
|
|
276
|
+
)}
|
|
277
|
+
</>
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const commonProps = {
|
|
281
|
+
className: `menu-item menu-item-${variant} ${isActiveItem ? 'active' : ''} ${item.disabled ? 'disabled' : ''}`,
|
|
282
|
+
'aria-label': item.label,
|
|
283
|
+
'aria-current': isActiveItem ? 'page' as const : undefined,
|
|
284
|
+
onClick: item.disabled ? undefined : handleClick,
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// External links
|
|
288
|
+
if (item.href && !item.disabled) {
|
|
289
|
+
return (
|
|
290
|
+
<a key={item.id} href={item.href} {...commonProps} target="_blank" rel="noopener noreferrer">
|
|
291
|
+
{content}
|
|
292
|
+
</a>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Internal navigation or custom click handlers
|
|
297
|
+
return (
|
|
298
|
+
<button
|
|
299
|
+
key={item.id}
|
|
300
|
+
type="button"
|
|
301
|
+
{...commonProps}
|
|
302
|
+
disabled={Boolean(item.disabled || (isActiveItem && item.route === currentPath))}
|
|
303
|
+
>
|
|
304
|
+
{content}
|
|
305
|
+
</button>
|
|
306
|
+
);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// Calculate layout spacing
|
|
310
|
+
const getLayoutSpacing = () => {
|
|
311
|
+
let paddingTop = showAppBar ? appBarHeight : 0;
|
|
312
|
+
let paddingBottom = 0;
|
|
313
|
+
let paddingLeft = 0;
|
|
314
|
+
|
|
315
|
+
if (screenSize === 'mobile') {
|
|
316
|
+
paddingBottom = 80; // Bottom nav height
|
|
317
|
+
} else if (screenSize === 'tablet') {
|
|
318
|
+
paddingLeft = isRailExpanded ? 280 : 80; // Rail width
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return { paddingTop, paddingBottom, paddingLeft };
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
const layoutSpacing = getLayoutSpacing();
|
|
325
|
+
|
|
326
|
+
const AppLogo = () => {
|
|
327
|
+
return <div
|
|
328
|
+
className="appbar-logo"
|
|
329
|
+
onClick={onLogoClick}
|
|
330
|
+
style={{ cursor: onLogoClick ? 'pointer' : 'default' }}
|
|
331
|
+
>
|
|
332
|
+
{displayLogo}
|
|
333
|
+
</div>
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<div className={`app-scaffold ${className}`}>
|
|
338
|
+
{/* App Bar */}
|
|
339
|
+
{showAppBar && (
|
|
340
|
+
<header
|
|
341
|
+
className="app-scaffold-appbar"
|
|
342
|
+
style={{ height: appBarHeight }}
|
|
343
|
+
>
|
|
344
|
+
<div className="appbar-content">
|
|
345
|
+
{/* Left section */}
|
|
346
|
+
<div className="appbar-left">
|
|
347
|
+
{/* Menu button for drawer (when needed) */}
|
|
348
|
+
{(drawerItems.length > 0 || screenSize === 'tablet') && (
|
|
349
|
+
<button
|
|
350
|
+
type="button"
|
|
351
|
+
className="menu-button"
|
|
352
|
+
onClick={screenSize === 'tablet' ? toggleRail : toggleDrawer}
|
|
353
|
+
aria-label={screenSize === 'tablet' ? 'Toggle navigation rail' : 'Open drawer menu'}
|
|
354
|
+
>
|
|
355
|
+
<span className="hamburger-icon">
|
|
356
|
+
<span></span>
|
|
357
|
+
<span></span>
|
|
358
|
+
<span></span>
|
|
359
|
+
</span>
|
|
360
|
+
</button>
|
|
361
|
+
)}
|
|
362
|
+
|
|
363
|
+
{/* Logo/Title */}
|
|
364
|
+
{(!enhancedAppBar?.logoPosition || enhancedAppBar.logoPosition === 'left') && <AppLogo />}
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
{/* Center section */}
|
|
368
|
+
<div className="appbar-center">
|
|
369
|
+
{enhancedAppBar?.logoPosition === 'center' && <AppLogo />}
|
|
370
|
+
|
|
371
|
+
{/* Desktop navigation items */}
|
|
372
|
+
{screenSize === 'desktop' && (
|
|
373
|
+
<nav className="appbar-navigation">
|
|
374
|
+
{primaryItems.map(item => renderMenuItem(item, 'appbar'))}
|
|
375
|
+
</nav>
|
|
376
|
+
)}
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
{/* Right section */}
|
|
380
|
+
<div className="appbar-right">
|
|
381
|
+
{enhancedAppBar?.actions && (
|
|
382
|
+
<div className="appbar-actions">
|
|
383
|
+
{enhancedAppBar.actions}
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
{/* Theme and Palette Switchers */}
|
|
387
|
+
<div className="appbar-theme-controls">
|
|
388
|
+
{showThemeSwitcher && <ThemeSwitcher />}
|
|
389
|
+
{showPaletteSwitcher && <PaletteSwitcher />}
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
</header>
|
|
394
|
+
)}
|
|
395
|
+
|
|
396
|
+
{/* Navigation Rail (Tablet) */}
|
|
397
|
+
{screenSize === 'tablet' && (
|
|
398
|
+
<nav className={`navigation-rail ${isRailExpanded ? 'expanded' : 'collapsed'}`}>
|
|
399
|
+
<div className="rail-items">
|
|
400
|
+
{primaryItems.map(item => renderMenuItem(item, 'rail'))}
|
|
401
|
+
</div>
|
|
402
|
+
</nav>
|
|
403
|
+
)}
|
|
404
|
+
|
|
405
|
+
{/* Bottom Navigation (Mobile) */}
|
|
406
|
+
{screenSize === 'mobile' && primaryItems.length > 0 && (
|
|
407
|
+
<nav className="bottom-navigation">
|
|
408
|
+
<div className="bottom-nav-items">
|
|
409
|
+
{primaryItems.map(item => renderMenuItem(item, 'bottom'))}
|
|
410
|
+
</div>
|
|
411
|
+
</nav>
|
|
412
|
+
)}
|
|
413
|
+
|
|
414
|
+
{/* Navigation Drawer (Overflow items) */}
|
|
415
|
+
{isDrawerOpen && drawerItems.length > 0 && (
|
|
416
|
+
<div className="drawer-overlay" onClick={toggleDrawer}>
|
|
417
|
+
<nav className="navigation-drawer" onClick={(e) => e.stopPropagation()}>
|
|
418
|
+
<div className="drawer-header">
|
|
419
|
+
<h3>Menu</h3>
|
|
420
|
+
<button
|
|
421
|
+
type="button"
|
|
422
|
+
className="drawer-close"
|
|
423
|
+
onClick={toggleDrawer}
|
|
424
|
+
aria-label="Close drawer"
|
|
425
|
+
>
|
|
426
|
+
×
|
|
427
|
+
</button>
|
|
428
|
+
</div>
|
|
429
|
+
<div className="drawer-items">
|
|
430
|
+
{/* Show all primary items in drawer for consistency */}
|
|
431
|
+
<div className="drawer-section">
|
|
432
|
+
<h4>Navigation</h4>
|
|
433
|
+
{primaryItems.map(item => renderMenuItem(item, 'drawer'))}
|
|
434
|
+
</div>
|
|
435
|
+
|
|
436
|
+
{/* Additional items */}
|
|
437
|
+
{drawerItems.length > 0 && (
|
|
438
|
+
<div className="drawer-section">
|
|
439
|
+
<h4>More</h4>
|
|
440
|
+
{drawerItems.map(item => renderMenuItem(item, 'drawer'))}
|
|
441
|
+
</div>
|
|
442
|
+
)}
|
|
443
|
+
</div>
|
|
444
|
+
</nav>
|
|
445
|
+
</div>
|
|
446
|
+
)}
|
|
447
|
+
|
|
448
|
+
{/* Main Content */}
|
|
449
|
+
<main
|
|
450
|
+
className="app-scaffold-content"
|
|
451
|
+
style={{
|
|
452
|
+
paddingTop: `${layoutSpacing.paddingTop}px`,
|
|
453
|
+
paddingBottom: `${layoutSpacing.paddingBottom}px`,
|
|
454
|
+
paddingLeft: `${layoutSpacing.paddingLeft}px`,
|
|
455
|
+
}}
|
|
456
|
+
>
|
|
457
|
+
{children}
|
|
458
|
+
</main>
|
|
459
|
+
</div>
|
|
460
|
+
);
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
export default Scaffold;
|