@qwickapps/react-framework 1.3.4 → 1.4.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/README.md +1688 -2
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +7 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/Html.d.ts +28 -18
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Logo.d.ts +12 -35
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +18 -13
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/QwickApp.d.ts +16 -3
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/QwickIcon.d.ts +23 -0
- package/dist/components/QwickIcon.d.ts.map +1 -0
- package/dist/components/SafeSpan.d.ts +12 -5
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/Scaffold.d.ts.map +1 -1
- package/dist/components/base/ModelView.d.ts +101 -0
- package/dist/components/base/ModelView.d.ts.map +1 -0
- package/dist/components/base/index.d.ts +11 -0
- package/dist/components/base/index.d.ts.map +1 -0
- package/dist/components/blocks/Article.d.ts +12 -2
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/Code.d.ts +13 -2
- package/dist/components/blocks/Code.d.ts.map +1 -1
- package/dist/components/blocks/Content.d.ts.map +1 -1
- package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
- package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
- package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
- package/dist/components/blocks/Footer.d.ts.map +1 -1
- package/dist/components/blocks/HeroBlock.d.ts +27 -13
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts +41 -0
- package/dist/components/blocks/Image.d.ts.map +1 -0
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
- package/dist/components/blocks/ProductCard.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts +16 -2
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +41 -0
- package/dist/components/blocks/Text.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +4 -0
- package/dist/components/blocks/index.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts +23 -7
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +19 -13
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts +17 -11
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts +17 -11
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/input/SelectInputField.d.ts +16 -10
- package/dist/components/input/SelectInputField.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +16 -10
- package/dist/components/input/SwitchInputField.d.ts.map +1 -1
- package/dist/components/input/TextField.d.ts.map +1 -1
- package/dist/components/input/TextInputField.d.ts +16 -11
- package/dist/components/input/TextInputField.d.ts.map +1 -1
- package/dist/components/layout/GridCell.d.ts +23 -6
- package/dist/components/layout/GridCell.d.ts.map +1 -1
- package/dist/components/layout/GridLayout.d.ts +24 -23
- package/dist/components/layout/GridLayout.d.ts.map +1 -1
- package/dist/components/pages/FormPage.d.ts.map +1 -1
- package/dist/components/pages/Page.d.ts +49 -87
- package/dist/components/pages/Page.d.ts.map +1 -1
- package/dist/components/pages/index.d.ts +2 -2
- package/dist/components/pages/index.d.ts.map +1 -1
- package/dist/config/AppConfig.d.ts +49 -0
- package/dist/config/AppConfig.d.ts.map +1 -0
- package/dist/config/AppConfigBuilder.d.ts +75 -0
- package/dist/config/AppConfigBuilder.d.ts.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/types.d.ts +130 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.esm.js +451 -0
- package/dist/config.js +455 -0
- package/dist/contexts/PrintModeContext.d.ts +27 -0
- package/dist/contexts/PrintModeContext.d.ts.map +1 -0
- package/dist/contexts/QwickAppContext.d.ts +2 -2
- package/dist/contexts/QwickAppContext.d.ts.map +1 -1
- package/dist/contexts/ThemeContext.d.ts.map +1 -1
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/usePrintMode.d.ts +39 -0
- package/dist/hooks/usePrintMode.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +20722 -16021
- package/dist/index.js +20725 -16010
- package/dist/schemas/CodeSchema.d.ts +2 -1
- package/dist/schemas/CodeSchema.d.ts.map +1 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
- package/dist/schemas/ContentSchema.d.ts +2 -1
- package/dist/schemas/ContentSchema.d.ts.map +1 -1
- package/dist/schemas/GridCellSchema.d.ts +25 -0
- package/dist/schemas/GridCellSchema.d.ts.map +1 -0
- package/dist/schemas/GridLayoutSchema.d.ts +23 -0
- package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/HtmlSchema.d.ts +14 -0
- package/dist/schemas/HtmlSchema.d.ts.map +1 -0
- package/dist/schemas/ImageSchema.d.ts +32 -0
- package/dist/schemas/ImageSchema.d.ts.map +1 -0
- package/dist/schemas/LogoSchema.d.ts +35 -0
- package/dist/schemas/LogoSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +14 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/PageTemplateSchema.d.ts +31 -0
- package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
- package/dist/schemas/PrintConfigSchema.d.ts +31 -0
- package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
- package/dist/schemas/SectionSchema.d.ts +2 -1
- package/dist/schemas/SectionSchema.d.ts.map +1 -1
- package/dist/schemas/TextSchema.d.ts +37 -0
- package/dist/schemas/TextSchema.d.ts.map +1 -0
- package/dist/schemas/ViewModelSchema.d.ts +23 -0
- package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +15 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
- package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
- package/dist/schemas/transformers/registry.d.ts +15 -0
- package/dist/schemas/transformers/registry.d.ts.map +1 -0
- package/dist/schemas/types/Serializable.d.ts +46 -0
- package/dist/schemas/types/Serializable.d.ts.map +1 -0
- package/dist/utils/htmlTransform.d.ts.map +1 -1
- package/dist/utils/reactUtils.d.ts +12 -3
- package/dist/utils/reactUtils.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
- package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
- package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
- package/src/__tests__/components/Logo.test.js +3 -3
- package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
- package/src/__tests__/components/base/ModelView.test.tsx +220 -0
- package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
- package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
- package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
- package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
- package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
- package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
- package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
- package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
- package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
- package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
- package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
- package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
- package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
- package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
- package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
- package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
- package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
- package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
- package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
- package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
- package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
- package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
- package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
- package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
- package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
- package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
- package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
- package/src/components/ErrorBoundary.tsx +8 -8
- package/src/components/Html.tsx +147 -44
- package/src/components/Logo.tsx +198 -100
- package/src/components/Markdown.tsx +125 -16
- package/src/components/QwickApp.tsx +64 -31
- package/src/components/QwickIcon.tsx +59 -0
- package/src/components/SafeSpan.tsx +65 -10
- package/src/components/Scaffold.tsx +2 -8
- package/src/components/base/ModelView.tsx +199 -0
- package/src/components/base/index.ts +11 -0
- package/src/components/blocks/Article.tsx +57 -18
- package/src/components/blocks/Code.md +529 -0
- package/src/components/blocks/Code.tsx +102 -15
- package/src/components/blocks/Content.tsx +25 -77
- package/src/components/blocks/CoverImageHeader.tsx +9 -4
- package/src/components/blocks/FeatureCard.tsx +1 -2
- package/src/components/blocks/FeatureGrid.tsx +19 -1
- package/src/components/blocks/Footer.tsx +13 -1
- package/src/components/blocks/HeroBlock.tsx +87 -20
- package/src/components/blocks/Image.tsx +395 -0
- package/src/components/blocks/PageBannerHeader.tsx +14 -12
- package/src/components/blocks/ProductCard.tsx +51 -52
- package/src/components/blocks/Section.tsx +113 -8
- package/src/components/blocks/Text.tsx +285 -0
- package/src/components/blocks/index.ts +4 -0
- package/src/components/buttons/Button.tsx +184 -15
- package/src/components/forms/FormBlock.tsx +70 -17
- package/src/components/index.ts +5 -0
- package/src/components/input/ChoiceInputField.tsx +48 -18
- package/src/components/input/HtmlInputField.tsx +48 -18
- package/src/components/input/SelectInputField.tsx +48 -16
- package/src/components/input/SwitchInputField.tsx +48 -17
- package/src/components/input/TextField.tsx +41 -1
- package/src/components/input/TextInputField.tsx +52 -18
- package/src/components/layout/GridCell.tsx +118 -9
- package/src/components/layout/GridLayout.tsx +125 -24
- package/src/components/pages/FormPage.tsx +0 -1
- package/src/components/pages/Page.css +304 -332
- package/src/components/pages/Page.tsx +307 -255
- package/src/components/pages/index.ts +2 -2
- package/src/config/AppConfig.ts +133 -0
- package/src/config/AppConfigBuilder.ts +421 -0
- package/src/config/__tests__/AppConfig.test.ts +385 -0
- package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
- package/src/config/index.ts +24 -0
- package/src/config/types.ts +170 -0
- package/src/config.ts +25 -0
- package/src/contexts/PrintModeContext.tsx +332 -0
- package/src/contexts/QwickAppContext.tsx +2 -2
- package/src/contexts/ThemeContext.tsx +1 -2
- package/src/contexts/index.ts +2 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/usePrintMode.ts +73 -0
- package/src/index.ts +3 -0
- package/src/schemas/CodeSchema.ts +3 -3
- package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
- package/src/schemas/ContentSchema.ts +2 -1
- package/src/schemas/GridCellSchema.ts +164 -0
- package/src/schemas/GridLayoutSchema.ts +133 -0
- package/src/schemas/HtmlSchema.ts +47 -0
- package/src/schemas/ImageSchema.ts +235 -0
- package/src/schemas/LogoSchema.ts +241 -0
- package/src/schemas/MarkdownSchema.ts +47 -0
- package/src/schemas/PageTemplateSchema.ts +186 -0
- package/src/schemas/PrintConfigSchema.ts +207 -0
- package/src/schemas/README.md +661 -0
- package/src/schemas/SectionSchema.ts +2 -1
- package/src/schemas/TextSchema.ts +329 -0
- package/src/schemas/ViewModelSchema.ts +115 -0
- package/src/schemas/index.ts +21 -2
- package/src/schemas/transformers/ComponentTransformer.ts +403 -0
- package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
- package/src/schemas/transformers/registry.ts +72 -0
- package/src/schemas/types/Serializable.ts +51 -0
- package/src/stories/AccessibilityProvider.stories.tsx +253 -253
- package/src/stories/Article.stories.tsx +433 -433
- package/src/stories/Button.stories.tsx +1 -1
- package/src/stories/CardListGrid.stories.tsx +451 -451
- package/src/stories/ChoiceInputField.stories.tsx +503 -503
- package/src/stories/Code.stories.tsx +1 -1
- package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
- package/src/stories/Content.stories.tsx +393 -393
- package/src/stories/CoverImageHeader.stories.tsx +701 -701
- package/src/stories/DataBinding.advanced.stories.tsx +432 -432
- package/src/stories/DataProvider.stories.tsx +1192 -1192
- package/src/stories/FeatureCard.stories.tsx +557 -557
- package/src/stories/FeatureGrid.stories.tsx +594 -594
- package/src/stories/Footer.stories.tsx +640 -640
- package/src/stories/FormBlock.stories.tsx +760 -760
- package/src/stories/FormComponents.stories.tsx +349 -541
- package/src/stories/GridCell.stories.tsx +417 -0
- package/src/stories/GridLayout.stories.tsx +353 -0
- package/src/stories/HeroBlock.stories.tsx +862 -373
- package/src/stories/HtmlInputField.stories.tsx +474 -474
- package/src/stories/Image.stories.tsx +819 -0
- package/src/stories/Introduction.stories.tsx +667 -667
- package/src/stories/LayoutBlocks.stories.tsx +324 -324
- package/src/stories/Logo.stories.tsx +165 -6
- package/src/stories/Markdown.stories.tsx +137 -137
- package/src/stories/ModelView.stories.tsx +477 -0
- package/src/stories/Page.stories.tsx +688 -688
- package/src/stories/PageBannerHeader.stories.tsx +864 -864
- package/src/stories/PaletteSwitcher.stories.tsx +119 -119
- package/src/stories/ProductCard.stories.tsx +424 -424
- package/src/stories/QwickApp.stories.tsx +368 -368
- package/src/stories/ResponsiveMenu.stories.tsx +249 -249
- package/src/stories/SafeSpan.stories.tsx +531 -531
- package/src/stories/Section.stories.tsx +90 -2
- package/src/stories/SelectInputField.stories.tsx +524 -524
- package/src/stories/Text.stories.tsx +560 -0
- package/src/stories/TextInputField.stories.tsx +443 -443
- package/src/stories/ThemeSwitcher.stories.tsx +123 -123
- package/src/utils/htmlTransform.tsx +74 -53
- package/src/utils/reactUtils.tsx +57 -6
- package/dist/index.bundled.css +0 -12
- /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
- /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
|
@@ -0,0 +1,819 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Component Stories - Comprehensive image display with data binding support
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Box, Divider, Typography, Alert, Paper, Grid } from '@mui/material';
|
|
8
|
+
import { JsonDataProvider } from '@qwickapps/schema';
|
|
9
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
10
|
+
import { Image } from '../components/blocks';
|
|
11
|
+
import { ComponentTransformer } from '../schemas/transformers/ComponentTransformer';
|
|
12
|
+
import { ModelView } from '../components/base/ModelView';
|
|
13
|
+
import QwickApp from '../components/QwickApp';
|
|
14
|
+
import React from 'react';
|
|
15
|
+
|
|
16
|
+
// Sample image URLs for different use cases
|
|
17
|
+
const sampleImages = {
|
|
18
|
+
landscape: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2340&q=80',
|
|
19
|
+
portrait: 'https://images.unsplash.com/photo-1494790108755-2616c57b8a14?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80',
|
|
20
|
+
square: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2340&q=80',
|
|
21
|
+
technology: 'https://images.unsplash.com/photo-1518709268805-4e9042af2176?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2225&q=80',
|
|
22
|
+
product: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
|
|
23
|
+
fallback: 'https://via.placeholder.com/400x300/e0e0e0/666666?text=Fallback+Image'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Sample CMS data for data binding examples
|
|
27
|
+
const sampleCmsData = {
|
|
28
|
+
gallery: {
|
|
29
|
+
heroImage: {
|
|
30
|
+
src: sampleImages.landscape,
|
|
31
|
+
alt: 'Beautiful mountain landscape at sunset',
|
|
32
|
+
width: 800,
|
|
33
|
+
height: 600,
|
|
34
|
+
objectFit: 'cover',
|
|
35
|
+
objectPosition: 'center',
|
|
36
|
+
title: 'Mountain Sunset - Professional Photography',
|
|
37
|
+
showLoading: true,
|
|
38
|
+
borderRadius: '12px'
|
|
39
|
+
},
|
|
40
|
+
profileImage: {
|
|
41
|
+
src: sampleImages.portrait,
|
|
42
|
+
alt: 'Professional headshot of a smiling woman',
|
|
43
|
+
width: 200,
|
|
44
|
+
height: 200,
|
|
45
|
+
objectFit: 'cover',
|
|
46
|
+
objectPosition: 'center',
|
|
47
|
+
borderRadius: '50%',
|
|
48
|
+
showLoading: true,
|
|
49
|
+
draggable: false
|
|
50
|
+
},
|
|
51
|
+
productImage: {
|
|
52
|
+
src: sampleImages.product,
|
|
53
|
+
alt: 'Premium headphones on white background',
|
|
54
|
+
width: 400,
|
|
55
|
+
height: 300,
|
|
56
|
+
objectFit: 'contain',
|
|
57
|
+
objectPosition: 'center',
|
|
58
|
+
showLoading: true,
|
|
59
|
+
showError: true,
|
|
60
|
+
fallbackSrc: sampleImages.fallback,
|
|
61
|
+
borderRadius: '8px'
|
|
62
|
+
},
|
|
63
|
+
responsiveImage: {
|
|
64
|
+
src: sampleImages.technology,
|
|
65
|
+
alt: 'Modern laptop setup with code on screen',
|
|
66
|
+
objectFit: 'cover',
|
|
67
|
+
objectPosition: 'center',
|
|
68
|
+
sizes: '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw',
|
|
69
|
+
srcSet: `${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`,
|
|
70
|
+
showLoading: true,
|
|
71
|
+
borderRadius: '16px'
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const dataProvider = new JsonDataProvider({ data: sampleCmsData });
|
|
77
|
+
|
|
78
|
+
const meta = {
|
|
79
|
+
title: 'Components/Image',
|
|
80
|
+
component: Image,
|
|
81
|
+
parameters: {
|
|
82
|
+
layout: 'padded',
|
|
83
|
+
docs: {
|
|
84
|
+
description: {
|
|
85
|
+
component: `Image is a comprehensive image display component with advanced features for responsive design, loading states, and accessibility.
|
|
86
|
+
|
|
87
|
+
**Key Features:**
|
|
88
|
+
- **Responsive Images**: Support for srcSet and sizes for optimized loading
|
|
89
|
+
- **Object Fit Control**: Full control over how images fit their containers
|
|
90
|
+
- **Loading States**: Visual feedback during image loading with customizable placeholders
|
|
91
|
+
- **Error Handling**: Graceful fallback for failed image loads
|
|
92
|
+
- **Accessibility**: Proper alt text and title support for screen readers
|
|
93
|
+
- **Lazy Loading**: Built-in support for performance optimization
|
|
94
|
+
- **Data Binding**: Full CMS integration through dataSource prop
|
|
95
|
+
- **Customization**: Border radius, positioning, and styling options
|
|
96
|
+
- **Fallback Support**: Automatic fallback to alternative image sources
|
|
97
|
+
- **Touch Friendly**: Configurable draggable behavior for touch interfaces
|
|
98
|
+
|
|
99
|
+
**Perfect For:**
|
|
100
|
+
- Hero sections and banners
|
|
101
|
+
- Product galleries and catalogs
|
|
102
|
+
- Profile pictures and avatars
|
|
103
|
+
- Content illustrations and media
|
|
104
|
+
- Responsive image grids
|
|
105
|
+
- Progressive web app imagery`,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
tags: ['autodocs'],
|
|
110
|
+
} satisfies Meta<typeof Image>;
|
|
111
|
+
|
|
112
|
+
export default meta;
|
|
113
|
+
type Story = StoryObj<typeof Image>;
|
|
114
|
+
|
|
115
|
+
// Traditional Usage Examples
|
|
116
|
+
export const BasicImage: Story = {
|
|
117
|
+
render: () => (
|
|
118
|
+
<QwickApp appId="image-basic" appName='Basic Image Example'>
|
|
119
|
+
<Image
|
|
120
|
+
src={sampleImages.landscape}
|
|
121
|
+
alt="Beautiful mountain landscape at sunset"
|
|
122
|
+
width={600}
|
|
123
|
+
height={400}
|
|
124
|
+
showLoading={true}
|
|
125
|
+
/>
|
|
126
|
+
</QwickApp>
|
|
127
|
+
),
|
|
128
|
+
parameters: {
|
|
129
|
+
docs: {
|
|
130
|
+
description: {
|
|
131
|
+
story: 'Basic image display with loading state and proper alt text for accessibility.',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const ResponsiveImage: Story = {
|
|
138
|
+
render: () => (
|
|
139
|
+
<QwickApp appId="image-responsive" appName='Responsive Image Example'>
|
|
140
|
+
<Image
|
|
141
|
+
src={sampleImages.technology}
|
|
142
|
+
alt="Modern laptop setup with code on screen"
|
|
143
|
+
objectFit="cover"
|
|
144
|
+
objectPosition="center"
|
|
145
|
+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
146
|
+
srcSet={`${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`}
|
|
147
|
+
showLoading={true}
|
|
148
|
+
borderRadius="16px"
|
|
149
|
+
style={{ width: '100%', maxWidth: '800px', height: '400px' }}
|
|
150
|
+
/>
|
|
151
|
+
</QwickApp>
|
|
152
|
+
),
|
|
153
|
+
parameters: {
|
|
154
|
+
docs: {
|
|
155
|
+
description: {
|
|
156
|
+
story: 'Responsive image with srcSet for different screen sizes and optimized loading.',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const ObjectFitModes: Story = {
|
|
163
|
+
render: () => (
|
|
164
|
+
<QwickApp appId="image-object-fit" appName='Object Fit Examples'>
|
|
165
|
+
<Grid container spacing={3}>
|
|
166
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
167
|
+
<Typography variant="h6" gutterBottom>Cover (default)</Typography>
|
|
168
|
+
<Image
|
|
169
|
+
src={sampleImages.landscape}
|
|
170
|
+
alt="Landscape with cover fit"
|
|
171
|
+
width={300}
|
|
172
|
+
height={200}
|
|
173
|
+
objectFit="cover"
|
|
174
|
+
borderRadius="8px"
|
|
175
|
+
showLoading={true}
|
|
176
|
+
/>
|
|
177
|
+
</Grid>
|
|
178
|
+
|
|
179
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
180
|
+
<Typography variant="h6" gutterBottom>Contain</Typography>
|
|
181
|
+
<Image
|
|
182
|
+
src={sampleImages.landscape}
|
|
183
|
+
alt="Landscape with contain fit"
|
|
184
|
+
width={300}
|
|
185
|
+
height={200}
|
|
186
|
+
objectFit="contain"
|
|
187
|
+
borderRadius="8px"
|
|
188
|
+
showLoading={true}
|
|
189
|
+
style={{ backgroundColor: '#f5f5f5' }}
|
|
190
|
+
/>
|
|
191
|
+
</Grid>
|
|
192
|
+
|
|
193
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
194
|
+
<Typography variant="h6" gutterBottom>Fill</Typography>
|
|
195
|
+
<Image
|
|
196
|
+
src={sampleImages.landscape}
|
|
197
|
+
alt="Landscape with fill fit"
|
|
198
|
+
width={300}
|
|
199
|
+
height={200}
|
|
200
|
+
objectFit="fill"
|
|
201
|
+
borderRadius="8px"
|
|
202
|
+
showLoading={true}
|
|
203
|
+
/>
|
|
204
|
+
</Grid>
|
|
205
|
+
|
|
206
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
207
|
+
<Typography variant="h6" gutterBottom>Scale Down</Typography>
|
|
208
|
+
<Image
|
|
209
|
+
src={sampleImages.square}
|
|
210
|
+
alt="Small image with scale-down fit"
|
|
211
|
+
width={300}
|
|
212
|
+
height={200}
|
|
213
|
+
objectFit="scale-down"
|
|
214
|
+
borderRadius="8px"
|
|
215
|
+
showLoading={true}
|
|
216
|
+
style={{ backgroundColor: '#f5f5f5' }}
|
|
217
|
+
/>
|
|
218
|
+
</Grid>
|
|
219
|
+
|
|
220
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
221
|
+
<Typography variant="h6" gutterBottom>None</Typography>
|
|
222
|
+
<Image
|
|
223
|
+
src={sampleImages.square}
|
|
224
|
+
alt="Image with no fitting"
|
|
225
|
+
width={300}
|
|
226
|
+
height={200}
|
|
227
|
+
objectFit="none"
|
|
228
|
+
borderRadius="8px"
|
|
229
|
+
showLoading={true}
|
|
230
|
+
style={{ backgroundColor: '#f5f5f5' }}
|
|
231
|
+
/>
|
|
232
|
+
</Grid>
|
|
233
|
+
</Grid>
|
|
234
|
+
</QwickApp>
|
|
235
|
+
),
|
|
236
|
+
parameters: {
|
|
237
|
+
docs: {
|
|
238
|
+
description: {
|
|
239
|
+
story: 'Different object-fit modes showing how images resize within their containers.',
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
export const LoadingAndErrorStates: Story = {
|
|
246
|
+
render: () => (
|
|
247
|
+
<QwickApp appId="image-states" appName='Loading and Error States'>
|
|
248
|
+
<Grid container spacing={3}>
|
|
249
|
+
<Grid item xs={12} md={4}>
|
|
250
|
+
<Typography variant="h6" gutterBottom>With Loading State</Typography>
|
|
251
|
+
<Image
|
|
252
|
+
src={sampleImages.portrait}
|
|
253
|
+
alt="Portrait with loading state"
|
|
254
|
+
width={300}
|
|
255
|
+
height={300}
|
|
256
|
+
objectFit="cover"
|
|
257
|
+
borderRadius="8px"
|
|
258
|
+
showLoading={true}
|
|
259
|
+
/>
|
|
260
|
+
</Grid>
|
|
261
|
+
|
|
262
|
+
<Grid item xs={12} md={4}>
|
|
263
|
+
<Typography variant="h6" gutterBottom>Error with Fallback</Typography>
|
|
264
|
+
<Image
|
|
265
|
+
src="https://invalid-url-that-will-fail.jpg"
|
|
266
|
+
alt="Image that will fail to load"
|
|
267
|
+
width={300}
|
|
268
|
+
height={300}
|
|
269
|
+
objectFit="cover"
|
|
270
|
+
borderRadius="8px"
|
|
271
|
+
showError={true}
|
|
272
|
+
fallbackSrc={sampleImages.fallback}
|
|
273
|
+
/>
|
|
274
|
+
</Grid>
|
|
275
|
+
|
|
276
|
+
<Grid item xs={12} md={4}>
|
|
277
|
+
<Typography variant="h6" gutterBottom>Error State Only</Typography>
|
|
278
|
+
<Image
|
|
279
|
+
src="https://another-invalid-url.jpg"
|
|
280
|
+
alt="Image that will show error"
|
|
281
|
+
width={300}
|
|
282
|
+
height={300}
|
|
283
|
+
objectFit="cover"
|
|
284
|
+
borderRadius="8px"
|
|
285
|
+
showError={true}
|
|
286
|
+
/>
|
|
287
|
+
</Grid>
|
|
288
|
+
</Grid>
|
|
289
|
+
</QwickApp>
|
|
290
|
+
),
|
|
291
|
+
parameters: {
|
|
292
|
+
docs: {
|
|
293
|
+
description: {
|
|
294
|
+
story: 'Loading states and error handling including fallback image support.',
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
export const ShapeVariations: Story = {
|
|
301
|
+
render: () => (
|
|
302
|
+
<QwickApp appId="image-shapes" appName='Image Shape Variations'>
|
|
303
|
+
<Grid container spacing={3} alignItems="center">
|
|
304
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
305
|
+
<Typography variant="h6" gutterBottom>Circular Avatar</Typography>
|
|
306
|
+
<Image
|
|
307
|
+
src={sampleImages.portrait}
|
|
308
|
+
alt="Circular profile picture"
|
|
309
|
+
width={150}
|
|
310
|
+
height={150}
|
|
311
|
+
objectFit="cover"
|
|
312
|
+
objectPosition="center"
|
|
313
|
+
borderRadius="50%"
|
|
314
|
+
draggable={false}
|
|
315
|
+
showLoading={true}
|
|
316
|
+
/>
|
|
317
|
+
</Grid>
|
|
318
|
+
|
|
319
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
320
|
+
<Typography variant="h6" gutterBottom>Rounded Rectangle</Typography>
|
|
321
|
+
<Image
|
|
322
|
+
src={sampleImages.product}
|
|
323
|
+
alt="Product image with rounded corners"
|
|
324
|
+
width={200}
|
|
325
|
+
height={150}
|
|
326
|
+
objectFit="cover"
|
|
327
|
+
borderRadius="16px"
|
|
328
|
+
showLoading={true}
|
|
329
|
+
/>
|
|
330
|
+
</Grid>
|
|
331
|
+
|
|
332
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
333
|
+
<Typography variant="h6" gutterBottom>Sharp Rectangle</Typography>
|
|
334
|
+
<Image
|
|
335
|
+
src={sampleImages.technology}
|
|
336
|
+
alt="Technology image with sharp corners"
|
|
337
|
+
width={200}
|
|
338
|
+
height={150}
|
|
339
|
+
objectFit="cover"
|
|
340
|
+
borderRadius="0px"
|
|
341
|
+
showLoading={true}
|
|
342
|
+
/>
|
|
343
|
+
</Grid>
|
|
344
|
+
|
|
345
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
346
|
+
<Typography variant="h6" gutterBottom>Custom Radius</Typography>
|
|
347
|
+
<Image
|
|
348
|
+
src={sampleImages.square}
|
|
349
|
+
alt="Image with custom border radius"
|
|
350
|
+
width={150}
|
|
351
|
+
height={150}
|
|
352
|
+
objectFit="cover"
|
|
353
|
+
borderRadius="24px"
|
|
354
|
+
showLoading={true}
|
|
355
|
+
/>
|
|
356
|
+
</Grid>
|
|
357
|
+
</Grid>
|
|
358
|
+
</QwickApp>
|
|
359
|
+
),
|
|
360
|
+
parameters: {
|
|
361
|
+
docs: {
|
|
362
|
+
description: {
|
|
363
|
+
story: 'Various border radius options for different image shapes and use cases.',
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
export const InteractiveFeatures: Story = {
|
|
370
|
+
render: () => (
|
|
371
|
+
<QwickApp appId="image-interactive" appName='Interactive Image Features'>
|
|
372
|
+
<Grid container spacing={3}>
|
|
373
|
+
<Grid item xs={12} md={6}>
|
|
374
|
+
<Typography variant="h6" gutterBottom>Clickable Image</Typography>
|
|
375
|
+
<Image
|
|
376
|
+
src={sampleImages.landscape}
|
|
377
|
+
alt="Clickable landscape image"
|
|
378
|
+
width={400}
|
|
379
|
+
height={300}
|
|
380
|
+
objectFit="cover"
|
|
381
|
+
borderRadius="12px"
|
|
382
|
+
showLoading={true}
|
|
383
|
+
onClick={(e) => alert('Image clicked!')}
|
|
384
|
+
style={{ cursor: 'pointer', transition: 'transform 0.2s', '&:hover': { transform: 'scale(1.02)' } }}
|
|
385
|
+
title="Click me!"
|
|
386
|
+
/>
|
|
387
|
+
</Grid>
|
|
388
|
+
|
|
389
|
+
<Grid item xs={12} md={6}>
|
|
390
|
+
<Typography variant="h6" gutterBottom>Non-draggable Image</Typography>
|
|
391
|
+
<Image
|
|
392
|
+
src={sampleImages.portrait}
|
|
393
|
+
alt="Non-draggable portrait"
|
|
394
|
+
width={300}
|
|
395
|
+
height={400}
|
|
396
|
+
objectFit="cover"
|
|
397
|
+
borderRadius="12px"
|
|
398
|
+
draggable={false}
|
|
399
|
+
showLoading={true}
|
|
400
|
+
title="This image cannot be dragged"
|
|
401
|
+
/>
|
|
402
|
+
</Grid>
|
|
403
|
+
</Grid>
|
|
404
|
+
</QwickApp>
|
|
405
|
+
),
|
|
406
|
+
parameters: {
|
|
407
|
+
docs: {
|
|
408
|
+
description: {
|
|
409
|
+
story: 'Interactive features including click handlers and drag control.',
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// Data Binding Examples
|
|
416
|
+
export const DataBoundHeroImage: Story = {
|
|
417
|
+
render: () => (
|
|
418
|
+
<QwickApp appId="image-hero-data" appName='Data-Bound Hero Image'>
|
|
419
|
+
<Image
|
|
420
|
+
dataSource={dataProvider.createDataSource('gallery.heroImage')}
|
|
421
|
+
bindingOptions={{
|
|
422
|
+
cache: true,
|
|
423
|
+
cacheTTL: 300000,
|
|
424
|
+
strict: false
|
|
425
|
+
}}
|
|
426
|
+
/>
|
|
427
|
+
</QwickApp>
|
|
428
|
+
),
|
|
429
|
+
parameters: {
|
|
430
|
+
docs: {
|
|
431
|
+
description: {
|
|
432
|
+
story: 'Hero image loaded from CMS data with caching enabled for performance.',
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
export const DataBoundProfileAvatar: Story = {
|
|
439
|
+
render: () => (
|
|
440
|
+
<QwickApp appId="image-avatar-data" appName='Data-Bound Profile Avatar'>
|
|
441
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
442
|
+
<Image
|
|
443
|
+
dataSource={dataProvider.createDataSource('gallery.profileImage')}
|
|
444
|
+
bindingOptions={{
|
|
445
|
+
cache: true,
|
|
446
|
+
strict: false
|
|
447
|
+
}}
|
|
448
|
+
/>
|
|
449
|
+
<Box>
|
|
450
|
+
<Typography variant="h6">Sarah Johnson</Typography>
|
|
451
|
+
<Typography variant="body2" color="text.secondary">Senior Developer</Typography>
|
|
452
|
+
</Box>
|
|
453
|
+
</Box>
|
|
454
|
+
</QwickApp>
|
|
455
|
+
),
|
|
456
|
+
parameters: {
|
|
457
|
+
docs: {
|
|
458
|
+
description: {
|
|
459
|
+
story: 'Profile avatar loaded from CMS with circular styling and non-draggable setting.',
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
export const DataBoundProductImage: Story = {
|
|
466
|
+
render: () => (
|
|
467
|
+
<QwickApp appId="image-product-data" appName='Data-Bound Product Image'>
|
|
468
|
+
<Image
|
|
469
|
+
dataSource={dataProvider.createDataSource('gallery.productImage')}
|
|
470
|
+
bindingOptions={{
|
|
471
|
+
cache: true,
|
|
472
|
+
strict: false
|
|
473
|
+
}}
|
|
474
|
+
/>
|
|
475
|
+
</QwickApp>
|
|
476
|
+
),
|
|
477
|
+
parameters: {
|
|
478
|
+
docs: {
|
|
479
|
+
description: {
|
|
480
|
+
story: 'Product image with fallback support and error handling from CMS data.',
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
export const DataBoundResponsiveImage: Story = {
|
|
487
|
+
render: () => (
|
|
488
|
+
<QwickApp appId="image-responsive-data" appName='Data-Bound Responsive Image'>
|
|
489
|
+
<Box sx={{ width: '100%', maxWidth: '800px' }}>
|
|
490
|
+
<Image
|
|
491
|
+
dataSource={dataProvider.createDataSource('gallery.responsiveImage')}
|
|
492
|
+
bindingOptions={{
|
|
493
|
+
cache: true,
|
|
494
|
+
strict: false
|
|
495
|
+
}}
|
|
496
|
+
style={{ width: '100%', height: '400px' }}
|
|
497
|
+
/>
|
|
498
|
+
</Box>
|
|
499
|
+
</QwickApp>
|
|
500
|
+
),
|
|
501
|
+
parameters: {
|
|
502
|
+
docs: {
|
|
503
|
+
description: {
|
|
504
|
+
story: 'Responsive image with srcSet and sizes loaded from CMS for optimal performance.',
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
// ModelView Serialization Examples - Demonstrating the new ModelView base class
|
|
511
|
+
export const ModelViewBasic: Story = {
|
|
512
|
+
render: () => {
|
|
513
|
+
// Demonstrate that Image extends ModelView
|
|
514
|
+
const imageInstance = new Image({
|
|
515
|
+
src: sampleImages.landscape,
|
|
516
|
+
alt: 'Mountain landscape',
|
|
517
|
+
width: 400,
|
|
518
|
+
height: 300,
|
|
519
|
+
objectFit: 'cover',
|
|
520
|
+
borderRadius: '12px',
|
|
521
|
+
showLoading: true
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// Show that it has ModelView properties
|
|
525
|
+
const hasToJson = typeof imageInstance.toJson === 'function';
|
|
526
|
+
const hasFromJson = typeof (imageInstance.constructor as any).fromJson === 'function';
|
|
527
|
+
const tagName = (imageInstance.constructor as any).tagName;
|
|
528
|
+
const version = (imageInstance.constructor as any).version;
|
|
529
|
+
|
|
530
|
+
return (
|
|
531
|
+
<QwickApp appId="image-modelview" appName='Image ModelView Demonstration'>
|
|
532
|
+
<Box sx={{ mb: 4 }}>
|
|
533
|
+
<Alert severity="info" sx={{ mb: 2 }}>
|
|
534
|
+
<Typography variant="body2" component="div">
|
|
535
|
+
<strong>Image Component extends ModelView:</strong><br />
|
|
536
|
+
• Has toJson method: {hasToJson ? '✅ Yes' : '❌ No'}<br />
|
|
537
|
+
• Has fromJson method: {hasFromJson ? '✅ Yes' : '❌ No'}<br />
|
|
538
|
+
• Component tag name: <code>{tagName}</code><br />
|
|
539
|
+
• Component version: <code>{version}</code>
|
|
540
|
+
</Typography>
|
|
541
|
+
</Alert>
|
|
542
|
+
|
|
543
|
+
{imageInstance.render()}
|
|
544
|
+
</Box>
|
|
545
|
+
</QwickApp>
|
|
546
|
+
);
|
|
547
|
+
},
|
|
548
|
+
parameters: {
|
|
549
|
+
docs: {
|
|
550
|
+
description: {
|
|
551
|
+
story: 'Demonstrates that Image extends ModelView and has serialization capabilities.',
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
// Enhanced Serialization Examples - "WebView for React" functionality
|
|
558
|
+
export const SerializationBasic: Story = {
|
|
559
|
+
render: () => {
|
|
560
|
+
// Create an Image component instance (now extends ModelView)
|
|
561
|
+
const originalImageComponent = (
|
|
562
|
+
<Image
|
|
563
|
+
src={sampleImages.landscape}
|
|
564
|
+
alt="Serializable mountain landscape"
|
|
565
|
+
width={600}
|
|
566
|
+
height={400}
|
|
567
|
+
objectFit="cover"
|
|
568
|
+
objectPosition="center"
|
|
569
|
+
borderRadius="16px"
|
|
570
|
+
showLoading={true}
|
|
571
|
+
title="Beautiful mountain vista"
|
|
572
|
+
/>
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
// Serialize the component to JSON
|
|
576
|
+
const serialized = ComponentTransformer.serialize(originalImageComponent);
|
|
577
|
+
|
|
578
|
+
// Deserialize back to a React component
|
|
579
|
+
const deserializedComponent = ComponentTransformer.deserialize(serialized);
|
|
580
|
+
|
|
581
|
+
return (
|
|
582
|
+
<QwickApp appId="image-serialization-basic" appName='Basic Image Serialization'>
|
|
583
|
+
<Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
|
|
584
|
+
|
|
585
|
+
<Box>
|
|
586
|
+
<Typography variant="h6" gutterBottom>Original Image Component</Typography>
|
|
587
|
+
{originalImageComponent}
|
|
588
|
+
</Box>
|
|
589
|
+
|
|
590
|
+
<Divider />
|
|
591
|
+
|
|
592
|
+
<Box>
|
|
593
|
+
<Typography variant="h6" gutterBottom>Serialized JSON Data</Typography>
|
|
594
|
+
<Paper elevation={1} sx={{ p: 2, backgroundColor: 'grey.50' }}>
|
|
595
|
+
<Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.75rem' }}>
|
|
596
|
+
{JSON.stringify(JSON.parse(serialized), null, 2)}
|
|
597
|
+
</Typography>
|
|
598
|
+
</Paper>
|
|
599
|
+
</Box>
|
|
600
|
+
|
|
601
|
+
<Divider />
|
|
602
|
+
|
|
603
|
+
<Box>
|
|
604
|
+
<Typography variant="h6" gutterBottom>Deserialized Component (Recreated from JSON)</Typography>
|
|
605
|
+
{deserializedComponent}
|
|
606
|
+
</Box>
|
|
607
|
+
|
|
608
|
+
<Alert severity="success">
|
|
609
|
+
<Typography variant="body2">
|
|
610
|
+
<strong>Serialization Success!</strong> The Image component was successfully serialized to JSON and deserialized back to a functional React component with all properties preserved.
|
|
611
|
+
</Typography>
|
|
612
|
+
</Alert>
|
|
613
|
+
|
|
614
|
+
</Box>
|
|
615
|
+
</QwickApp>
|
|
616
|
+
);
|
|
617
|
+
},
|
|
618
|
+
parameters: {
|
|
619
|
+
docs: {
|
|
620
|
+
description: {
|
|
621
|
+
story: 'Demonstrates basic Image component serialization and deserialization using ComponentTransformer.',
|
|
622
|
+
},
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
export const SerializationComplex: Story = {
|
|
628
|
+
render: () => {
|
|
629
|
+
// Create a complex Image with multiple features
|
|
630
|
+
const complexImageComponent = (
|
|
631
|
+
<Image
|
|
632
|
+
src={sampleImages.technology}
|
|
633
|
+
alt="Complex responsive technology image"
|
|
634
|
+
width={800}
|
|
635
|
+
height={500}
|
|
636
|
+
objectFit="cover"
|
|
637
|
+
objectPosition="center"
|
|
638
|
+
loading="lazy"
|
|
639
|
+
borderRadius="20px"
|
|
640
|
+
showLoading={true}
|
|
641
|
+
showError={true}
|
|
642
|
+
fallbackSrc={sampleImages.fallback}
|
|
643
|
+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
644
|
+
srcSet={`${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`}
|
|
645
|
+
title="Advanced technology setup with multiple monitors"
|
|
646
|
+
draggable={false}
|
|
647
|
+
/>
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
// Serialize with all the complex properties
|
|
651
|
+
const serialized = ComponentTransformer.serialize(complexImageComponent);
|
|
652
|
+
const deserializedComponent = ComponentTransformer.deserialize(serialized);
|
|
653
|
+
|
|
654
|
+
// Parse for display
|
|
655
|
+
const parsedData = JSON.parse(serialized);
|
|
656
|
+
|
|
657
|
+
return (
|
|
658
|
+
<QwickApp appId="image-serialization-complex" appName='Complex Image Serialization'>
|
|
659
|
+
<Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
|
|
660
|
+
|
|
661
|
+
<Box>
|
|
662
|
+
<Typography variant="h6" gutterBottom>Original Complex Image</Typography>
|
|
663
|
+
<Typography variant="body2" color="text.secondary" gutterBottom>
|
|
664
|
+
Includes responsive srcSet, fallback image, loading states, and custom styling
|
|
665
|
+
</Typography>
|
|
666
|
+
{complexImageComponent}
|
|
667
|
+
</Box>
|
|
668
|
+
|
|
669
|
+
<Divider />
|
|
670
|
+
|
|
671
|
+
<Box>
|
|
672
|
+
<Typography variant="h6" gutterBottom>Serialized Properties</Typography>
|
|
673
|
+
<Grid container spacing={2}>
|
|
674
|
+
<Grid item xs={12} md={6}>
|
|
675
|
+
<Paper elevation={1} sx={{ p: 2, height: '300px', overflow: 'auto' }}>
|
|
676
|
+
<Typography variant="subtitle2" gutterBottom>JSON Structure:</Typography>
|
|
677
|
+
<Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.7rem' }}>
|
|
678
|
+
{JSON.stringify(parsedData, null, 2)}
|
|
679
|
+
</Typography>
|
|
680
|
+
</Paper>
|
|
681
|
+
</Grid>
|
|
682
|
+
<Grid item xs={12} md={6}>
|
|
683
|
+
<Paper elevation={1} sx={{ p: 2 }}>
|
|
684
|
+
<Typography variant="subtitle2" gutterBottom>Key Properties:</Typography>
|
|
685
|
+
<Typography variant="body2" component="div">
|
|
686
|
+
• Component: <code>{parsedData.tag}</code><br />
|
|
687
|
+
• Version: <code>{parsedData.version}</code><br />
|
|
688
|
+
• Source: <code>{parsedData.data?.src ? 'Present' : 'Missing'}</code><br />
|
|
689
|
+
• Alt text: <code>{parsedData.data?.alt ? 'Present' : 'Missing'}</code><br />
|
|
690
|
+
• Dimensions: <code>{parsedData.data?.width}x{parsedData.data?.height}</code><br />
|
|
691
|
+
• Object fit: <code>{parsedData.data?.objectFit}</code><br />
|
|
692
|
+
• Border radius: <code>{parsedData.data?.borderRadius}</code><br />
|
|
693
|
+
• Loading behavior: <code>{parsedData.data?.loading}</code><br />
|
|
694
|
+
• Fallback: <code>{parsedData.data?.fallbackSrc ? 'Present' : 'None'}</code><br />
|
|
695
|
+
• Responsive: <code>{parsedData.data?.srcSet ? 'Yes' : 'No'}</code>
|
|
696
|
+
</Typography>
|
|
697
|
+
</Paper>
|
|
698
|
+
</Grid>
|
|
699
|
+
</Grid>
|
|
700
|
+
</Box>
|
|
701
|
+
|
|
702
|
+
<Divider />
|
|
703
|
+
|
|
704
|
+
<Box>
|
|
705
|
+
<Typography variant="h6" gutterBottom>Deserialized Component</Typography>
|
|
706
|
+
<Typography variant="body2" color="text.secondary" gutterBottom>
|
|
707
|
+
Recreated from JSON with all properties and functionality intact
|
|
708
|
+
</Typography>
|
|
709
|
+
{deserializedComponent}
|
|
710
|
+
</Box>
|
|
711
|
+
|
|
712
|
+
<Alert severity="info">
|
|
713
|
+
<Typography variant="body2">
|
|
714
|
+
<strong>Advanced Serialization Success!</strong> All Image properties including responsive configuration,
|
|
715
|
+
fallback handling, loading states, and styling were perfectly preserved through the serialization process.
|
|
716
|
+
</Typography>
|
|
717
|
+
</Alert>
|
|
718
|
+
|
|
719
|
+
</Box>
|
|
720
|
+
</QwickApp>
|
|
721
|
+
);
|
|
722
|
+
},
|
|
723
|
+
parameters: {
|
|
724
|
+
docs: {
|
|
725
|
+
description: {
|
|
726
|
+
story: 'Demonstrates complex Image serialization with responsive images, fallbacks, and all advanced features.',
|
|
727
|
+
},
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
export const SerializationWithDataBinding: Story = {
|
|
733
|
+
render: () => {
|
|
734
|
+
// Create a data-bound Image component
|
|
735
|
+
const dataBoundImageComponent = (
|
|
736
|
+
<Image
|
|
737
|
+
dataSource={dataProvider.createDataSource('gallery.heroImage')}
|
|
738
|
+
bindingOptions={{
|
|
739
|
+
cache: true,
|
|
740
|
+
cacheTTL: 300000,
|
|
741
|
+
strict: false
|
|
742
|
+
}}
|
|
743
|
+
/>
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
// Serialize the data-bound component
|
|
747
|
+
const serialized = ComponentTransformer.serialize(dataBoundImageComponent);
|
|
748
|
+
const deserializedComponent = ComponentTransformer.deserialize(serialized);
|
|
749
|
+
const parsedData = JSON.parse(serialized);
|
|
750
|
+
|
|
751
|
+
return (
|
|
752
|
+
<QwickApp appId="image-serialization-databound" appName='Data-Bound Image Serialization'>
|
|
753
|
+
<Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
|
|
754
|
+
|
|
755
|
+
<Box>
|
|
756
|
+
<Typography variant="h6" gutterBottom>Original Data-Bound Image</Typography>
|
|
757
|
+
<Typography variant="body2" color="text.secondary" gutterBottom>
|
|
758
|
+
Image loaded from CMS data source with caching enabled
|
|
759
|
+
</Typography>
|
|
760
|
+
{dataBoundImageComponent}
|
|
761
|
+
</Box>
|
|
762
|
+
|
|
763
|
+
<Divider />
|
|
764
|
+
|
|
765
|
+
<Box>
|
|
766
|
+
<Typography variant="h6" gutterBottom>Serialized Data Binding</Typography>
|
|
767
|
+
<Grid container spacing={2}>
|
|
768
|
+
<Grid item xs={12} md={8}>
|
|
769
|
+
<Paper elevation={1} sx={{ p: 2 }}>
|
|
770
|
+
<Typography variant="subtitle2" gutterBottom>Serialized JSON:</Typography>
|
|
771
|
+
<Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.7rem', maxHeight: '200px', overflow: 'auto' }}>
|
|
772
|
+
{JSON.stringify(parsedData, null, 2)}
|
|
773
|
+
</Typography>
|
|
774
|
+
</Paper>
|
|
775
|
+
</Grid>
|
|
776
|
+
<Grid item xs={12} md={4}>
|
|
777
|
+
<Paper elevation={1} sx={{ p: 2 }}>
|
|
778
|
+
<Typography variant="subtitle2" gutterBottom>Data Binding Info:</Typography>
|
|
779
|
+
<Typography variant="body2" component="div">
|
|
780
|
+
• Data source: <code>{parsedData.data?.dataSource ? 'Preserved' : 'Missing'}</code><br />
|
|
781
|
+
• Binding options: <code>{parsedData.data?.bindingOptions ? 'Present' : 'None'}</code><br />
|
|
782
|
+
• Cache enabled: <code>{parsedData.data?.bindingOptions?.cache ? 'Yes' : 'No'}</code><br />
|
|
783
|
+
• Cache TTL: <code>{parsedData.data?.bindingOptions?.cacheTTL || 'Default'}</code><br />
|
|
784
|
+
• Strict mode: <code>{parsedData.data?.bindingOptions?.strict ? 'Yes' : 'No'}</code>
|
|
785
|
+
</Typography>
|
|
786
|
+
</Paper>
|
|
787
|
+
</Grid>
|
|
788
|
+
</Grid>
|
|
789
|
+
</Box>
|
|
790
|
+
|
|
791
|
+
<Divider />
|
|
792
|
+
|
|
793
|
+
<Box>
|
|
794
|
+
<Typography variant="h6" gutterBottom>Deserialized Data-Bound Component</Typography>
|
|
795
|
+
<Typography variant="body2" color="text.secondary" gutterBottom>
|
|
796
|
+
Recreated with full data binding functionality preserved
|
|
797
|
+
</Typography>
|
|
798
|
+
{deserializedComponent}
|
|
799
|
+
</Box>
|
|
800
|
+
|
|
801
|
+
<Alert severity="success">
|
|
802
|
+
<Typography variant="body2">
|
|
803
|
+
<strong>Data Binding Serialization Success!</strong> The Image component with CMS data binding,
|
|
804
|
+
caching configuration, and all binding options was successfully serialized and recreated.
|
|
805
|
+
</Typography>
|
|
806
|
+
</Alert>
|
|
807
|
+
|
|
808
|
+
</Box>
|
|
809
|
+
</QwickApp>
|
|
810
|
+
);
|
|
811
|
+
},
|
|
812
|
+
parameters: {
|
|
813
|
+
docs: {
|
|
814
|
+
description: {
|
|
815
|
+
story: 'Demonstrates serialization of data-bound Image components with CMS integration preserved.',
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
};
|