@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,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image - Comprehensive image display component with serialization support
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Responsive image handling with srcSet and sizes
|
|
6
|
+
* - Multiple fit modes and positioning options
|
|
7
|
+
* - Loading states and error handling
|
|
8
|
+
* - Accessibility support with proper alt text
|
|
9
|
+
* - Lazy loading support
|
|
10
|
+
* - Fallback image handling
|
|
11
|
+
* - Full serialization support via ModelView
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import React, { ReactElement, useState, useCallback } from 'react';
|
|
17
|
+
import { Box, Skeleton, Typography, useTheme } from '@mui/material';
|
|
18
|
+
import { BrokenImage as BrokenImageIcon } from '@mui/icons-material';
|
|
19
|
+
import type { WithDataBinding, ModelProps } from '@qwickapps/schema';
|
|
20
|
+
import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding } from '../../hooks';
|
|
21
|
+
import ImageModel, { ImageFit, ImageLoading, ImagePosition } from '../../schemas/ImageSchema';
|
|
22
|
+
import { ModelView } from '../base/ModelView';
|
|
23
|
+
|
|
24
|
+
type ImageViewProps = ModelProps<ImageModel> & {
|
|
25
|
+
/** Click handler for the image */
|
|
26
|
+
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
27
|
+
/** Additional inline styles */
|
|
28
|
+
style?: React.CSSProperties;
|
|
29
|
+
/** Additional CSS class names */
|
|
30
|
+
className?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export interface ImageProps extends ImageViewProps, WithDataBinding {}
|
|
34
|
+
|
|
35
|
+
// View component - handles the actual rendering
|
|
36
|
+
function ImageView({
|
|
37
|
+
src,
|
|
38
|
+
alt = '',
|
|
39
|
+
width,
|
|
40
|
+
height,
|
|
41
|
+
objectFit = 'cover',
|
|
42
|
+
objectPosition = 'center',
|
|
43
|
+
loading = 'lazy',
|
|
44
|
+
title,
|
|
45
|
+
draggable = false,
|
|
46
|
+
borderRadius,
|
|
47
|
+
showLoading = false,
|
|
48
|
+
showError = false,
|
|
49
|
+
fallbackSrc,
|
|
50
|
+
sizes,
|
|
51
|
+
srcSet,
|
|
52
|
+
loadingPlaceholder,
|
|
53
|
+
errorPlaceholder,
|
|
54
|
+
onClick,
|
|
55
|
+
style,
|
|
56
|
+
className,
|
|
57
|
+
...restProps
|
|
58
|
+
}: ImageViewProps) {
|
|
59
|
+
const { styleProps, htmlProps, restProps: otherProps } = useBaseProps(restProps);
|
|
60
|
+
const theme = useTheme();
|
|
61
|
+
|
|
62
|
+
// Mark as QwickApp component
|
|
63
|
+
(ImageView as any)[QWICKAPP_COMPONENT] = true;
|
|
64
|
+
|
|
65
|
+
const [imageState, setImageState] = useState<'loading' | 'loaded' | 'error'>('loading');
|
|
66
|
+
const [currentSrc, setCurrentSrc] = useState(src);
|
|
67
|
+
|
|
68
|
+
const handleLoad = useCallback(() => {
|
|
69
|
+
setImageState('loaded');
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
72
|
+
const handleError = useCallback(() => {
|
|
73
|
+
// Try fallback source if available and not already using it
|
|
74
|
+
if (fallbackSrc && currentSrc !== fallbackSrc) {
|
|
75
|
+
setCurrentSrc(fallbackSrc);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
setImageState('error');
|
|
79
|
+
}, [fallbackSrc, currentSrc]);
|
|
80
|
+
|
|
81
|
+
// Early return if no src provided
|
|
82
|
+
if (!src) {
|
|
83
|
+
if (showError) {
|
|
84
|
+
return (
|
|
85
|
+
<Box
|
|
86
|
+
{...htmlProps}
|
|
87
|
+
{...styleProps}
|
|
88
|
+
{...otherProps}
|
|
89
|
+
className={`image-error ${className || ''}`.trim()}
|
|
90
|
+
style={{
|
|
91
|
+
display: 'flex',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
justifyContent: 'center',
|
|
94
|
+
backgroundColor: theme.palette.grey[100],
|
|
95
|
+
color: theme.palette.text.secondary,
|
|
96
|
+
width: width || 200,
|
|
97
|
+
height: height || 150,
|
|
98
|
+
borderRadius,
|
|
99
|
+
...style
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{errorPlaceholder || (
|
|
103
|
+
<Box sx={{ textAlign: 'center' }}>
|
|
104
|
+
<BrokenImageIcon sx={{ fontSize: 48, mb: 1, opacity: 0.5 }} />
|
|
105
|
+
<Typography variant="body2" color="text.secondary">
|
|
106
|
+
No image source
|
|
107
|
+
</Typography>
|
|
108
|
+
</Box>
|
|
109
|
+
)}
|
|
110
|
+
</Box>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Loading state
|
|
117
|
+
if (imageState === 'loading' && showLoading) {
|
|
118
|
+
return (
|
|
119
|
+
<Box
|
|
120
|
+
{...htmlProps}
|
|
121
|
+
{...styleProps}
|
|
122
|
+
{...otherProps}
|
|
123
|
+
className={`image-loading ${className || ''}`.trim()}
|
|
124
|
+
style={{
|
|
125
|
+
width: width || '100%',
|
|
126
|
+
height: height || 200,
|
|
127
|
+
borderRadius,
|
|
128
|
+
...style
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
131
|
+
{loadingPlaceholder || (
|
|
132
|
+
<Skeleton
|
|
133
|
+
variant="rectangular"
|
|
134
|
+
width="100%"
|
|
135
|
+
height="100%"
|
|
136
|
+
sx={{ borderRadius }}
|
|
137
|
+
/>
|
|
138
|
+
)}
|
|
139
|
+
</Box>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Error state
|
|
144
|
+
if (imageState === 'error' && showError) {
|
|
145
|
+
return (
|
|
146
|
+
<Box
|
|
147
|
+
{...htmlProps}
|
|
148
|
+
{...styleProps}
|
|
149
|
+
{...otherProps}
|
|
150
|
+
className={`image-error ${className || ''}`.trim()}
|
|
151
|
+
style={{
|
|
152
|
+
display: 'flex',
|
|
153
|
+
alignItems: 'center',
|
|
154
|
+
justifyContent: 'center',
|
|
155
|
+
backgroundColor: theme.palette.grey[100],
|
|
156
|
+
color: theme.palette.text.secondary,
|
|
157
|
+
width: width || '100%',
|
|
158
|
+
height: height || 200,
|
|
159
|
+
borderRadius,
|
|
160
|
+
...style
|
|
161
|
+
}}
|
|
162
|
+
>
|
|
163
|
+
{errorPlaceholder || (
|
|
164
|
+
<Box sx={{ textAlign: 'center', p: 2 }}>
|
|
165
|
+
<BrokenImageIcon sx={{ fontSize: 48, mb: 1, opacity: 0.5 }} />
|
|
166
|
+
<Typography variant="body2" color="text.secondary">
|
|
167
|
+
Failed to load image
|
|
168
|
+
</Typography>
|
|
169
|
+
{fallbackSrc && (
|
|
170
|
+
<Typography variant="caption" color="text.secondary">
|
|
171
|
+
Fallback image also failed
|
|
172
|
+
</Typography>
|
|
173
|
+
)}
|
|
174
|
+
</Box>
|
|
175
|
+
)}
|
|
176
|
+
</Box>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const imageStyles: React.CSSProperties = {
|
|
181
|
+
display: 'block',
|
|
182
|
+
maxWidth: '100%',
|
|
183
|
+
height: 'auto',
|
|
184
|
+
objectFit,
|
|
185
|
+
objectPosition,
|
|
186
|
+
borderRadius,
|
|
187
|
+
cursor: onClick ? 'pointer' : 'default',
|
|
188
|
+
...style
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Apply dimensions if provided
|
|
192
|
+
if (width) imageStyles.width = width;
|
|
193
|
+
if (height) imageStyles.height = height;
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<img
|
|
197
|
+
{...htmlProps}
|
|
198
|
+
{...styleProps}
|
|
199
|
+
{...otherProps}
|
|
200
|
+
src={currentSrc}
|
|
201
|
+
alt={alt}
|
|
202
|
+
width={width}
|
|
203
|
+
height={height}
|
|
204
|
+
loading={loading}
|
|
205
|
+
title={title}
|
|
206
|
+
draggable={draggable}
|
|
207
|
+
sizes={sizes}
|
|
208
|
+
srcSet={srcSet}
|
|
209
|
+
className={`image ${className || ''}`.trim()}
|
|
210
|
+
style={imageStyles}
|
|
211
|
+
onClick={onClick}
|
|
212
|
+
onLoad={handleLoad}
|
|
213
|
+
onError={handleError}
|
|
214
|
+
/>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Main component with data binding support and serialization capability
|
|
219
|
+
export class Image extends ModelView<ImageProps, ImageModel> {
|
|
220
|
+
// Component self-declaration for serialization
|
|
221
|
+
static readonly tagName = 'Image';
|
|
222
|
+
static readonly version = '1.0.0';
|
|
223
|
+
|
|
224
|
+
// Deserialization: JSON data → React element
|
|
225
|
+
static fromJson(jsonData: any): ReactElement {
|
|
226
|
+
return <Image {...jsonData} />;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Component-specific serialization properties
|
|
230
|
+
protected getComponentSpecificProps(): any {
|
|
231
|
+
return {
|
|
232
|
+
src: this.props.src,
|
|
233
|
+
alt: this.props.alt,
|
|
234
|
+
width: this.props.width,
|
|
235
|
+
height: this.props.height,
|
|
236
|
+
objectFit: this.props.objectFit,
|
|
237
|
+
objectPosition: this.props.objectPosition,
|
|
238
|
+
loading: this.props.loading,
|
|
239
|
+
title: this.props.title,
|
|
240
|
+
draggable: this.props.draggable,
|
|
241
|
+
borderRadius: this.props.borderRadius,
|
|
242
|
+
showLoading: this.props.showLoading,
|
|
243
|
+
showError: this.props.showError,
|
|
244
|
+
fallbackSrc: this.props.fallbackSrc,
|
|
245
|
+
sizes: this.props.sizes,
|
|
246
|
+
srcSet: this.props.srcSet,
|
|
247
|
+
// Note: loadingPlaceholder and errorPlaceholder are ReactNodes
|
|
248
|
+
// and will be handled by base serialization if needed
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Image component renders traditional props view
|
|
253
|
+
protected renderView(): React.ReactElement {
|
|
254
|
+
const { dataSource, bindingOptions, ...restProps } = this.props;
|
|
255
|
+
return <ImageView {...restProps} />;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Image component renders data-bound view
|
|
259
|
+
protected renderWithDataBinding(): React.ReactElement {
|
|
260
|
+
return <ImageWithDataBinding {...this.props} />;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Register HTML patterns that Image component can handle
|
|
264
|
+
static registerPatternHandlers(registry: any): void {
|
|
265
|
+
// Register img elements
|
|
266
|
+
if (!registry.hasPattern('img')) {
|
|
267
|
+
registry.registerPattern('img', Image.transformImage);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Register figure elements with img
|
|
271
|
+
if (!registry.hasPattern('figure img')) {
|
|
272
|
+
registry.registerPattern('figure img', Image.transformFigureImage);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Transform img elements to Image component
|
|
277
|
+
private static transformImage(element: Element): any {
|
|
278
|
+
const src = element.getAttribute('src') || '';
|
|
279
|
+
const alt = element.getAttribute('alt') || '';
|
|
280
|
+
const width = element.getAttribute('width');
|
|
281
|
+
const height = element.getAttribute('height');
|
|
282
|
+
const loading = element.getAttribute('loading') as 'lazy' | 'eager' | undefined;
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
tagName: 'Image',
|
|
286
|
+
props: {
|
|
287
|
+
src,
|
|
288
|
+
alt,
|
|
289
|
+
width: width ? parseInt(width) : undefined,
|
|
290
|
+
height: height ? parseInt(height) : undefined,
|
|
291
|
+
loading: loading || 'lazy'
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Transform figure > img elements to Image component with caption support
|
|
297
|
+
private static transformFigureImage(element: Element): any {
|
|
298
|
+
const figure = element.closest('figure');
|
|
299
|
+
const figcaption = figure?.querySelector('figcaption');
|
|
300
|
+
const caption = figcaption?.textContent || '';
|
|
301
|
+
|
|
302
|
+
const src = element.getAttribute('src') || '';
|
|
303
|
+
const alt = element.getAttribute('alt') || caption;
|
|
304
|
+
const width = element.getAttribute('width');
|
|
305
|
+
const height = element.getAttribute('height');
|
|
306
|
+
|
|
307
|
+
return {
|
|
308
|
+
tagName: 'Image',
|
|
309
|
+
props: {
|
|
310
|
+
src,
|
|
311
|
+
alt,
|
|
312
|
+
caption: caption || undefined,
|
|
313
|
+
width: width ? parseInt(width) : undefined,
|
|
314
|
+
height: height ? parseInt(height) : undefined,
|
|
315
|
+
loading: 'lazy'
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Helper component to handle data binding with hooks (since we can't use hooks in class components)
|
|
322
|
+
function ImageWithDataBinding(props: ImageProps) {
|
|
323
|
+
const { dataSource, bindingOptions, ...restProps } = props;
|
|
324
|
+
|
|
325
|
+
// Use data binding
|
|
326
|
+
const { dataSource: _source, loading, error, cached, ...rawImageProps } = useDataBinding<ImageModel>(
|
|
327
|
+
dataSource!,
|
|
328
|
+
restProps as Partial<ImageModel>,
|
|
329
|
+
ImageModel.getSchema(),
|
|
330
|
+
{ cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
// Use props directly since new serialization system handles component-level transformation
|
|
334
|
+
const imageProps = rawImageProps;
|
|
335
|
+
|
|
336
|
+
// Show loading state
|
|
337
|
+
if (loading) {
|
|
338
|
+
return (
|
|
339
|
+
<Box
|
|
340
|
+
sx={{
|
|
341
|
+
display: 'flex',
|
|
342
|
+
alignItems: 'center',
|
|
343
|
+
justifyContent: 'center',
|
|
344
|
+
backgroundColor: 'grey.100',
|
|
345
|
+
width: imageProps.width || 200,
|
|
346
|
+
height: imageProps.height || 150,
|
|
347
|
+
borderRadius: imageProps.borderRadius
|
|
348
|
+
}}
|
|
349
|
+
>
|
|
350
|
+
<Skeleton
|
|
351
|
+
variant="rectangular"
|
|
352
|
+
width="100%"
|
|
353
|
+
height="100%"
|
|
354
|
+
sx={{ borderRadius: imageProps.borderRadius }}
|
|
355
|
+
/>
|
|
356
|
+
</Box>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (error) {
|
|
361
|
+
console.error('Error loading image:', error);
|
|
362
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
363
|
+
return (
|
|
364
|
+
<Box
|
|
365
|
+
sx={{
|
|
366
|
+
display: 'flex',
|
|
367
|
+
flexDirection: 'column',
|
|
368
|
+
alignItems: 'center',
|
|
369
|
+
justifyContent: 'center',
|
|
370
|
+
backgroundColor: 'error.light',
|
|
371
|
+
color: 'error.contrastText',
|
|
372
|
+
p: 2,
|
|
373
|
+
borderRadius: imageProps.borderRadius,
|
|
374
|
+
width: imageProps.width || 200,
|
|
375
|
+
height: imageProps.height || 150
|
|
376
|
+
}}
|
|
377
|
+
>
|
|
378
|
+
<BrokenImageIcon sx={{ fontSize: 48, mb: 1 }} />
|
|
379
|
+
<Typography variant="body2" align="center">
|
|
380
|
+
Error Loading Image
|
|
381
|
+
</Typography>
|
|
382
|
+
<Typography variant="caption" align="center">
|
|
383
|
+
{error.message}
|
|
384
|
+
</Typography>
|
|
385
|
+
</Box>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
console.log('Resolved props for Image:', imageProps);
|
|
392
|
+
return <ImageView {...imageProps} />;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export default Image;
|
|
@@ -397,18 +397,20 @@ function PageBannerHeader(props: PageBannerHeaderProps) {
|
|
|
397
397
|
);
|
|
398
398
|
|
|
399
399
|
// Convert HeaderActionModel[] to HeaderAction[] by adding default onClick handlers
|
|
400
|
-
const convertedActions: HeaderAction[] | undefined = modelProps.actions
|
|
401
|
-
id: action.id
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
400
|
+
const convertedActions: HeaderAction[] | undefined = modelProps.actions
|
|
401
|
+
?.filter((action): action is typeof action & { id: string } => typeof action.id === 'string')
|
|
402
|
+
.map(action => ({
|
|
403
|
+
id: action.id,
|
|
404
|
+
label: action.label,
|
|
405
|
+
icon: action.icon as React.ReactNode,
|
|
406
|
+
disabled: action.disabled,
|
|
407
|
+
destructive: action.destructive,
|
|
408
|
+
priority: action.priority,
|
|
409
|
+
onClick: () => {
|
|
410
|
+
console.log(`Action clicked: ${action.id} - ${action.label}`);
|
|
411
|
+
// In a real app, this would dispatch events or call configured handlers
|
|
412
|
+
}
|
|
413
|
+
}));
|
|
412
414
|
|
|
413
415
|
const pageBannerHeaderProps: PageBannerHeaderViewProps = {
|
|
414
416
|
...modelProps,
|
|
@@ -141,26 +141,29 @@ function ProductCardView({
|
|
|
141
141
|
|
|
142
142
|
const displayActions = actions || getDefaultActions();
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
// INLINE WRAPPERS REFACTORED: Instead of inline component declarations (which cause remounts),
|
|
145
|
+
// compute JSX fragments via plain variables/functions and inject directly.
|
|
146
|
+
|
|
147
|
+
const featuresListElement = (() => {
|
|
148
|
+
const featuresToShow = variant === 'compact'
|
|
146
149
|
? (product.features || []).slice(0, maxFeaturesCompact)
|
|
147
150
|
: (product.features || []);
|
|
148
151
|
|
|
149
152
|
return (
|
|
150
153
|
<Box sx={{ mb: variant === 'detailed' ? 2.5 : 2 }}>
|
|
151
|
-
<Typography
|
|
152
|
-
variant="h6"
|
|
154
|
+
<Typography
|
|
155
|
+
variant="h6"
|
|
153
156
|
component="h4"
|
|
154
|
-
sx={{
|
|
155
|
-
mb: 1.5,
|
|
157
|
+
sx={{
|
|
158
|
+
mb: 1.5,
|
|
156
159
|
fontSize: '1.1rem',
|
|
157
160
|
fontWeight: 600
|
|
158
161
|
}}
|
|
159
162
|
>
|
|
160
163
|
Key Features:
|
|
161
164
|
</Typography>
|
|
162
|
-
<Box component="ul" sx={{
|
|
163
|
-
m: 0,
|
|
165
|
+
<Box component="ul" sx={{
|
|
166
|
+
m: 0,
|
|
164
167
|
p: 0,
|
|
165
168
|
listStyle: 'none'
|
|
166
169
|
}}>
|
|
@@ -185,9 +188,9 @@ function ProductCardView({
|
|
|
185
188
|
flexShrink: 0
|
|
186
189
|
}}
|
|
187
190
|
/>
|
|
188
|
-
<Typography
|
|
189
|
-
variant="body2"
|
|
190
|
-
sx={{
|
|
191
|
+
<Typography
|
|
192
|
+
variant="body2"
|
|
193
|
+
sx={{
|
|
191
194
|
fontSize: '0.95rem',
|
|
192
195
|
lineHeight: 1.4,
|
|
193
196
|
opacity: 0.8
|
|
@@ -198,10 +201,10 @@ function ProductCardView({
|
|
|
198
201
|
</Box>
|
|
199
202
|
))}
|
|
200
203
|
{variant === 'compact' && (product.features || []).length > maxFeaturesCompact && (
|
|
201
|
-
<Typography
|
|
202
|
-
variant="body2"
|
|
204
|
+
<Typography
|
|
205
|
+
variant="body2"
|
|
203
206
|
color="primary"
|
|
204
|
-
sx={{
|
|
207
|
+
sx={{
|
|
205
208
|
fontSize: '0.9rem',
|
|
206
209
|
pl: 2.5,
|
|
207
210
|
fontWeight: 500
|
|
@@ -213,41 +216,37 @@ function ProductCardView({
|
|
|
213
216
|
</Box>
|
|
214
217
|
</Box>
|
|
215
218
|
);
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
const TechnologiesSection = () => {
|
|
219
|
-
if (!showTechnologies || variant === 'compact') return null;
|
|
219
|
+
})();
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
</Box>
|
|
221
|
+
const technologiesSectionElement = (!showTechnologies || variant === 'compact') ? null : (
|
|
222
|
+
<Box sx={{ mb: 3 }}>
|
|
223
|
+
<Typography
|
|
224
|
+
variant="h6"
|
|
225
|
+
component="h4"
|
|
226
|
+
sx={{
|
|
227
|
+
mb: 1.5,
|
|
228
|
+
fontSize: '1rem',
|
|
229
|
+
fontWeight: 600
|
|
230
|
+
}}
|
|
231
|
+
>
|
|
232
|
+
Technologies:
|
|
233
|
+
</Typography>
|
|
234
|
+
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
|
235
|
+
{product.technologies.map((tech, index) => (
|
|
236
|
+
<Chip
|
|
237
|
+
key={index}
|
|
238
|
+
label={tech}
|
|
239
|
+
variant="outlined"
|
|
240
|
+
size="small"
|
|
241
|
+
sx={{
|
|
242
|
+
fontSize: '0.8rem',
|
|
243
|
+
fontWeight: 500
|
|
244
|
+
}}
|
|
245
|
+
/>
|
|
246
|
+
))}
|
|
248
247
|
</Box>
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
</Box>
|
|
249
|
+
);
|
|
251
250
|
|
|
252
251
|
return (
|
|
253
252
|
<Box
|
|
@@ -364,11 +363,11 @@ function ProductCardView({
|
|
|
364
363
|
</Typography>
|
|
365
364
|
</Box>
|
|
366
365
|
|
|
367
|
-
|
|
368
|
-
|
|
366
|
+
{/* Features */}
|
|
367
|
+
{featuresListElement}
|
|
369
368
|
|
|
370
|
-
|
|
371
|
-
|
|
369
|
+
{/* Technologies */}
|
|
370
|
+
{technologiesSectionElement}
|
|
372
371
|
|
|
373
372
|
{/* Action Buttons */}
|
|
374
373
|
<Box sx={{
|
|
@@ -381,7 +380,7 @@ function ProductCardView({
|
|
|
381
380
|
<Button
|
|
382
381
|
key={action.id}
|
|
383
382
|
variant={action.variant || 'contained'}
|
|
384
|
-
color={action.color || 'primary'}
|
|
383
|
+
// color={action.color || 'primary'}
|
|
385
384
|
disabled={action.disabled}
|
|
386
385
|
onClick={action.onClick}
|
|
387
386
|
{...(variant === 'compact' && { fullWidth: true })}
|